Replies: 7 (Who?), Viewed: 296 times.
Virtual gardener
staff: administrator
Original Poster
#1 Old 28th Jul 2020 at 12:27 PM Last edited by Lyralei : 28th Jul 2020 at 2:53 PM.
Default Alarms and persisted data
Hi everyone!
This is indeed a lot for one question tbh :p but one is more or less a "am I doing this right" and the other is just really confusing me. Again, it's about data getting resetted on reloading the game. 

1. Persistable Data
Currently I'm trying to keep data stored during gameplay in a dictionary. The dictionary holds both a SimDescription and a Resource key, so that I can figure out who already discovered what objects. Now, using the example given in this thread I've come up with this:

Code:
    [Persistable]
    public class PersistedData
    {
        [Persistable]
        public Dictionary<SimDescription, ResourceKey> mDiscoveredObjects;
      
        public PersistedData()
        {
            if(mDiscoveredObjects == null)
            {
                mDiscoveredObjects = new Dictionary<SimDescription, ResourceKey>();
            }
        }
        
        public void Cleanup()
        {
            mDiscoveredObjects = null;
        }
    
And in my 'instantiator' class I've done the following:

Code:
        [PersistableStatic]
        protected static PersistedData sSettings;
        
        public static PersistedData retrieveData
        {
            get 
            {
                if (GlobalOptionsSewingTable.sSettings == null) 
                {
                    GlobalOptionsSewingTable.sSettings = new PersistedData();
                }
                return GlobalOptionsSewingTable.sSettings;
            }
        
I *think* either I'm misunderstanding what the persistable data does or it being the Cleanup that sets it back to null after the player saves and quits the game. But I'm not entirely sure.

Now I will say, I do re-instantiate it in the following way when calling the dictionary var, which feels odd to me, hence why I'm mentioning it :p This is just an example of one of the ways I do it (keep in mind that they're inside static functions):

Code:
PersistedData pd = new PersistedData();

if(pd.whoIsInPatternClub.ContainsKey(ActorDesc))
{
    pd.whoIsInPatternClub.Remove(ActorDesc);
(actorDesc being obviously the actor's SimDescription).

tl;dr: How do I keep the dictionary data that has been obtained, even when the game has been saved, quit and later rebooted again?

2. Alarms
My second problem is the alarms I set up on the mailboxes. This alarm basically gives a pattern to the mailbox and the mailperson will deliver said pattern. Now, again (lol), that also gets reset on restarting the game. And I just can't seem to see why, since I did actually look really closely to what EA did. Here's what I have:

Code:
public static void OnWorldLoadFinished(object sender, EventArgs e)
{    
    JoinPatternClub club = new JoinPatternClub(); // JoinPatternClub is a computer interaction.
    mPatternClubAlarm = AlarmManager.Global.AddAlarmDay(1f, DaysOfTheWeek.Thursday, club.SendPatterns, "Mailbox:  Pattern club", AlarmType.NeverPersisted, null);
}

public static void OnWorldQuit(object sender, EventArgs e)
{
   AlarmManager.Global.RemoveAlarm(mPatternClubAlarm);
   mPatternClubAlarm = AlarmHandle.kInvalidHandle;
}
I also tried doing this:

Code:
static GlobalOptionsSewingTable() // Is the instantiator
{
   LoadSaveManager.ObjectGroupsPostLoad += new ObjectGroupsPostLoadHandler(GlobalOptionsSewingTable.OnPostWorldLoad);
}
public static void OnPostWorldLoad()
{
   JoinPatternClub club = new JoinPatternClub();
   GlobalOptionsSewingTable.mPatternClubAlarm = AlarmManager.Global.AddAlarmDay(1f, DaysOfTheWeek.All, club.SendPatterns, "Mailbox:  Pattern club", AlarmType.NeverPersisted, null);
But alas, it no work :p

Again, sorry for throwing so much at you guys! Hopefully it's a bit clear, but do let me know if it isn't. The current Sewing table that has been uploaded doesn't have this code, so that's not really a great reference to use if you do .
Advertisement
Virtual gardener
staff: administrator
Original Poster
#2 Old 28th Jul 2020 at 6:43 PM
Regarding the first issue, turns out that I hadn't put the following in my Assembly info:

Code:
 [assembly: PersistableStatic
Big thanks to @battery !

Still trying to figure out the alarm issue though. I'm almost wondering if I should change 'AlarmType.NeverPersisted' to 'AlwaysPersisted'
Virtual gardener
staff: administrator
Original Poster
#3 Old 29th Jul 2020 at 9:56 AM
Quote:
Originally Posted by Lyralei
Regarding the first issue, turns out that I hadn't put the following in my Assembly info:

Code:
 [assembly: PersistableStatic
Big thanks to @battery !

Still trying to figure out the alarm issue though. I'm almost wondering if I should change 'AlarmType.NeverPersisted' to 'AlwaysPersisted'
Given how now the dictionaries actually save which sims have joined the book club, I guess what I can do, is on world load see if any sims in the active household are members of the bookclub and re-add the alarm that way. Problem with this, however, (I think) Is that the game wouldn't re-do this for other households that have this. But then doing the check for all households in one go feels like it will affect the performance... 
Test Subject
#4 Old 29th Jul 2020 at 3:43 PM
I'm still pretty green so who knows if I understand anything, but does the OnWorldQuit method not guarantee that mPatternClubAlarm will always be removed and need to be reset every time you leave and reload the world, no matter how that alarm is made? If not I've been misunderstanding how those work all this time and need to fix something I'm working on

Also I'm curious what the difference between alarm types is, I've always just sort of guessed at that. I'm going to test and see if my pregnancy moodlets mod also has this problem with alarms resetting, since I use a NeverPersisted alarm for that too but don't remove it on world quit. Hey, I wonder if you could make a dictionary of alarm handles...
Field Researcher
#5 Old 29th Jul 2020 at 7:16 PM Last edited by Battery : 29th Jul 2020 at 7:44 PM.
So i overread your Alarm question last time.

Are you sure your club.SendPatterns is able to be called since i dont see it beeing persistable or static.

E: Make sure your callback method exists !

A bit from my Abductor mod (slightly altered)
Code:
objektalarmhandler = AlarmManager.Global.AddAlarmDay(8,DaysOfTheWeek.All, Timer, "alarm", AlarmType.AlwaysPersisted,null);


Works for me (Timer is a method thats either static or part of ther persistable class instance)
Field Researcher
#6 Old 30th Jul 2020 at 1:42 AM Last edited by gamefreak130 : 30th Jul 2020 at 2:00 AM.
Quote:
Originally Posted by lizcandor
I'm still pretty green so who knows if I understand anything, but does the OnWorldQuit method not guarantee that mPatternClubAlarm will always be removed and need to be reset every time you leave and reload the world, no matter how that alarm is made? If not I've been misunderstanding how those work all this time and need to fix something I'm working on


That's correct -- in fact, explicitly clearing the alarm on WorldQuit is unnecessary, since the alarm is NeverPersisted and the game purges the global AlarmManager automatically. That should be okay here, though, as it will be re-applied with (presumably) the exact same functionality on WorldLoadFinished.

@Lyralei If possible, I would try making your callback a static function. That's what EA does for the book club alarms, after all.

Quote:
Originally Posted by lizcandor
Also I'm curious what the difference between alarm types is, I've always just sort of guessed at that. I'm going to test and see if my pregnancy moodlets mod also has this problem with alarms resetting, since I use a NeverPersisted alarm for that too but don't remove it on world quit. Hey, I wonder if you could make a dictionary of alarm handles...


Here's a comparison table for reference:

Alarm TypePreserved when owner object is reset?Preserved on saving and quitting?
AlwaysPersistedYesYes
DeleteOnResetNoYes
NeverPersistedNoNo


Owner objects are the GameObjects passed as the last argument to the alarm add methods. Typically they are null for global alarms, in which case DeleteOnReset and AlwaysPersisted are functionally equivalent. Global alarms almost never need to be persisted, though -- just readded on WorldLoadFinished. That way, there's a little bit less to save and load in an already-bloated game.

"The Internet is the first thing that humanity has built that humanity doesn't understand, the largest experiment in anarchy that we have ever had." - Eric Schmidt

If you enjoy the mods I put out, consider supporting me on patreon: www.patreon.com/Gamefreak130
Virtual gardener
staff: administrator
Original Poster
#7 Old 31st Jul 2020 at 3:59 PM
This is super helpful! Thank you @gamefreak130  The source code, I will say, was pretty confusing to figure out what it does, so thanks again for making such a great scheme there!

Quote:
Originally Posted by Battery
Are you sure your club.SendPatterns is able to be called since i dont see it beeing persistable or static.


Quote:
Originally Posted by gamefreak130
@Lyralei If possible, I would try making your callback a static function. That's what EA does for the book club alarms, after all.
Not a bad idea. Would need to do some code shifting and what-not (Since I somehow thought it's a good idea to put the original function in the interaction, which you can't really make any static functions inside of). But I think indeed this will probably fix it. Thanks for your help again! You guys are great
Test Subject
#8 Old 31st Jul 2020 at 11:09 PM
That table is exactly what I needed to know! Thank you!
Back to top