Forum Announcement, Click Here to Read More From EA_Cade.

Mood Tests

TriplisTriplis Posts: 3,048 Member
edited March 5 in Nominated Threads
Maybe I'm interpreting it wrong, but as far as I can tell, mood tests are based on the dominant mood, rather than existing moodlets overall. So, for example, the phenomenon (which I'm now understanding the why) where your sim is super sad, so you're using the Sadness Hotline to drain it down. Then suddenly some other mood dominates for a bit and Sadness Hotline is unavailable. But they're still Sad underneath, they just can't use Sadness Hotline on it because it's not the dominant mood.

Would it be possible to create a test in the future that checks for existing moods of a type, as opposed to only testing for what the dominant mood is? (Or is there already such a test and I'm missing it?)

I was trying to create a custom interaction that involves draining Happy moodlets and running into the problem that it cancels out because the dominant mood changes. What I wanted is for it to cancel out once all Happy moodlets are gone. But there doesn't seem to be a supported way to do this.
Mods moved from MTS, now hosted at: https://triplis.github.io
Post edited by EA_Cade on

Comments

  • TURBODRIVERTURBODRIVER Posts: 68 Member
    Hey @Triplis

    So you're looking for a test that would result positive if a Sim has a moodlet of a specific mood?
    It's not hard to write a test that would do it (https://pastebin.com/QwJQ0jRM), but I haven't found a way to inject that test into the game.

    Tests are done via TunableTestVariant class that holds all of the tests inside of it and then that class is initiated by specific tunable types. The only way I would see it happen is if you would runtime edit the TunableGlobalTestSet class (global test of interactions) somehow, but good luck with that. It's probably possible and someone might have done that already, but if you get so deep into scripting, you might as well do the test yourself with a custom class interaction. It's far far easier.

    And to your question "Would it be possible to create a test in the future that checks for existing moods of a type", where, I guess, you're asking the developers. Have they ever made anything that is >purely< for modding except the 'Mods' folder that loads the mods? They made great work with allowing for modding, but I don't think they could have planned for such deep modding.
  • Hadron1776Hadron1776 Posts: 330 Member
    Just use the statistic_in_category test. I've noticed that very few buffs aren't tagged with their appropriate mood type. Does that help? ;)
  • TURBODRIVERTURBODRIVER Posts: 68 Member
    @Hadron1776 has a good point, testing for tags would be a much better idea and then only mods that have not tagged moodlets with the mood would be a problem. Yet, I don't think this will work since moodlets aren't statistics. Now, I don't know, I am just saying that they aren't statistics, but I may not know about a different way of testing for tags.
  • Hadron1776Hadron1776 Posts: 330 Member
    edited June 2017
    @TURBODRIVER Buffs with timeouts have them because of this:
      <V t="enabled" n="_temporary_commodity_info">
        <U n="enabled">
          <L n="categories">
            <E>Embarrassed_Buffs</E>
          </L>
          <T n="max_duration">480</T>
        </U>
      </V>
    
    Which creates a temporary statistic with a max value of 'max_duration' and a decay rate of 1. The only real caveat is that I don't think the commodities can be accessed explicitly as they're tied to their buffs. However, you can still use 'decay_modifier_by_category', or 'statistic_(change|remove)_by_category' and it will affect the buffs as well. Also note that these tags can also be applied to instanced commodities as well.

    P.S. Moodlets and buffs are the same thing. Apparently, they're 'buffs' in the source code, but 'moodlets' in the tutorial/other things that are player facing. It's the same thing in TS3. I don't know why they're named differently, though.
  • TriplisTriplis Posts: 3,048 Member
    Hey guys, quick reply for now. First, thanks for the input. Haven't looked at your script in-depth yet, Turbodriver, so maybe it covers this, but... a little clarification for both of you:

    The test (at least for how I'm wanting to do what I'm doing) needs to be a test within an interaction. Interactions have some existing possible tests for exiting the interaction, like buff_based, time_based, etc. One of them is mood_based, but as far as I can tell, mood_based only checks for entering a mood or (when inverted) checks for exiting a mood. I'd want something that can check for the existence of a particular mood, but within those type of interaction tests. That's why statistic_in_category probably won't work; it's not part of the interaction tests.
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • Hadron1776Hadron1776 Posts: 330 Member
    Idea: You probably won't be able to tie it directly in with 'statistic_in_category', you might be able to rig it in 'operation_actions' under periodic_stat_change', where you add a buff to the Sim once all the happy moodlets go away. Then you key the interaction to end as soon as said buff is added. Might that work? :)
  • TriplisTriplis Posts: 3,048 Member
    Hadron1776 wrote: »
    Idea: You probably won't be able to tie it directly in with 'statistic_in_category', you might be able to rig it in 'operation_actions' under periodic_stat_change', where you add a buff to the Sim once all the happy moodlets go away. Then you key the interaction to end as soon as said buff is added. Might that work? :)
    Hmm. Not sure I'm totally following what your idea is.

    Here's a sample of how the code can look so we're working with a more concrete example:
      <V n="basic_content" t="flexible_length">
        <U n="flexible_length">
          <L n="conditional_actions">
            <V t="literal">
              <U n="literal">
                <L n="conditions">
                  <V t="buff_based">
                    <U n="buff_based">
                      <T n="buff">Buff ID Here<!--Buff: OnAdd_EndInteraction_Buff--></T>
                      <E n="timing">ON_ADD</E>
                    </U>
                  </V>
                </L>
                <E n="interaction_action">EXIT_NATURALLY</E>
              </U>
            </V>
    	<V t="literal">
              <U n="literal">
                <L n="conditions">
                  <V t="mood_based">
                    <U n="mood_based">
                      <T n="invert">True</T>
                      <T n="mood">14640<!--Mood: Mood_Happy--></T>
                    </U>
    		<E n="who">TargetSim</E>
                  </V>
                  <V t="time_based">
                    <U n="time_based">
                      <T n="min_time">15</T>
                    </U>
                  </V>
                </L>
                <E n="interaction_action">EXIT_NATURALLY</E>
              </U>
            </V>
          </L>
          [animations code here]
          <V n="periodic_stat_change" t="enabled">
            <U n="enabled">
              <L n="operations">
              [stat changes here]
              </L>
            </U>
          </V>
          <T n="start_autonomous_inertial">False</T>
          <V t="enabled" n="statistic_reduction_by_category">
            <U n="enabled">
              <L n="categories">
                <E>Happy_Buffs</E>
              </L>
              <T n="rate">5</T>
              <L n="subject">
                <E>TargetSim</E>
              </L>
            </U>
          </V>
    

    As far as what you're saying, I'm not sure how you'd get it to add a buff based on the stat changes.

    Something that I've done in other interactions (based on some of the Vampire Mind Control interactions) is use a buff_based, but that's a setup where it's a buff that is triggered by a player interaction; in the Vampire case, dispelling some kind of control, which frees the target from the interaction.

    In other words, there's a separate interaction (Dispel) and when the player uses it, its loot includes a buff (the same buff that is inside the ON_ADD exit condition for the "mind control" interaction), if that makes sense.

    What I'm currently thinking is maybe it'd be best to, rather than attempt to test precisely for buff existence, make the interaction purely time-based, with the ability for the player to cancel out of it. For example, make an interaction that drains Happy and it just goes for something like 15 seconds, whether the target still has Happy buffs or not. The player can then choose to let it run its length or cancel it out early.

    A more involved way to play for the player, but at least it would be less jerky in terms of ending early.

    The other approach I'm considering for one of my planned interactions is to do a set duration (ex: 15 seconds) like the other example, but with one addition: At the end of the interaction, it does a loot that instantly removes all moods of a type. So it reduces duration over time and if any are left over at the end, it removes them instantly. Bit of a... I don't know... weak design?, I think, as the player would be able to cancel the interaction early with an ON_ADD Dispel kind of thing, giving them a much quicker removal of the relevant mood than waiting out any of the interaction's timer. And yet, it may not be entirely arbitrary; I intend to have periodic skill gain as part of the interaction, so if the player is trying to gain points in the skill, that would give them a reason to let the interaction play out its length, rather than canceling it early.
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • Hadron1776Hadron1776 Posts: 330 Member
    edited June 2017
      <V n="basic_content" t="flexible_length">
        <U n="flexible_length">
          <L n="conditional_actions">
            <V t="literal">
              <U n="literal">
                <L n="conditions">
                  <V t="buff_based">
                    <U n="buff_based">
                      <T n="buff">Auto-added buff here<!-- This buff to end the interaction automatically--></T>
                      <E n="participant">TargetSim</E>
                      <E n="timing">ON_ADD</E>
                    </U>
                  </V>
                </L>
                <E n="interaction_action">EXIT_NATURALLY</E>
              </U>
            </V>
            <V t="literal">
              <U n="literal">
                <L n="conditions">
                  <V t="buff_based">
                    <U n="buff_based">
                      <T n="buff">Dispel buff here<!--This buff for the player to dispel the SI manually (SI = SuperInteraction, SA is super affordance. They're the same thing, really)--></T>
                      <E n="participant">TargetSim</E>
                      <E n="timing">ON_ADD</E>
                    </U>
                  </V>
                </L>
                <E n="interaction_action">EXIT_NATURALLY</E>
              </U>
            </V>
          </L>
          <V t="staging_content" n="content">
            <U n="staging_content">
             [animation code]
              <U n="content_set">
                <L n="affordance_links">
                  <T>Alternative secondary affordance here<!--Or you could add the buff in an affordance link--></T>
                </L>
              </U>
            </U>
          </V>
          <V n="periodic_stat_change" t="enabled">
            <U n="enabled">
              <U n="operation_actions">
                <T n="alarm_interval">1</T>
                <L n="actions">
                  <T>Action ID here <!-- This action adds the buff that ends the interaction--></T>
                </L>
              </U>
               <L n="operations">
                 [stuff]
               </L>
             </U>
            </V>
          <V t="enabled" n="statistic_reduction_by_category">
            <U n="enabled">
              <L n="categories">
                <E>Happy_Buffs</E>
              </L>
              <T n="rate">5</T>
              <L n="subject">
                <E>TargetSim</E>
              </L>
            </U>
          </V>
    <!--More stuffs here, don't forget to close tags :)-->
      <L n="provided_affordances">
        <U>
          <T n="affordance">SI to allow the player to dispel this manually. This will automatically show up when the target is running this SI (provided he/she passes the other tests)</T>
        </U>
      </L>
    

    Do not use mood_based as a separate condition. The interaction ends if any of the conditional actions specify an EXIT_NATURALLY or EXIT_CANCEL action. In the loot you could do something like this:
      <L n="loot_actions">
        <V t="buff">
          <U n="buff">
            <U n="buff">
              <T n="buff_type">Buff ID from above<!--Add the buff to end the interaction here--></T>
            </U>
            <E n="subject">TargetSim</E>
           <L n="tests">
              <L>
                <V t="statistic_in_category">
                    <U n="statistic_in_category">
                      <T n="check_for_existence">False</T>
                      <E n="statistic_category">Happy_Buffs</E>
                      <E n="who">TargetSim</E>
                    </U>
                 </V>
               </L>
             </L>
          </U>
        </V>
      </L>
    

    And BTW, I've tried adding the "end interaction" buff directly under 'conditional_actions' and had problems (though that may be due to awkward test sets, so IDK), so that's why I'm proposing to do it this way. Either do it under 'operation_actions' with the 'alarm_interval' set to 1, or you can do it as an outcome in an affordance link.

    Another thing you could to is shift some of the operations to the target:
      <V n="affordance_to_push_on_target" t="push_affordance">
        <T n="push_affordance">affordance<!--here!--></T>
      </V>
    

    Using a "pusher" would also work (A pusher just being a one-shot interaction that has a continuation to push on the target. That continuation would be the 'real' SI in that case.) That would have the advantage of forcing one of the two outcomes, especially if you put 'prohibit_cancelation' on the continuation:
      <V n="outcome" t="test_based">
        <U n="test_based">
          <L n="fallback_outcomes">
            <U>
              <U n="outcome">
                <L n="continuation">
                  <U>
                    <T n="affordance">super affordance goes here</T>
                    <E n="actor">TargetSim</E>
                  </U>
                </L>
                <L n="loot_list">
                  <T>loot ID<!--Other stuff you might want--></T>
                </L>
              </U>
            </U>
          </L>
         </U>
        </V>
    

    The only caveat with this method is that it might make it difficult to have a periodic skill gain, though. The point is, ending the interaction when all the happy buffs are gone is entirely doable (Though you'll probably get a delay of a minute or so)
    Post edited by Hadron1776 on
  • TriplisTriplis Posts: 3,048 Member
    Hadron1776 wrote: »
    Do not use mood_based as a separate condition. The interaction ends if any of the conditional actions specify an EXIT_NATURALLY or EXIT_CANCEL action.
    I know it's an OR condition.

    But thank you, your example seems to work. I had so far either missed or glazed over operation_actions and looting during an interaction, so that's why I was not understanding.

    It makes perfect sense now I've tried implementing it and I haven't seen any indication of it messing with periodic skill gain.

    I left in my skill gain in addition to operation_actions and it works fine.

    Also, I simplified from your example a little bit. Since I already had a manual ON_ADD buff exit condition from using an interaction (like in the vampire case). I just reused that same buff for the one that gets added in operation_actions loot. So one less check needed in conditions. I just have the one on_add check.
    Mods moved from MTS, now hosted at: https://triplis.github.io

Leave a Comment

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