Hi there! You are currently browsing as a guest. Why not create an account? Then you get less ads, can thank creators, post feedback, keep a list of your favourites, and more!
Test Subject
Original Poster
#1 Old 11th Dec 2023 at 12:55 AM
Default kGotBuff event not working? Or working as intended?
I have a question regarding the kGotBuff EventType: from reading excerpts here on the forums, I was under the impression that this event would trigger anytime that a Sim gained a new moodlet. I was experimenting with this EventType so as to understand the fundamentals, but my experience in testing has consistently been that the event will trigger once for the first Sim in the active household to gain a moodlet, and then never again for any Sim in town, including upon switching active households. Does the Listener need to somehow be refreshed/reinstantiated after each event trigger? Does kGotBuff not actually trigger for every instance of a moodlet gain? The code I've written is below: if there is some glaring oversight I've missed, it would be a tremendous help if anyone could point it out.

Code:
namespace DubbleDeez
{   
    public class GarlicTest
    {
        [Tunable]
        protected static bool kInstantiator = false;
        private static EventListener sOnGotBuffListener = null;

        static GarlicTest()
        {
            World.OnWorldLoadFinishedEventHandler += new EventHandler(OnWorldLoadFinishedHandler);
        }

        public static void OnWorldLoadFinishedHandler(object sender, System.EventArgs e)
        {
            sOnGotBuffListener = EventTracker.AddListener(EventTypeId.kGotBuff, new ProcessEventDelegate(OnGotBuff));  
        }               

        private static ListenerAction OnGotBuff(Event e)
        {
            Sim sim = e.Actor as Sim;
            if (sim != null)
            {
                OnGotBuffRun(sim);
            }
            return ListenerAction.Keep;
        }

        public static void OnGotBuffRun(Sim s)
        {
            if (!s.BuffManager.HasElement(Sims3.Gameplay.ActorSystems.BuffNames.GarlicBreath))
            {
                s.BuffManager.AddElement(Sims3.Gameplay.ActorSystems.BuffNames.GarlicBreath, Sims3.Gameplay.ActorSystems.Origin.FromEatingGarlic);
            }                        
        }
    }
}
Advertisement
Test Subject
Original Poster
#2 Old 11th Dec 2023 at 2:04 PM
I became suspicious that applying moodlets during an event that was listening for the application of moodlets might be causing some sort of recursive loop, despite having included a check for whether the applied moodlet was already present. I changed up the code to affect something other than the moodlets themselves, and now kGetBuff appears to be operating as expected:

Code:
public static void OnGotBuffRun(Sim s)
        {
            s.SimDescription.FirstName = "OnGotBuff";
        }


I now have a town full of Sims named "OnGotBuff", demonstrating that kGotBuff does indeed trigger on every instance of a moodlet gain. But why was the original code causing a hangup? To my understanding, the order of operations should have been as follows:

  • Sim gains moodlet, triggering kGotBuff
  • Method is called, checking whether GarlicBreath moodlet is present on Sim
    • If present, end method
    • If absent, add GarlicBreath
  • If GarlicBreath moodlet was added, recursively trigger kGotBuff, which should then check for and find moodlet, ending the method

Does anybody have any idea why the original method would always get stuck on the first Sim in town to gain moodlets?
Test Subject
#3 Old 11th Dec 2023 at 5:29 PM
After some digging, I found the reason in the AddBuff function, which gets called by the AddElement function: the kGotBuff event gets send before the buff gets added to the BuffManager. This creates an endless loop for your code.

What exactly is your goal here?

Also a better way to check, if the added Buff is the one you want:
Code:
public static ListenerAction OnGotBuff(Event e)
{
    HasGuidEvent<BuffNames> hasGuidEvent = e as HasGuidEvent<BuffNames>;
    BuffInstance buff= hasGuidEvent.HasGuidObject as BuffInstance;
    if(buff.BuffGuid==(ulong)BuffNames.GarlicBreath)
    {
    }
    return ListenerAction.Keep;
}
Test Subject
Original Poster
#4 Old 11th Dec 2023 at 7:33 PM
Quote: Originally posted by Rites
What exactly is your goal here?

Just to better understand the execution order of the kGotBuff event, and whether moodlet addition/removal could be interrupted/responded to. However, if the BuffManager doesn't get updated until after the event has already been triggered, there doesn't seem an elegant way of making instant alterations to Sims' moodlets.

Thank you very much for the code suggestion: that could be very useful for flagging Sims for future moodlet adjustment.

I'll continue looking through the forums for ideas, but if anyone knows of a way to delay the execution of a method by a specified in-game time, such that it could allow a moment for the BuffManager to update beforehand, I think that would be helpful for better implementing kGotBuff events as I had originally imagined them.
Test Subject
#5 Old 11th Dec 2023 at 8:25 PM
You could try executing your function after some time passed. That way it might add the buff before you execute your function for a second time.

You can delay your funtion with OneShotFuntionTask, e.g.:

Code:
Simulator.AddObject(new OneShotFunctionTask(OnGotBuffRun(Sim s), StopWatch.TickStyles.Seconds, 0.1))

this executes your function once after 0.1 seconds
Back to top