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!
Quick Reply
Search this Thread
Field Researcher
Original Poster
#26 Old 8th Aug 2015 at 6:31 AM
So I want to try to tackle this now. Anyone have any experience with dictionaries? And Lot IDs? I've read this tutorial http://simswiki.info/index.php?titl...ata&oldid=58323 so I am vaguely familiar with the concept ... but that tutorial talks about Sim IDs and storing info for a particular Sim.

I want to use a particular lot ID and store whether or not it is accepting roommates, and then be able to recall that when a lot is loaded. (Basically, this will let the game "remember" the status of roommates in every lot, something it does not do now.) I have this so far:



I'm not sure what to do with the Lot ID, and also where I have ??????. Also not sure if this even does what I want it to. Any suggestions?
Advertisement
Field Researcher
#27 Old 9th Aug 2015 at 3:59 PM
A dictionary may not even be necessary in this case, a list should suffice. Try setting up a new List<ulong>, and whenever roommates are enabled for a lot add the LotId of the lot to the list, and remove the LotId from the list when roommates are disabled. You then need a method to run whenever the active lot is changed which simply checks if the new active lot's LotId is in the list or not and sets the value of Household.RoommateManager.mAcceptingRoommates accordingly. As to how to get a method to run when the active lot has been changed, I've not tried this personally so can't guarantee that it works, but from the looks of it the following should work

LotManager.ActiveLotChanged += new LotManager.ActiveLotChangedHandler(OnActiveLotChanged);
//you can try running this line when the world first loads if running it when your script is initialized doesn't work

public static void OnActiveLotChanged(object sender, LotManager.ActiveLotChangedArgs e)
{
//code that needs to run when active lot has changed here. To retrieve the new active lot, use "e.mNewActiveLot"
}
Field Researcher
Original Poster
#28 Old 9th Aug 2015 at 7:08 PM
Quote: Originally posted by icarus_allsorts
A dictionary may not even be necessary in this case, a list should suffice. Try setting up a new List<ulong>, and whenever roommates are enabled for a lot add the LotId of the lot to the list, and remove the LotId from the list when roommates are disabled. You then need a method to run whenever the active lot is changed which simply checks if the new active lot's LotId is in the list or not and sets the value of Household.RoommateManager.mAcceptingRoommates accordingly. As to how to get a method to run when the active lot has been changed, I've not tried this personally so can't guarantee that it works, but from the looks of it the following should work

LotManager.ActiveLotChanged += new LotManager.ActiveLotChangedHandler(OnActiveLotChanged);
//you can try running this line when the world first loads if running it when your script is initialized doesn't work

public static void OnActiveLotChanged(object sender, LotManager.ActiveLotChangedArgs e)
{
//code that needs to run when active lot has changed here. To retrieve the new active lot, use "e.mNewActiveLot"
}


Ok, thanks! I'll give it a shot. I have to read up some about Lists, but that shouldn't be too hard to figure out.

I've been wanting to know how to do something else when the active lot changes, so this might come in handy for that, too!

Does the underlined parts signify something in particular??
Field Researcher
Original Poster
#29 Old 10th Aug 2015 at 3:02 AM
Quote: Originally posted by pjsutton
Ok, thanks! I'll give it a shot. I have to read up some about Lists, but that shouldn't be too hard to figure out.

I've been wanting to know how to do something else when the active lot changes, so this might come in handy for that, too!

Does the underlined parts signify something in particular??


Okay, I think I almost (possibly) have it working, but I'm getting a bizarre error with this line of code:

Code:
 LotManager.ActiveLotChanged += new LotManager.ActiveLotChangedHandler(RoommatesFix.OnActiveLotChanged); 


It's saying:
Quote:
Error 3 Ambiguity between 'Sims3.Gameplay.Core.LotManager.ActiveLotChanged' and 'Sims3.Gameplay.Core.LotManager.ActiveLotChanged'


I checked in ILSpy and there are 2 "ActiveLotChanged" entries in Sims3.Gameplay.Core.LotManager. One has a lightning bolt icon and one has the regular blue block. I'm assuming this is why I'm getting that error, but I don't know how to proceed from here!
Field Researcher
#30 Old 10th Aug 2015 at 3:24 AM
That's one of the tougher errors to get by, that particular dll will need to be recompiled somehow for that to work. You might have to try using the unprotected game dlls shared over at the NRaas github or here: http://nraas.wikispaces.com/Creating+an+NRaas+project (you'll be getting all the NRaas project files but the dlls you're seeking are found in the Sims 3 \ compiler folder as per the information on the link)
Field Researcher
Original Poster
#31 Old 10th Aug 2015 at 5:22 AM Last edited by pjsutton : 10th Aug 2015 at 6:25 AM.
Quote: Originally posted by icarus_allsorts
That's one of the tougher errors to get by, that particular dll will need to be recompiled somehow for that to work. You might have to try using the unprotected game dlls shared over at the NRaas github or here: http://nraas.wikispaces.com/Creating+an+NRaas+project (you'll be getting all the NRaas project files but the dlls you're seeking are found in the Sims 3 \ compiler folder as per the information on the link)


Okay - I downloaded that, and found the DLL (it's Sims3GameplaySystems) and I changed the reference in Visual Studio to the new DLL, compile, etc. Open the game and I can see that it's working -- I want it to check for this right when a lot is loaded, and it does! I know because I have it displaying a message -- except that the game is screwed up. Build and Buy mode are grayed out, and as soon as I unpause, the game crashes. Was I supposed to include the new DLL in my .package file as a separate S3SA? I'm thinking yes.

EDIT: I tried that, and it didn't work either. When I take the mod out of the packages folder it plays normally. Hm...
Field Researcher
#32 Old 10th Aug 2015 at 8:42 AM
Don't add the dll into your package, the problem is clearly elsewhere, possibly in where you added the LotManager.ActiveLotChanged += new LotManager.ActiveLotChangedHandler(RoommatesFix.OnActiveLotChanged); line (doing it after the world loads should be safe) or perhaps something in your OnActiveLotChanged method itself needs to be looked into.
Field Researcher
Original Poster
#33 Old 10th Aug 2015 at 5:07 PM
Quote: Originally posted by icarus_allsorts
Don't add the dll into your package, the problem is clearly elsewhere, possibly in where you added the LotManager.ActiveLotChanged += new LotManager.ActiveLotChangedHandler(RoommatesFix.OnActiveLotChanged); line (doing it after the world loads should be safe) or perhaps something in your OnActiveLotChanged method itself needs to be looked into.


Okay, got it to load and run the game - I put the method in OnWorldLoadFinished.

Now, the problem I am having is getting it to get the new lot ID when I change lots. It seems to only get the lot ID of the load that it first loads. When I change lots, the method is running, because I have a notification set up to display a message that the lot was added or removed to the list. It shows up, but it's blank, when I switch to other lots. The first lot, it shows the address (because I used string Address = Sims3.SimIFace.World.GetLotAddress(lotId); and display that in a notification). When I change lots, it's just a blank space where the address should be. Here's the code:

Code:
public static void OnActiveLotChanged(object sender, LotManager.ActiveLotChangedArgs mNewActiveLot)
        {
            ulong lotId = Household.ActiveHousehold.LotId;
            string Address = Sims3.SimIFace.World.GetLotAddress(lotId);
            
            if (RoommatesStatus.Contains(lotId))
            {
                Household.RoommateManager.mAcceptingRoommates = true;
                StyledNotification.Format formatC = new StyledNotification.Format("Roommate Services are currently enabled on " + Address + ". This setting has been retrieved from the last time this lot was opened and reset to its previous state. ", ObjectGuid.InvalidObjectGuid, ObjectGuid.InvalidObjectGuid, StyledNotification.NotificationStyle.kGameMessagePositive);
                StyledNotification.Show(formatC);
            }
            else
            {
                Household.RoommateManager.mAcceptingRoommates = false;
                StyledNotification.Format formatD = new StyledNotification.Format("Roommate Services are currently disabled on " + Address + ". This setting has been retrieved from the last time this lot was opened and reset to its previous state. ", ObjectGuid.InvalidObjectGuid, ObjectGuid.InvalidObjectGuid, StyledNotification.NotificationStyle.kGameMessagePositive);
                StyledNotification.Show(formatD);
            }


Not sure how to get it to recognize the "new" lot ID.
Field Researcher
#34 Old 10th Aug 2015 at 6:16 PM
The new lot can be retrieved from LotManager.ActiveLotChangedArgs argument passed to your OnActiveLotChanged method, for example

public static void OnActiveLotChanged(object sender, LotManager.ActiveLotChangedArgs e)
{
//To retrieve the new active lot, use "e.mNewActiveLot". Subsequently the new LotId can be retrieved from this new lot.
}

It could be that the method runs before the active household change actually happens codewise.
Field Researcher
Original Poster
#35 Old 10th Aug 2015 at 6:29 PM
Quote: Originally posted by icarus_allsorts
The new lot can be retrieved from LotManager.ActiveLotChangedArgs argument passed to your OnActiveLotChanged method, for example

public static void OnActiveLotChanged(object sender, LotManager.ActiveLotChangedArgs e)
{
//To retrieve the new active lot, use "e.mNewActiveLot". Subsequently the new LotId can be retrieved from this new lot.
}

It could be that the method runs before the active household change actually happens codewise.


So I should replace the "e" in the public static void with "e.mNewActiveLot" ? I have tried that and it gives me errors saying that mNewActiveLot doesn't exist.

Is a list persistable? Perhaps it's clearing the list when it changes the active household? Do I maybe need to set it as persistable somehow?
Field Researcher
#36 Old 10th Aug 2015 at 7:42 PM
Sorry for not clarifying the confusion:

public static void OnActiveLotChanged(object sender, LotManager.ActiveLotChangedArgs e)
{
Lot activeLot = e.mActiveLot; // <- This is the new lot retrieved from the "e" above.
ulong activeLotId = activeLot.LotId;
...
}

Hope that helps. Your List should probably be given the PersistableStatic attribute otherwise it will be cleared out when you exit the game even if you saved it. It shouldn't clear itself out during gameplay unless your code explicitly does so.
Field Researcher
Original Poster
#37 Old 10th Aug 2015 at 8:34 PM Last edited by pjsutton : 10th Aug 2015 at 9:52 PM.
Quote: Originally posted by icarus_allsorts
Sorry for not clarifying the confusion:

public static void OnActiveLotChanged(object sender, LotManager.ActiveLotChangedArgs e)
{
Lot activeLot = e.mActiveLot; // <- This is the new lot retrieved from the "e" above.
ulong activeLotId = activeLot.LotId;
...
}

Hope that helps. Your List should probably be given the PersistableStatic attribute otherwise it will be cleared out when you exit the game even if you saved it. It shouldn't clear itself out during gameplay unless your code explicitly does so.




EDIT: Got it working! It now remembers the setting when switching to different lots! Just need to make it persistable now.

Any ideas, now, on how to get it to store the number of roommates set for each lot? I'm not sure if this would be possible or not. Is it possible to create a list of ... lists? Example: 55 Sim Way & 2 roommates. That way when it retrieves the status it could also set the previous number of roommates? Currently, the way it works is if 55 Sim way enables 6 roommates, other lots that enable roommates will have it set to the same number. EA really did not put a lot of effort in to getting this to work properly!
Field Researcher
Original Poster
#38 Old 11th Aug 2015 at 4:58 AM
Quote: Originally posted by pjsutton
EDIT: Got it working! It now remembers the setting when switching to different lots! Just need to make it persistable now.

Any ideas, now, on how to get it to store the number of roommates set for each lot? I'm not sure if this would be possible or not. Is it possible to create a list of ... lists? Example: 55 Sim Way & 2 roommates. That way when it retrieves the status it could also set the previous number of roommates? Currently, the way it works is if 55 Sim way enables 6 roommates, other lots that enable roommates will have it set to the same number. EA really did not put a lot of effort in to getting this to work properly!


A new "problem" has arisen: As Sims travel from home to various places, every lot they pass spawns 2 status messages about whether or not roommates are enabled or disabled. I tried putting something in the code about "&& Household.ActiveHouseholdLot.IsResidentialLot" thinking this would stop the messages from showing up unless they were residential lots, but it still shows up.

The same also happens if 1 member of the household is on a different lot and I switched back and forth between them - every lot the camera passes over on the way to showing me where they are spawns the status message. I guess it's a matter of what the game considers an "active lot"
Field Researcher
#39 Old 11th Aug 2015 at 6:12 AM
Quote: Originally posted by pjsutton
A new "problem" has arisen: As Sims travel from home to various places, every lot they pass spawns 2 status messages about whether or not roommates are enabled or disabled. I tried putting something in the code about "&& Household.ActiveHouseholdLot.IsResidentialLot" thinking this would stop the messages from showing up unless they were residential lots, but it still shows up.

The same also happens if 1 member of the household is on a different lot and I switched back and forth between them - every lot the camera passes over on the way to showing me where they are spawns the status message. I guess it's a matter of what the game considers an "active lot"


That was what I was beginning to suspect, that the method is being called not only when the player switches active households, but every time the focus is switched to a new lot hence why it's called OnActiveLotChanged and not OnActiveHouseholdChanged (not that changing the naming convention does anything but that was all I had to go upon).

There may be some other way to have your method run precisely only when the active household is actually changed vs every time one of your active sims goes to a new lot and you focus on them. If you can't find one, you could try making it work currently, just make sure to check if the new lot being entered/the camera is newly focusing on IS actually the active household's home lot and do nothing if it isn't i.e.

if (e.mNewActiveLot == Household.ActiveHouseholdLot)
...

you may still want to check that the actual active household has changed since the method will still run every time you follow one of your active sims back to their home lot. Maybe record the active household at the time when the game loads and check if the active household at the time of the method running matches that or not.
Field Researcher
Original Poster
#40 Old 11th Aug 2015 at 6:34 AM Last edited by pjsutton : 11th Aug 2015 at 7:06 AM.
Quote: Originally posted by icarus_allsorts
That was what I was beginning to suspect, that the method is being called not only when the player switches active households, but every time the focus is switched to a new lot hence why it's called OnActiveLotChanged and not OnActiveHouseholdChanged (not that changing the naming convention does anything but that was all I had to go upon).

There may be some other way to have your method run precisely only when the active household is actually changed vs every time one of your active sims goes to a new lot and you focus on them. If you can't find one, you could try making it work currently, just make sure to check if the new lot being entered/the camera is newly focusing on IS actually the active household's home lot and do nothing if it isn't i.e.

if (e.mNewActiveLot == Household.ActiveHouseholdLot)
...

you may still want to check that the actual active household has changed since the method will still run every time you follow one of your active sims back to their home lot. Maybe record the active household at the time when the game loads and check if the active household at the time of the method running matches that or not.


Well, since I posted that I was able to stop the posting as a Sim passes every house, but now it just reappears everytime I go back to home. I tried doing some kind of bool that would change i.e. "RoommateStatusShown" true or false at a certain time, but it just kept going in a circle:



It goes in a perpetual cycle and shows them over and over again! I think this method would work if I knew how to do it (haha, obviously...). I only want it to show once upon changing households, just as a reminder.

AND, what about the number of roommates, also? Anyway to store that in a list and have the LotID and number of roommates retrieved simultaneously? What if I had a list that was of the form (LotId, (LotId, NumberOfRoommates) ) or something? It could be retrieved using the LotId, and then I would maybe be able to get the number of roommates from that and reset that?
Field Researcher
#41 Old 11th Aug 2015 at 11:31 AM
It looks like when the active household is changed a HouseholdUpdateEvent is sent so you could try using an event listener listening for this specific type of event instead of relying on LotManager.ActiveLotChanged which as you've seen triggers too frequently for your needs.

Add the following listener when the world finishes loading:

EventTracker.AddListener(EventTypeId.kHouseholdSelected, new ProcessEventDelegate("name of ListenerAction method here"));

(btw in post #26 you had

World.OnWorldLoadFailedEventHandler += new EventHandler(OnWorldLoadFinished);

in your Instantiator which should be World.OnWorldLoadFinishedEventHandler)

And your ListenerAction should start like:

Code:
 
private static ListenerAction "method name here"(Event e)
{
         HouseholdUpdateEvent h = e as HouseholdUpdateEvent;
         if (h != null)
         {
                 Household newHousehold = h.Household; // <- This is new household that "sent" the HouseholdUpdateEvent.
                  ....
          }   
}

Hopefully that works for you. You can see when the event is sent in the PlumbBob.CheckForChangeInActiveHousehold method.

If you're looking to store more information than just a true or false boolean based on lot ids, try defining your own simple class to store that information and use a Dictionary to store  it all e.g.

Code:
public class RoommateInfo
{
       public bool mAcceptingRoommates;
       public int mNumRoommates;
       etc.

       public RoommateInfo(bool b, int i, etc)
       {
             mAcceptingRoommates = b;
             mNumRoommates = i;
             etc.
       }
}

Code:
[PersistableStatic]
public static Dictionary<ulong, RoommateInfo> sDictionary = new DIctionary<ulong, RoommateInfo>();

//adding a new lot's information to sDictionary:
Dictionary["lot id of the new lot here"] = new RoommateInfo("whether or not this lot accepts roommates", "how many roommates", etc);

//to retrieve the info of a given lot using its lot id:

RoommateInfo info;
if (sDictionary.TryGetValue("lot id of the lot", out info)) // <- if sDictionary contains the lot id you are loooking for, this condition returns true and the RoommateInfo corresponding to the lot id is retrieved from the dictionary and assigned to "info". if sDictionary does not contain the lot id being searched for the condition is false and info becomes null.
{
      bool doesLotAcceptRoommates = info.mAcceptingRoommates;
      int numOfRoommates = info.mNumRoommates;
      etc...
}

Field Researcher
Original Poster
#42 Old 11th Aug 2015 at 6:11 PM
Quote: Originally posted by icarus_allsorts
It looks like when the active household is changed a HouseholdUpdateEvent is sent so you could try using an event listener listening for this specific type of event instead of relying on LotManager.ActiveLotChanged which as you've seen triggers too frequently for your needs.

Add the following listener when the world finishes loading:

EventTracker.AddListener(EventTypeId.kHouseholdSelected, new ProcessEventDelegate("name of ListenerAction method here"));

(btw in post #26 you had

World.OnWorldLoadFailedEventHandler += new EventHandler(OnWorldLoadFinished);

in your Instantiator which should be World.OnWorldLoadFinishedEventHandler)

And your ListenerAction should start like:

Code:
 
private static ListenerAction "method name here"(Event e)
{
         HouseholdUpdateEvent h = e as HouseholdUpdateEvent;
         if (h != null)
         {
                 Household newHousehold = h.Household; // <- This is new household that "sent" the HouseholdUpdateEvent.
                  ....
          }   
}

Hopefully that works for you. You can see when the event is sent in the PlumbBob.CheckForChangeInActiveHousehold method.

If you're looking to store more information than just a true or false boolean based on lot ids, try defining your own simple class to store that information and use a Dictionary to store  it all e.g.

Code:
public class RoommateInfo
{
       public bool mAcceptingRoommates;
       public int mNumRoommates;
       etc.

       public RoommateInfo(bool b, int i, etc)
       {
             mAcceptingRoommates = b;
             mNumRoommates = i;
             etc.
       }
}

Code:
[PersistableStatic]
public static Dictionary<ulong, RoommateInfo> sDictionary = new DIctionary<ulong, RoommateInfo>();

//adding a new lot's information to sDictionary:
Dictionary["lot id of the new lot here"] = new RoommateInfo("whether or not this lot accepts roommates", "how many roommates", etc);

//to retrieve the info of a given lot using its lot id:

RoommateInfo info;
if (sDictionary.TryGetValue("lot id of the lot", out info)) // <- if sDictionary contains the lot id you are loooking for, this condition returns true and the RoommateInfo corresponding to the lot id is retrieved from the dictionary and assigned to "info". if sDictionary does not contain the lot id being searched for the condition is false and info becomes null.
{
      bool doesLotAcceptRoommates = info.mAcceptingRoommates;
      int numOfRoommates = info.mNumRoommates;
      etc...
}



Hm, I see that now, but I ended up not using the code in #26 anyway - I will blame Visual Studio for that for trying to predict what I was gonna type - it actually happens to me a lot!

I'll try the HouseholdUpdate thing. I had a different idea for the number of roommates thing that was more of a "hack" but I might try that first because I've been planning it out in my head. We'll see how it goes.
Field Researcher
Original Poster
#43 Old 12th Aug 2015 at 6:28 AM
Well, there was an error that came up when I tried HouseholdUpdate that I didn't understand and feel like dealing with, so I didn't get that to work. But it was most likely because I tried to just re-use the same code that had been in the LotManager line.

I *think* I got the game working to remember and retrieve the number of roommates per lot. I kind of "hacked" it together by using some while and foreach loops to add the LotId to the list repeatedly, and then I have another loop doing a count of how many times the Id is in the list. And that number becomes "MaxNumRoommates". It seems to accurately recall this information (and displays in a status message once a day - or when I go to Map View, move away from my house, and move back.)

But, what it doesn't seem able to do is have more than one active set of roommates at a time, on more than one lot. Example: Lot A I set to have 1 roommate. At 9AM the roommate shows up. Switch to Lot B, and set to have 3 roommates. At 9AM, 3 roommates show up. I switch back to Lot A, and my message appears telling me I have 1 roommate, however the roommate is no longer in the household and at 9AM a new one is not generated. If I go back to Lot B, the 3 will still be there.

If I go back to Lot A, and either disable/enable, or change the number of roommates, at 9AM the proper number will be generated, but they are then gone from Lot B, etc. And it goes in a cycle.

Can you think of any possible way of fixing this? Even if it were to at least be able to re-generate the correct number of roommates at 9AM upon changing lots, I would be okay with that. I tried adding Household.RoommateManager.StartAcceptingRoommates(Household.ActiveHousehold); to my OnActiveLotChanged method, but it doesn't seem to do anything. (this is the same function that is called in the CallChangeRoommateCount, which is what spurs the roommate generation at 9AM). However, in that function, it is Household.RoommateManager.StartAcceptingRoommates(this.Actor.Household); instead, but I got an error when it was placed in the different location.

I'm guessing this is a limitation of the Roommate Manager? Wonder if that could be changed somehow?
Field Researcher
#44 Old 12th Aug 2015 at 12:25 PM
Well, it's rather apparent that the coders had no intention of letting the roommate manager run across multiple households at a time, which is why there is only one static instance of the RoommateManager class per game session that specifically refers and handles the current active household only (i.e. the roommates created for and recorded by it will only be sent to the active household lot according to all its methods).

If you're really up to it, study the RoommateManager class and perhaps try creating your custom version of it that perhaps refers to a variable household, essentially creating a manager for households other than the active one. You'd then perhaps need a system to make sure every household the player enables roommates with gets one of these managers and runs it in the background even once households are switched. How feasible any of this is you'll have to try and see, but honestly speaking... I'll just stop there since it's probably not my place to discourage or encourage you here. Perhaps you'll find a much more doable way to get what you want. Whatever the case, best of luck
Field Researcher
Original Poster
#45 Old 12th Aug 2015 at 6:15 PM
Quote: Originally posted by icarus_allsorts
Well, it's rather apparent that the coders had no intention of letting the roommate manager run across multiple households at a time, which is why there is only one static instance of the RoommateManager class per game session that specifically refers and handles the current active household only (i.e. the roommates created for and recorded by it will only be sent to the active household lot according to all its methods).

If you're really up to it, study the RoommateManager class and perhaps try creating your custom version of it that perhaps refers to a variable household, essentially creating a manager for households other than the active one. You'd then perhaps need a system to make sure every household the player enables roommates with gets one of these managers and runs it in the background even once households are switched. How feasible any of this is you'll have to try and see, but honestly speaking... I'll just stop there since it's probably not my place to discourage or encourage you here. Perhaps you'll find a much more doable way to get what you want. Whatever the case, best of luck


Haha, I get what you're saying ... I'm surprised I got this far (with lots of help!). I was a math major and had to take 1 programming class in college and I'm not even sure how I got through it ... so I feel I've come a long way and learned a lot in writing this! I at least got Story Progression to stop adding the roommates to the household, and also to make the lot rentable.

I just tried something and had some bizarre results... but I actually have 2 different households with Roommates right now. I don't know how it happened, or if it would happen again! I need to try to duplicate it...or maybe it was just a fluke.
Field Researcher
Original Poster
#46 Old 13th Aug 2015 at 8:00 AM
Update: so I read up on dictionaries, and I decided that it SEEMED fairly straightforward to use a dictionary to keep the same sets of roommates. I figured that I could add the roommates to a <ulong SimDescription> dictionary where the ulong is the lot ID.

I found a place in the RoommateValidation code where it looked like the roommates were being created, and they just so happened to add the newly created roommates to a list. Great! I'll just add that to my list on the next line. Then, I had something written with a foreach loop in OnActiveLotChanged involving ContainsKey which I was pretty sure would work. I coded a status message to check, but never saw it. So I backtracked.

I ended up putting many status messages in the section where I thought the roommates were created. None of them ever showed up. Grrrrr!!

Searched ILSpy and found the AddRoommate Story Progression, so I have to imagine that's what's doing it. It was that same SP that forcibly adds the roommates to lots (and made them controllable) before I stopped that, and there is something in the mod that changes something to 0 to stop that.

So, I guess I need to find a clever spot to do what I want now. Is there some way to check every member of a household to see if they are NPC's? And then add those to a list? Once I have the roommates in the dictionary with the lot ID, I think I can just retrieve the Sim and add them using Household.Roommate Manager.AddRoommate.

I'm learning a lot, so that's a good thing! But staying up entirely too late in the process....
Field Researcher
Original Poster
#47 Old 13th Aug 2015 at 10:57 PM
For some reason, the roommates don't seem to be added to Household.ActiveHousehold.SimDescriptions ?? I believe they are added to Household.RoommateManager.mRoommates, but as a ulong.

Is them some way to "convert" a ulong Sim into a SimDescription?
Instructor
#48 Old 14th Aug 2015 at 4:05 AM
Is it possible to append
Code:
(SimDescription)
before the ulong you want to work with?
Field Researcher
Original Poster
#49 Old 14th Aug 2015 at 4:43 AM
Quote: Originally posted by SimsMatthew
Is it possible to append
Code:
(SimDescription)
before the ulong you want to work with?


I tried that and I don't think it worked, but I found a way around it.

Now, I'm at this point: I was able to get the LotId and the Sim (not a SimDescription) stored in a dictionary <ulong, Sim>. I found the command Household.ActiveHousehold.AddSim(Sim sim).

I actually was able to switch households, and when I came back, it remember the roommate and added her to the household! Except, it made her selectable. Which I assume makes sense because that's what that method does.

So ... I feel somewhat successful! If I could figure out how to change "Sim" into "SimDescription" I think I'll be all set...
Field Researcher
Original Poster
#50 Old 14th Aug 2015 at 6:34 AM Last edited by pjsutton : 14th Aug 2015 at 7:01 AM.
Okay, so I'm able to get them successfully added to the household as roommates when I switch active households. The sim shows up in the Relationship panel, and says that they are roommates ... but the Sim is not on the lot. When I click on them it says "Texting..." and then the options for Texting come up. I've written my own custom AddSim method:

Code:
public static void AddSim(Sim sim)
        {
            if (sim.Household == Household.ActiveHousehold)
            {
                return;
            }
            if (sim.Household != null)
            {
                sim.Household.RemoveSim(sim);
            }
            sim.SimDescription.IsNeverSelectable = true;
            Household.RoommateManager.mRoommates.Add(sim.SimDescription.SimDescriptionId);
            Household.ActiveHousehold.Add(sim.SimDescription);
            Household.RoommateManager.AddRoommateInteractions(sim);
            if (sim.SimDescription.Household != null)
            {
                foreach (SimDescription current in sim.Household.SimDescriptions)
                {
                    if (current != sim.SimDescription)
                    {
                        Relationship relationship = current.GetRelationship(sim.SimDescription, true);
                        relationship.Roommates = true;
                    }
                }
            }
            if (sim.IsSelectable)
            {
                sim.OnBecameSelectable();
            }
        }      


I sort of combined the "Household.AddSim" and "Household.RoommateManager.AddRoommate methods.

Am I missing something that I don't realize is being called, like making the Sim physically go to the lot?

EDIT: ErrorTrap reported that Sim "missing" and then she reappeared... but something odd is still happening! But I'm slightly more intrigued that this is somewhat working!
Page 2 of 3
Back to top