Forum Announcement, Click Here to Read More From EA_Cade.

Trying to add an interaction to terrain but it's causing a route failure

lexus20lexus20 Posts: 1,302 Member
edited March 5 in Nominated Threads
I'm trying to make a "Pee Here" mod, so I created a new interaction based on the pee while standing interaction and added it to object_terrain. I also copied most of a toilet's tuning to terrain as well so it would be recognized as a toilet (or at least I thought it would). The interaction does show up in the game, but the problem is that it doesn't work, it always ends up in a route failure. I have no idea what's causing the route failure or how can I get the mod to work, can someone help me?

I tried to paste the XML code for the Object Tuning and Interaction Tuning here, but it was too long so I couldn't, so I uploaded the package file instead (link here).
Post edited by EA_Cade on

Comments

  • TriplisTriplis Posts: 3,048 Member
    I haven't looked at your code, but judging from what you've said, a couple things come to mind:

    1) You shouldn't need or want to edit object_terrain in any way, unless it's to force a new interaction on it using an override (and if that's your goal, you can use scripts, which'll have better forward compatibility, since they can inject the interaction to object_terrain). I can share an example of such a script if need be. As far as terrain being recognized as a toilet, that's probably going to be an involved process and may not work for generic terrain itself; I mean, if you're wanting some kind of remnant of it happening on the terrain, I can see why you'd go in that direction, but you could probably create a puddle at the end of the interaction, which more or less simulates a result of the terrain being peed on. If all you want is for the sim to autonomously consider terrain as a possible option for peeing, you should be able to pull that off in your custom pee-while-standing interaction itself, by implementing some autonomy pull for bladder.

    2) It sounds like you're on the right track with creating an interaction based on the pee while standing interaction. The route failure part probably has something to do with the animation and/or the constraints of the interaction. You could try experimenting with the removal of constraints, changing of animation, etc., to try to nail down where the problem area is.
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • lexus20lexus20 Posts: 1,302 Member
    edited September 2017
    1) Yes, I was editing object_terrain to force a new interaction as I'm still not familiarized with Python. After I get the mod to work I will probably try to create a script instead of overriding object_terrain.

    2) I've made some progress, I removed one of the constraints and also created an Animation Tuning and Animation State Machine based on the original one with some changes. It doesn't cause a route failure anymore, but the sim will just walk to the spot where I clicked and generate a puddle underneath (I've set it in the Interaction Tuning to always generate a puddle because it's more realistic). However, for some reason, the peeing animation does not play and also the bladder motive does not go up.

    This time I pasted the code in a website so it's easier to see it:
    Object Tuning (Terrain): Link
    Interaction Tuning: Link
    Animation Tuning: Link
    Animation State Machine: Link

    The "toilet_sit" in the ASM is just because Sims4Studio wouldn't let me remove one of the choice values, it would always reset to two, so I just duplicated "toilet_stand" and renamed it as "toilet_sit", but they are the same.
  • TriplisTriplis Posts: 3,048 Member
    Hmm. Is it giving you a lastexception error when you attempt to do the interaction? From the way you describe it, it sounds like something is erroring out.
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • lexus20lexus20 Posts: 1,302 Member
    No, I don't get any errors, it's just not working as expected. I recorded a video of what is happening:

    https://www.youtube.com/watch?v=_tXsHw5TYHU&feature=youtu.be
  • TriplisTriplis Posts: 3,048 Member
    Ok, I think I get something I didn't before. I wanted to check your code to verify, but for some reason, your CodePaste links aren't working for me anymore. Anyway, I think it's to do with the constraint.

    I don't remember for sure what constraints you still had in there, if any. But I think the posture_manifest_tuning part may be vital to put the sim in the peeing stance. The body_target_tuning part can probably be deleted; I'd have to review the tdesc on that to be certain. But now that I'm thinking about how the toilet animation looks normally from my recollection, I think it's mostly just a static posture.

    So you could try the following for constraints (if you haven't already) and see what happens:
    <L n="_constraints">
        <U>
          <L n="constraints">
            <U>
              <E n="key">HUMAN</E>
              <V n="value" t="posture">
                <U n="posture">
                  <L n="posture_manifest_tuning">
                    <U>
                      <V n="posture_type" t="enabled">
                        <T n="enabled">15540<!--Posture: posture_ToiletStand--></T>
                      </V>
                    </U>
                  </L>
                </U>
              </V>
            </U>
          </L>
        </U>
      </L>
    
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • lexus20lexus20 Posts: 1,302 Member
    edited September 2017
    It didn't work. I tried both replacing the constraints I already had by these and keeping both, but in both cases it caused a route failure.

    The interaction tuning (before I added the posture_manifest_tuning) is the following:
    <?xml version="1.0" encoding="utf-8"?>
    <I c="SuperInteraction" i="interaction" m="objects.terrain" n="TS40:pee-here" s="12219767895069610653">
      <L n="_constraints">
        <U>
          <L n="constraints">
            <U>
              <E n="key">HUMAN</E>
              <V n="value" t="circle">
                <U n="circle">
                  <T n="ideal_radius">0</T>
                  <T n="radius">0.75</T>
                </U>
              </V>
            </U>
          </L>
        </U>
      </L>
      <V t="participant" n="_icon">
        <U n="participant">
          <L n="participant_type">
            <E>Actor</E>
          </L>
        </U>
      </V>
      <T n="_provided_posture_type">15540<!--posture_ToiletStand--></T>
      <V t="enabled" n="_saveable" />
      <T n="attention_cost">1</T>
      <V n="basic_content" t="flexible_length">
        <U n="flexible_length">
          <V t="override" n="allow_holster" />
          <L n="conditional_actions">
            <V t="literal">
              <U n="literal">
                <L n="conditions">
                  <V t="stat_based">
                    <U n="stat_based">
                      <T n="absolute">True</T>
                      <T n="stat">16652<!--motive_Bladder--></T>
                      <U n="threshold">
                        <E n="comparison">GREATER_OR_EQUAL</E>
                        <T n="value">100</T>
                      </U>
                    </U>
                  </V>
                  <V t="time_based">
                    <U n="time_based">
                      <T n="min_time">2</T>
                    </U>
                  </V>
                </L>
                <E n="interaction_action">EXIT_NATURALLY</E>
              </U>
            </V>
            <V t="list_reference">
              <T n="list_reference">39200<!--ExitConditionList_StateBrokenObject--></T>
            </V>
          </L>
          <V n="content" t="looping_content">
            <U n="looping_content">
              <U n="animation_ref">
                <T n="factory">7187252873586608110<!--TS40:PeeStand--></T>
              </U>
            </U>
          </V>
          <V n="periodic_stat_change" t="enabled">
            <U n="enabled">
              <U n="operation_actions">
                <L n="actions">
                  <T>104297<!--loot_Commodity_Fireleaf_ElixirOfBurning--></T>
                </L>
              </U>
              <L n="operations">
                <V t="statistic_change">
                  <U n="statistic_change">
                    <T n="amount">10</T>
                    <T n="exclusive_to_owning_si">False</T>
                    <T n="stat">16652<!--motive_Bladder--></T>
                  </U>
                </V>
                <V t="statistic_change">
                  <U n="statistic_change">
                    <T n="amount">10</T>
                    <T n="exclusive_to_owning_si">True</T>
                    <T n="stat">16652<!--motive_Bladder--></T>
                  </U>
                </V>
                <V t="statistic_change">
                  <U n="statistic_change">
                    <T n="advertise">False</T>
                    <T n="amount">-1.1</T>
                    <T n="stat">16575<!--commodity_dirtiness--></T>
                    <L n="subject">
                      <E>Object</E>
                    </L>
                  </U>
                </V>
                <V t="statistic_change">
                  <U n="statistic_change">
                    <T n="advertise">False</T>
                    <T n="amount">-5</T>
                    <T n="stat">16575<!--commodity_dirtiness--></T>
                    <L n="subject">
                      <E>Object</E>
                    </L>
                    <L n="tests">
                      <L>
                        <V t="state">
                          <U n="state">
                            <T n="value">15131<!--DirtyState_Dirty--></T>
                          </U>
                        </V>
                      </L>
                    </L>
                  </U>
                </V>
                <V t="statistic_change">
                  <U n="statistic_change">
                    <T n="amount">-10</T>
                    <T n="stat">16616<!--commodity_Motive_HygieneHands--></T>
                  </U>
                </V>
              </L>
            </U>
          </V>
          <T n="start_autonomous_inertial">False</T>
        </U>
      </V>
      <L n="basic_extras">
        <V t="state_change">
          <U n="state_change">
            <V t="single_value" n="new_value">
              <U n="single_value">
                <T n="new_value">15187<!--Flushed_Unflushed--></T>
              </U>
            </V>
            <V t="at_end" n="timing">
              <U n="at_end">
                <E n="criticality">OnCancel</E>
              </U>
            </V>
          </U>
        </V>
        <V t="buff">
          <U n="buff">
            <U n="buff_type">
              <T n="buff_type">100122<!--buff_Object_Toilet_NoTablet--></T>
            </U>
            <L n="tests">
              <L>
                <V t="trait">
                  <U n="trait">
                    <L n="whitelist_traits">
                      <T>16858<!--trait_Neat--></T>
                    </L>
                  </U>
                </V>
              </L>
            </L>
          </U>
        </V>
      </L>
      <T n="display_name">0x4FAA2FF0<!--Fazer Xixi Aqui--></T>
      <V n="display_name_overrides" t="testable">
        <U n="testable">
          <L n="overrides">
            <U>
              <V t="enabled" n="new_display_name">
                <T n="enabled">0xFC1AB036<!--Fazer Xixi Como {M0.um Campeão}{F0.uma Campeã}--></T>
              </V>
              <L n="test">
                <L>
                  <V t="mood">
                    <U n="mood">
                      <T n="mood">14634<!--Mood_Confident--></T>
                    </U>
                  </V>
                </L>
              </L>
            </U>
          </L>
        </U>
      </V>
      <U n="display_name_text_tokens">
        <L n="tokens">
          <V t="participant_type">
            <U n="participant_type">
              <E n="participant">Actor</E>
            </U>
          </V>
          <V t="participant_type">
            <U n="participant_type">
              <E n="participant">Object</E>
            </U>
          </V>
        </L>
      </U>
      <T n="force_autonomy_on_inertia">False</T>
      <T n="force_exit_on_inertia">False</T>
      <L n="interaction_category_tags">
        <E>Interaction_UseToilet</E>
        <E>Interaction_Super</E>
        <E>Interaction_All</E>
        <E>Interaction_WaitstaffIdle</E>
      </L>
      <L n="mood_list">
        <T>14634<!--Mood_Confident--></T>
      </L>
      <V n="outcome" t="single">
        <U n="single">
          <U n="actions">
            <L n="loot_list">
              <T>10396<!--loot_Commodity_Motive_Hygiene_UseToilet--></T>
              <T>25085<!--loot_SpreadPuddle--></T>
            </L>
          </U>
        </U>
      </V>
      <T n="pie_menu_priority">10</T>
      <U n="post_run_autonomy_commodities">
        <L n="requests">
          <U>
            <T n="same_target_only">True</T>
            <L n="static_commodities">
              <T>16428<!--StaticCommodity_Flush--></T>
            </L>
          </U>
        </L>
      </U>
      <U n="posture_preferences">
        <T n="apply_penalties">False</T>
      </U>
      <V t="enabled" n="posture_target_preference">
        <L n="enabled">
          <U>
            <E n="key">SEATING_TOILET</E>
            <T n="value">0</T>
          </U>
        </L>
      </V>
      <L n="pre_add_autonomy_commodities">
        <U>
          <T n="same_target_only">True</T>
          <L n="static_commodities">
            <T>98165<!--StaticCommodity_PreFlush--></T>
          </L>
        </U>
      </L>
      <V t="disabled" n="privacy">
        <U n="disabled">
          <V t="reference" n="privacy_snippet">
            <T n="reference">39309<!--privacy_snippet_medium_distance--></T>
          </V>
        </U>
      </V>
      <V t="enabled" n="route_start_balloon">
        <U n="enabled">
          <U n="balloon">
            <L n="balloon_choices">
              <U>
                <V n="item" t="balloon_icon">
                  <U n="balloon_icon">
                    <V t="participant" n="icon">
                      <U n="participant">
                        <L n="participant_type">
                          <E>Object</E>
                        </L>
                      </U>
                    </V>
                  </U>
                </V>
              </U>
            </L>
            <L n="balloon_target">
              <E>Actor</E>
            </L>
          </U>
        </U>
      </V>
      <E n="scoring_priority">NORMAL</E>
      <T n="subaction_selection_weight">1</T>
      <V n="super_affordance_compatibility" t="literal">
        <U n="literal">
          <V n="default_inclusion" t="include_all">
            <U n="include_all">
              <L n="exclude_affordances">
                <T>13481<!--idle_Bladder--></T>
              </L>
              <L n="exclude_lists">
                <T>30816<!--affordanceList_FoodConsume--></T>
                <T>16339<!--Drink_Drink--></T>
                <T>36156<!--AffordanceList_Socialize--></T>
                <T>30642<!--AffordanceList_Phone--></T>
              </L>
            </U>
          </V>
        </U>
      </V>
      <E n="target_type">OBJECT</E>
      <L n="test_globals">
        <V t="buff">
          <U n="buff">
            <L n="blacklist">
              <T>26171<!--buff_Sim_IsDying--></T>
            </L>
          </U>
        </V>
        <V t="sim_info">
          <U n="sim_info">
            <V t="specified" n="ages">
              <L n="specified">
                <E>TEEN</E>
                <E>YOUNGADULT</E>
                <E>ADULT</E>
                <E>ELDER</E>
                <E>CHILD</E>
              </L>
            </V>
            <E n="who">Actor</E>
          </U>
        </V>
        <V t="state">
          <U n="state">
            <V t="enabled" n="tooltip">
              <T n="enabled">0x1DB3D754<!--Não há como realizar esta interação em um objeto quebrado. Repare-o primeiro.--></T>
            </V>
            <T n="value">15081<!--BrokenState_Unbroken--></T>
          </U>
        </V>
      </L>
      <L n="tests">
        <L>
          <V t="trait">
            <U n="trait">
              <L n="whitelist_traits">
                <T>136876<!--trait_GenderOptions_Toilet_Standing--></T>
              </L>
            </U>
          </V>
          <V t="statistic">
            <U n="statistic">
              <T n="stat">16652<!--motive_Bladder--></T>
              <V t="value_threshold" n="threshold">
                <U n="value_threshold">
                  <E n="comparison">GREATER_OR_EQUAL</E>
                  <T n="value">-100</T>
                </U>
              </V>
              <E n="who">Actor</E>
            </U>
          </V>
        </L>
      </L>
      <T n="time_overhead">5</T>
      <E n="visual_type_override">SIMPLE</E>
    </I>
    
  • TriplisTriplis Posts: 3,048 Member
    edited September 2017
    Oh. I think I see something that may be problematic. Try changing m="objects.terrain" to m="interactions.base.super_interaction"

    Then try with or without the posture constraint again. You might also try removing _provided_posture_type, but with the constraint. I've read the tdesc before, but I'm not totally sure how _provided_posture_type functions in practice.

    Edit: Also, unless you're wanting a flush animation to happen in some way, you should be able to safely get rid of the pre-add and post-run commodities. All they do is push the sim to move into a flush interaction after peeing, but since it's not an actual toilet, you shouldn't need that.

    Also also, if you get stumped, my recommendation would be to look for a Maxis-made interaction that is as similar as possible to what you're attempting to do and just use that as a base, with the peeing animation and posture inserted into it... see if it makes any difference. I don't know how helpful that is, but it's what I usually do if I'm struggling. Off-hand, I'm not sure what all there is in the way of interactions that are ground-targeted that aren't just a movement-based thing. But I guess there's the list of super_affordances in terrain object, so you could look there for examples.
    Post edited by Triplis on
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • lexus20lexus20 Posts: 1,302 Member
    Unfortunately they didn't work, even with m="interactions.base.super_interaction". When I add the posture_manifest_tuning, I get a route failure, when I remove it, I get what I showed in the video.
    I also tried to create a new Posture Tuning and ASM for this Posture Tuning based on the ones from other terrain interactions, but it didn't make any difference. I had already tried to look at other terrain interactions too such as Do Push-Ups and replace the animations and postures by the peeing ones but then the interaction didn't even appear in the queue, it was simply ignored every time I clicked it.
  • TriplisTriplis Posts: 3,048 Member
    Weird. Only thing I can think is if maybe there's something in the clip files for the animation that requires a target object of a particular height (that or in the posture). Only reason I can see for this is because of the peeing animation stream effect, maybe there's a height requirement, so that the stream hits in the right place.

    I mean, you could maybe try extracting the peeing animation and just try to have it play without the posture or something. But then it probably wouldn't have the peeing stream effect (which may not reach the ground even if your attempts were working).

    I'm not sure I can be of much more help. I hope you can figure it out though.
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • TriplisTriplis Posts: 3,048 Member
    edited September 2017
    Scratch previous post, I have a strong hunch I know what you need to do, from something loosely related that I just got working. In the super_affordances for object_terrain, try adding the interaction generic_ToiletStand (id is 151354 if that helps you locate/add it)

    Edit: On giving it more thought, this may not be as much of a clincher as I thought. The reason it seems important is because I ran into a situation in experimenting with SitOnGround and attempting to allow ages other than toddler to do it, just to see if I could get past the contraint, for one thing. In the end, what clinched that was editing the age in both the SitOnGround interaction and the "generic" SitOnGround (there are a lot of "generic" named files like these, which are apparently important in interactions that involve special posture).
    Post edited by Triplis on
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • lexus20lexus20 Posts: 1,302 Member
    I found out that the problem is the posture. I removed the posture constraint and replaced the animation by the push-up animation just to test if it would work and it did. Then, I copied the push-up ASM and replaced the animation by the peeing animation and it worked as well, but with no censor grid, no sound, no pee stream, and the animation also ends abruptly not smoothly. The animation is divided into start, loop, and stop, but I think it is going straight to the loop and skipping both the start (which creates the censor grid, sound and pee stream effect) and stop, probably because I used posture_Stand instead of posture_ToiletStand. So I tried to create a new ToiletStand posture by removing the object requirements from the original but it didn't work either. I don't know what could be causing the problem with the new posture.

    Posture Tuning:
    <?xml version="1.0" encoding="utf-8"?>
    <I c="Posture" i="posture" m="postures.posture" n="posture_PeeTS40" s="14341254444375132971">
      <U n="_animation_data">
        <L n="_actor_species_mapping">
          <U>
            <E n="key">HUMAN</E>
            <U n="value">
              <T n="_asm_key" p="InGame\Sage\TS40:PeePostureASM.postureasm">02d5df13:00000000:00aa8c29b1c913f7</T>
              <T n="_enter_state_name">useStanding_start</T>
              <U n="_idle_animation">
                <T n="factory">6359664752630901125<!--TS40:PeeAnim--></T>
              </U>
              <T n="_state_name">Toilet_Stand_Posture</T>
            </U>
          </U>
        </L>
      </U>
      <L n="_supported_postures">
        <U>
          <T n="posture_type">15537<!--posture_Stand--></T>
        </U>
      </L>
      <T n="cost">20</T>
      <U n="social_geometry">
        <U n="focal_point">
          <T n="x">0</T>
          <T n="y">0</T>
          <T n="z">0.15</T>
        </U>
        <L n="social_space">
          <U>
            <T n="x">-0.5</T>
            <T n="y">0</T>
            <T n="z">0</T>
          </U>
          <U>
            <T n="x">0.5</T>
            <T n="y">0</T>
            <T n="z">0</T>
          </U>
          <U>
            <T n="x">1</T>
            <T n="y">0</T>
            <T n="z">1</T>
          </U>
          <U>
            <T n="x">-1</T>
            <T n="y">0</T>
            <T n="z">1</T>
          </U>
        </L>
      </U>
      <L n="surface_types">
        <E />
        <E>SURFACETYPE_OBJECT</E>
      </L>
    </I>
    

    Animation State Machine (for the posture):
    <?xml version="1.0" encoding="utf-8"?>
    <ASM name="TS40:PeePostureASM" dcc="sage">
      <Actor name="x" type="Sim" master="true" virtual="false" />
      <Parameter name="x:age" type="enum" labels="baby,toddler,child,teen,youngadult,adult,elder" default="adult" />
      <Parameter name="x:sex" type="enum" labels="male,female" default="male" />
      <IkConfiguration name="a2o_toilet_useStanding.ma">
        <SourceFile name="a2o_toilet_useStanding.ma">
          <MapNamespace namespace="x" actor="x" />
        </SourceFile>
      </IkConfiguration>
      <PostureManifest>
        <Provide name="PeeTS40" family="stand" compatibility="FullBody" carry_left="*" carry_right="*" surface="*" />
        <Provide name="PeeTS40" family="stand" compatibility="UpperBody" carry_left="*" carry_right="*" surface="*" />
      </PostureManifest>
      <State type="public" countlooptime="false" disableautostop="false" skippable="true" interrupt_this="true" name="Toilet_Stand_Posture" focus="full body" facialoverlays="true" tailoverlays="true" />
      <State type="public" skippable="false" interrupt_this="false" name="useStanding_start" focus="full body" facialoverlays="true" tailoverlays="true" />
      <State type="private" skippable="false" interrupt_this="false" name="useStanding_stop" focus="full body" facialoverlays="true" tailoverlays="true" />
      <Connection from="Toilet_Stand_Posture" to="useStanding_stop" />
      <Connection from="entry" to="useStanding_start" />
      <Connection from="useStanding_start" to="Toilet_Stand_Posture" />
      <Connection from="useStanding_stop" to="exit" />
      <State name="Toilet_Stand_Posture" type="public" countlooptime="false" disableautostop="false" skippable="true" interrupt_this="true" focus="full body" facialoverlays="true" tailoverlays="true">
        <description />
        <MakeController>
          <Controller target="x" controller="@ClipController(clip=a2o_toilet_stand_posture_x, loop_count=#1)" overridePosture="false" mask="" track="low" mirror_conditional="False" suppress_footsteps="False" transition_class_in="Default" transition_class_out="Default" ik_configuration="a2o_toilet_useStanding.ma" focus="undefined" start_frame_offset="0" end_frame_offset="0" unique_id="1">
            <TransitionClassList>
              <Transition transition_class_name="Default" transition_duration_in="0.2666667" use_custom_transition_in="true" transition_type_in="linear" transition_mask_in="" transition_duration_out="0.2666667" use_custom_transition_out="true" transition_type_out="linear" transition_mask_out="" />
            </TransitionClassList>
          </Controller>
        </MakeController>
      </State>
      <State name="useStanding_start" type="public" skippable="false" interrupt_this="false" focus="full body" facialoverlays="true" tailoverlays="true">
        <description />
        <Controller target="x" controller="@ClipController(clip=a2o_toilet_useStanding_start_x, loop_count=#1)" overridePosture="false" mask="" track="normal" mirror_conditional="False" suppress_footsteps="False" transition_class_in="Default" transition_class_out="Default" ik_configuration="a2o_toilet_useStanding.ma" focus="undefined" start_frame_offset="0" end_frame_offset="0" unique_id="2">
          <TransitionClassList>
            <Transition transition_class_name="Default" transition_duration_in="0.2666667" use_custom_transition_in="true" transition_type_in="linear" transition_mask_in="" transition_duration_out="0.2666667" use_custom_transition_out="false" transition_type_out="linear" transition_mask_out="" />
          </TransitionClassList>
        </Controller>
      </State>
      <State name="useStanding_stop" type="private" skippable="false" interrupt_this="false" focus="full body" facialoverlays="true" tailoverlays="true">
        <description />
        <Controller target="x" controller="@ClipController(clip=a2o_toilet_useStanding_stop_x, loop_count=#1)" overridePosture="false" mask="" track="normal" mirror_conditional="False" suppress_footsteps="False" transition_class_in="Default" transition_class_out="Default" ik_configuration="a2o_toilet_useStanding.ma" focus="undefined" start_frame_offset="0" end_frame_offset="0" unique_id="3">
          <TransitionClassList>
            <Transition transition_class_name="Default" transition_duration_in="0.2666667" use_custom_transition_in="true" transition_type_in="linear" transition_mask_in="" transition_duration_out="0.2666667" use_custom_transition_out="false" transition_type_out="linear" transition_mask_out="" />
          </TransitionClassList>
        </Controller>
      </State>
    </ASM>
    
  • TriplisTriplis Posts: 3,048 Member
    edited September 2017
    Well, from the stuff I've dealt in recently, special situations with posture will have a generic_ interaction as one of the affordances on the object that looks something like this:
    <?xml version="1.0" encoding="utf-8"?>
    <I c="SuperInteraction" i="interaction" m="interactions.base.super_interaction" n="generic_ToiletStand" s="151354">
      <V t="participant" n="_icon">
        <U n="participant">
          <L n="participant_type">
            <E>Object</E>
          </L>
        </U>
      </V>
      <T n="_provided_posture_type">15540<!--Posture: posture_ToiletStand--></T>
      <V t="disabled" n="_saveable" />
      <T n="allow_autonomous">False</T>
      <T n="allow_user_directed">False</T>
      <T n="attention_cost">0.5</T>
      <U n="display_name_text_tokens">
        <L n="tokens">
          <V t="participant_type">
            <U n="participant_type">
              <E n="participant">Actor</E>
            </U>
          </V>
          <V t="participant_type">
            <U n="participant_type">
              <E n="participant">Object</E>
            </U>
          </V>
        </L>
      </U>
      <T n="ignore_group_socials">False</T>
      <L n="interaction_category_tags">
        <E>Interaction_Super</E>
        <E>Interaction_All</E>
      </L>
      <E n="scoring_priority">NORMAL</E>
      <T n="subaction_selection_weight">1</T>
      <E n="target_type">OBJECT</E>
      <L n="test_globals">
        <V t="buff">
          <U n="buff">
            <L n="blacklist">
              <T>26171<!--Buff: buff_Sim_IsDying--></T>
            </L>
          </U>
        </V>
        <V t="sim_info">
          <U n="sim_info">
            <V t="specified" n="ages">
              <L n="specified">
                <E>CHILD</E>
                <E>TEEN</E>
                <E>YOUNGADULT</E>
                <E>ADULT</E>
                <E>ELDER</E>
              </L>
            </V>
            <V t="specified" n="species">
              <L n="specified">
                <E />
              </L>
            </V>
            <E n="who">Actor</E>
          </U>
        </V>
      </L>
      <T n="time_overhead">30</T>
      <T n="visible">False</T>
    </I>
    

    So if you're making a new/modified posture, you might try creating a custom version of this interaction and add it to object_terrain super_affordances, with the _provided_posture_type being your toilet stand posture, instead of Maxis's. (Not sure terrain is treated in the same way as most objects though.)

    Or maybe try adding it to postures.posture_graph in the POSTURE_PROVIDING_AFFORDANCES section.
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • lexus20lexus20 Posts: 1,302 Member
    Good news (almost)! The animation finally played (with sound, effects, everything), I guess the problem was that I needed to add the generic interaction to postures.posture_graph, the route fail was happening probably because of this. The problem now is that the sim is not walking to the spot where I clicked anymore, he pees right where he is, although the puddle spawns where I clicked, not where he peed.
  • TriplisTriplis Posts: 3,048 Member
    Awesome! Does it still have the circle constraint at all? You could try adding that back in, if not, and see if it still works.

    If that fails, maybe try structuring it as two interactions, the way stuff like pushups does it? Where the first interaction is a GoHere with a circle constraint and then it does a continuation into the main peeing interaction?
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • lexus20lexus20 Posts: 1,302 Member
    Thank you so much for the help! I used two interactions and it's now fully working! I had actually tried using two interactions but I had forgot to change object_terrain to the first interaction rather than the second. Just one thing, do you know how could I change the position where the puddle spawns? It's spawning right under the sim rather than in his front where he peed. This is a minor thing, though, I'm very happy that the mod is working! Next I will try to use a script instead of replacing object_terrain. Do I need to make a script too for postures.posture_graph?
  • TriplisTriplis Posts: 3,048 Member
    Awesome! Glad I could be of help. :smile:

    As far as where the puddle spawns, I did a quick search and found this (this is from a LootActions file):
    <V t="create_puddles">
          <U n="create_puddles">
            <U n="default_puddle_factory">
              <T n="large">0</T>
              <E n="liquid">WATER</E>
              <T n="medium">1</T>
              <T n="none">0</T>
              <T n="small">4</T>
            </U>
            <T n="max_distance">2.5</T>
            <E n="subject">Actor</E>
            <E n="target_participant_type">Object</E>
          </U>
        </V>
    

    So it looks like choosing where the puddle spawns is definitely possible to some extent. Your target_participant_type would probably want to be set to Object as it is in the example above, since your target participant is terrain (a type of object). max_distance might help with tweaking where it lands?

    I would recommend looking at the TDESCs under Actions > Descriptions > LootActions.tdesc and see what all possible commands can be used in determining where a puddle spawns.

    Altho, just having it be set to spawn on target_participant_type as Object might do it.

    I'm not really sure. Haven't messed with puddle spawning a lot.


    W/ regards to scripts: @TURBODRIVER might know if there's a way to inject to postures.posture_graph, as opposed to using an override. I've never attempted it myself. If anyone knows, he probably would.

    For injecting to object_terrain, I know that can be done and is pretty straightforward. If you need or want code samples for injecting to object_terrain, feel free to ask. I'm sure I have an example laying around somewhere in stuff I've done.
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • lexus20lexus20 Posts: 1,302 Member
    I couldn't change the puddle spawning but I think it's okay the way it is, it doesn't bother me that much.

    I tried to make a script based off the one from this thread by replacing the names and interaction hash ids to inject the interactions to object_terrain but how should I add it to the package? Do I save it as .py and put it in the Mods folder or do I need a .pyo file too? If a .pyo is needed, how does that file need to be? This is my first time scripting so I'm not really sure.

    Script:
    import services
    import injector
    import sims4.resources
    from sims4.tuning.instance_manager import InstanceManager
    from sims4.resources import Types
    
    TS40_PeeHere_Interactions_ObjectTerrain_sa_instance_ids = (15295192161465113131, 6192637829597138744,)
    TS40_PeeHere_Interactions_ObjectTerrain_object_ids = (14982,)
    
    @injector.inject_to(InstanceManager, 'load_data_into_class_instances')
    def add_superaffordances(original, self):
        original(self)
    
        if self.TYPE == Types.OBJECT:
            affordance_manager = services.affordance_manager()
            sa_list = []
            for sa_id in TS40_PeeHere_Interactions_ObjectTerrain_sa_instance_ids:
                key = sims4.resources.get_resource_key(sa_id, Types.INTERACTION)
                sa_tuning = affordance_manager.get(key)
                if not sa_tuning is None:
                    sa_list.append(sa_tuning)
            sa_tuple = tuple(sa_list)
    
            for obj_id in TS40_PeeHere_Interactions_ObjectTerrain_object_ids:
                key = sims4.resources.get_resource_key(obj_id, Types.OBJECT)
                obj_tuning = self._tuned_classes.get(key)
                if not obj_tuning is None:
                    obj_tuning._super_affordances = obj_tuning._super_affordances + sa_tuple
    
  • TriplisTriplis Posts: 3,048 Member
    For testing purposes (e.g. to try out the script before compiling), you go to your Mods folder and created a folder inside of it called Testing. Then a folder inside of Testing called Scripts. And then put any .py files in the Scripts folder. So it'll look like Mods > Testing > Scripts

    For sharing the final product with others, you'll want to compile, to make it into a .pyo file, which can be read by the game without being in the special testing/scripts folder.

    To compile, you first want to download Python 3.3. For me, after downloading, it's located in C:\Python33

    Put a copy of your scripts in the Python33 folder.

    Then I pull up the start menu and in the search box, put in the file path for Python 33, python.exe, and then append -O at the end. So something like this: C:\Python33\python.exe -O

    If the path is right, this should bring up an option to open up a python.exe command prompt.

    When you've opened the command prompt that comes up, type in;

    import myScriptName

    Where myScriptName is the name of your script, obviously. :tongue:

    And just do that for every script you put in the Python33 folder.

    When you're finished, go into __pycache__ folder within Python33 and there should be a .pyo file for each script you compiled. Its name will have some extra stuff in it (I forget the syntax). Just change its name back to what it was originally (with the exception of the file extension, of course).

    Now that you have your compiled scripts together, you can put them in a zip file and then change the file extension from .zip to .ts4script (this is just so that it's more clear to people using your mod that the script part is not something they're meant to unzip). Then put it in your Mods folder (*not* within the testing folder this time, since it's compiled and zipped now). I suggest testing it in its compiled form, to be sure compiling went as expected.

    Then you're good to go!
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • lexus20lexus20 Posts: 1,302 Member
    Thank you so much, it worked perfectly! :)
  • QuintessedlQuintessedl Posts: 6 New Member
    Hi there! Sorry to piggyback on this thread but I am having animation issue and this is the closest thread to my issue that I've seen.

    I have been trying to just simply override the animations for the Yoga skill-- exporting the corresponding animation pose as a base, creating my own animation and importing the animation to the mod override file. However, every time I try to replace the pose "a2o_yoga_posture_getIn_x" and playtest it, my sim gets a routing failure. Other poses seem to work fine when being overwritten.

    Could this be a tuning issue? I do not have coding experience and most tuning troubleshooting goes way over my head. I guess I am looking for guidance as to if this could be a very simple fix or if I'm treading into deep waters. Thank you!

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file
Return to top