Replies: 10 (Who?), Viewed: 816 times.
Field Researcher
Original Poster
#1 Old 15th May 2021 at 5:32 PM Last edited by lizcandor : 15th May 2021 at 5:58 PM.
Default Relationship symmetry
I'm trying to figure out how to make sims' relationships with each other asymmetrical/understand what causes them to be symmetrical at all, if anyone knows something about this I would love to hear it! What I know so far is this:

Relationship objects are stored in the dictionary sAllRelationships (<SimDescription,Dictionary<SimDescription,Relationship>>). Every sim (simA) who has a relationship with anyone has an entry in sAllRelationships, and every simA's sAllRelationships dictionary entry is *another* dictionary with an entry for every sim (simB) that simA has a relationship with. The simB entry of simA's entry of sAllRelationships contains a Relationship object with simA's SimDescription as SimDescriptionA and simB's SimDescription as SimDescriptionB, and that Relationship object is what you get back when you use Relationship.Get(simA,simB,bool) to get the relationship between a pair of sims.

The problem is, it seems that once simA and simB have a relationship, Relationship.Get(simB,simA,bool) and Relationship.Get(simA,simB,bool) both return a Relationship with simA's SimDescription as A and simB's as B, and I can't figure out how those two Relationship objects are getting linked to each other.

[Edit: ...wait a second, I think writing up what the problem is just gave me an idea again, this keeps happening]

[Edit 2: yeah, I think the issue might be this section of the Relationship constructor:]
Code:
if (simDescriptionA.CreatedSim != null)
	{
		simDescriptionA.CreatedSim.SocialComponent.AddRelationship(this);
	}
	if (simDescriptionB.CreatedSim != null)
	{
		simDescriptionB.CreatedSim.SocialComponent.AddRelationship(this);
	}

Which...can this be changed without a core mod? It can't, right? I think I'd just need to remove the second if statement so the game will create a new Relationship object for simB instead of using simA's for both, but changing the constructor of a class seems like it would need a core mod. I'd be willing to learn but I don't know if that would even be worth it, there's so much I don't know about core mods.
Advertisement
Lab Assistant
#2 Old 15th May 2021 at 6:00 PM
I sadly have not wisdom to offer, since I have no idea and no time to look into the code. Just wanted to say how happy I am somebody is as unnerved by the symmetry as me I hope you find a way, if not I will probably also study that code once life is less stressfull but that will probably be autumn for me. Good luck!!! Thank you for looking into this.
Virtual gardener
staff: administrator
#3 Old 15th May 2021 at 7:03 PM
Quote:
Originally Posted by lizcandor
I'm trying to figure out how to make sims' relationships with each other asymmetrical/understand what causes them to be symmetrical at all, if anyone knows something about this I would love to hear it! What I know so far is this:

Relationship objects are stored in the dictionary sAllRelationships (<SimDescription,Dictionary<SimDescription,Relationship>>). Every sim (simA) who has a relationship with anyone has an entry in sAllRelationships, and every simA's sAllRelationships dictionary entry is *another* dictionary with an entry for every sim (simB) that simA has a relationship with. The simB entry of simA's entry of sAllRelationships contains a Relationship object with simA's SimDescription as SimDescriptionA and simB's SimDescription as SimDescriptionB, and that Relationship object is what you get back when you use Relationship.Get(simA,simB,bool) to get the relationship between a pair of sims.

The problem is, it seems that once simA and simB have a relationship, Relationship.Get(simA,simB,bool) and Relationship.Get(simA,simB,bool) both return a Relationship with simA's SimDescription as A and simB's as B, and I can't figure out how those two Relationship objects are getting linked to each other.

[Edit: ...wait a second, I think writing up what the problem is just gave me an idea again, this keeps happening]

[Edit 2: yeah, I think the issue might be this section of the Relationship constructor:]
Code:
if (simDescriptionA.CreatedSim != null)
   {
      simDescriptionA.CreatedSim.SocialComponent.AddRelationship(this);
   }
   if (simDescriptionB.CreatedSim != null)
   {
      simDescriptionB.CreatedSim.SocialComponent.AddRelationship(this);
   }

Which...can this be changed without a core mod? It can't, right? I think I'd just need to remove the second if statement so the game will create a new Relationship object for simB instead of using simA's for both, but changing the constructor of a class seems like it would need a core mod. I'd be willing to learn but I don't know if that would even be worth it, there's so much I don't know about core mods.
Funnily enough, they're actually not symmetric, it's just programmed to always get the same relationship score after each social interaction In the end, All relationships get updated by "UpdateLiking(float chance)", where a lot of multipliers are also being added over the regular number you parsed in

You're correct in thinking that sAllRelationships has basically ALL the relationships you can think of.  If you check the 'GetInternal()' function inside Sims3.Gameplay.Socializing.Relationship then you can see from the dictionary, it's getting all the relationships from Sim 'x'. Sim Y then gets extracted from the sim X dictionary. But, of course, this works as well visa-versa!

So in your case, I'd actually check out the GetInternal function and for testing and debugging purposes create a custom social interaction and start with:

Code:
public static void GetAndSetRelationshipPoint(SimDescription x, SimDescription y, float chance)
{
    Dictionary<SimDescription, Relationship> dictionary;
    Relationship relationshipSimY;
   Relationship relationshipSimx;
    if (Relationship.sAllRelationships.TryGetValue(x, out dictionary))
    {
        if (dictionary.TryGetValue(y, out relationshipSimY))
        {
         relationshipSimY.LTR.mLiking = 10f;
        }
      // Theoretically this if statement should work too!
      if (dictionary.TryGetValue(x, out relationshipSimx))
        {
         relationshipSimY.LTR.mLiking = -10f;
        }
    }
}
As you can probably tell, we're hardcoding in the amount of value the mLiking is going to be like for sim x and sim y. In UpdateLiking() you might see that mLiking is also used the same way  So, just a fair warning, I just wrote this without any compiler or testing :p so if it breaks things then that's on me! But in theory this should do

In case you're curious about custom social interactions, here's my to go thread: https://modthesims.info/t/492221
Alternatively you can check out Arsil's Fist bump social interaction that has a LOT of documentation in his XML: https://modthesims.info/d/580634/fist-bump.html
I also did some social interactions for the sewing table, but I can understand that that's a bit tougher to read with all the other features it comes with
Field Researcher
Original Poster
#4 Old 15th May 2021 at 10:25 PM Last edited by lizcandor : 16th May 2021 at 2:54 AM.
Quote:
Originally Posted by Lyralei
Funnily enough, they're actually not symmetric, it's just programmed to always get the same relationship score after each social interaction In the end, All relationships get updated by "UpdateLiking(float chance)", where a lot of multipliers are also being added over the regular number you parsed in

You're correct in thinking that sAllRelationships has basically ALL the relationships you can think of.  If you check the 'GetInternal()' function inside Sims3.Gameplay.Socializing.Relationship then you can see from the dictionary, it's getting all the relationships from Sim 'x'. Sim Y then gets extracted from the sim X dictionary. But, of course, this works as well visa-versa!

So in your case, I'd actually check out the GetInternal function and for testing and debugging purposes create a custom social interaction and start with:

Code:
public static void GetAndSetRelationshipPoint(SimDescription x, SimDescription y, float chance)
{
    Dictionary<SimDescription, Relationship> dictionary;
    Relationship relationshipSimY;
   Relationship relationshipSimx;
    if (Relationship.sAllRelationships.TryGetValue(x, out dictionary))
    {
        if (dictionary.TryGetValue(y, out relationshipSimY))
        {
         relationshipSimY.LTR.mLiking = 10f;
        }
      // Theoretically this if statement should work too!
      if (dictionary.TryGetValue(x, out relationshipSimx))
        {
         relationshipSimY.LTR.mLiking = -10f;
        }
    }
}
As you can probably tell, we're hardcoding in the amount of value the mLiking is going to be like for sim x and sim y. In UpdateLiking() you might see that mLiking is also used the same way  So, just a fair warning, I just wrote this without any compiler or testing :p so if it breaks things then that's on me! But in theory this should do

In case you're curious about custom social interactions, here's my to go thread: https://modthesims.info/t/492221
Alternatively you can check out Arsil's Fist bump social interaction that has a LOT of documentation in his XML: https://modthesims.info/d/580634/fist-bump.html
I also did some social interactions for the sewing table, but I can understand that that's a bit tougher to read with all the other features it comes with


Hm, you’re right about the relationship points updates - even if I could unlink the relationships I’d also need to change how they get updated for that to mean anything.

I did a test with the same concept as you’re thinking with the attraction scores; both entries of the dictionary return the same object, though, so no luck there.

Oh, but maybe instead of changing the Relationship class I could edit entries of the sAllRelationships dictionary on world load and when new relationships start, to make sure it actually stores different Relationships for each sim! I think that might work, I’ll try it and update on how that goes when I’m back at a real computer :D

Edit: It worked! I now have asymmetrical attraction for real, instead of just the sort of hack-y way I did it before (one sim gets the Attractive Company buff but the other doesn't, and presumably the sim with the crush will be encouraged to try romantic socials while the other won't). And changing the relationship points with cheats only affects the active sim, instead of both!
Virtual gardener
staff: administrator
#5 Old 17th May 2021 at 10:16 AM
Quote:
Originally Posted by lizcandor
Hm, you’re right about the relationship points updates - even if I could unlink the relationships I’d also need to change how they get updated for that to mean anything.

I did a test with the same concept as you’re thinking with the attraction scores; both entries of the dictionary return the same object, though, so no luck there.

Oh, but maybe instead of changing the Relationship class I could edit entries of the sAllRelationships dictionary on world load and when new relationships start, to make sure it actually stores different Relationships for each sim! I think that might work, I’ll try it and update on how that goes when I’m back at a real computer :D

Edit: It worked! I now have asymmetrical attraction for real, instead of just the sort of hack-y way I did it before (one sim gets the Attractive Company buff but the other doesn't, and presumably the sim with the crush will be encouraged to try romantic socials while the other won't). And changing the relationship points with cheats only affects the active sim, instead of both!
Awesome! I personally wasn't too sure if editing it the way I figured it might worked would work because you'd also need to do it the other way (So after you set the points for sim relationship X, you need to do it for Y as well being 'x' if that makes sense ;p)

But awesome to hear it's working! Hopefully doing it on worldload won't make things harder to create a mod from it though! 
Field Researcher
Original Poster
#6 Old 29th May 2021 at 6:46 PM
Rewriting the dictionary on world load has been pretty easy! The way to do it, if anyone else wants to try it too, is to just cycle through every entry of sAllRelationships while creating new, unique Relationship objects and inserting them in the place of the original ones (originally the dictionary just stores 2 references to the same object, so that relationshipSimY==relationshipSimX, so you have to actually create a new object instead of editing the one that's already there).

I've also made it so the two unique Relationship objects share the same ShortTermContext - when I make a pair of complementary Relationships, I set the mSTC field of one to reference the other's mSTC, while everything else is still unique - since in my initial tests having two independent STCs made for weird gameplay. But you don't have to do that.

Should be able to make these same edits with an event listener that'll catch the creation of new Relationships after world load, too - I'm trying kMetSim as the event for now, haven't tested very thoroughly yet though so I don't know if it's working.
Field Researcher
Original Poster
#7 Old 13th Jun 2021 at 9:22 PM Last edited by lizcandor : 14th Jun 2021 at 4:16 AM.
I've got unlinking relationships, relinking relationships (to put the game back to normal before the mod is removed), and restoring symmetry to the LTR types that I think it makes sense to leave symmetrical (romantic interest, best friends forever, spouse, ex, engaged, and going steady) working! And have learned stuff about the UIRelationship class, which I'd never explored before, so that was fun.

New question: does anyone know whether/how I could edit or replace methods of the Conversation class, like UpdateSimAfterInteraction and FindMostSuitableRule? I think doing that would let me change which of the two relationships decides/is affected by the outcome of an interaction - right now, the one belonging to the actor is the only one that those methods seem to do anything with. I tried replacing SocialInteractionA a while ago by making an edited class with the same name and namespace, but that didn't seem to do anything, so I'm not sure if I should try it again here.

[Edit: I core modded it (UpdateSimAfterInteraction, FindMostSuitableRule, GetAllInteractionsForPieMenu, and GetAllInteractionsForAutonomy) and that seems to be working! BailaBaila99's tutorial was super helpful and easy to follow, I don't know why it took me this long to be determined enough to actually try it]
Field Researcher
Original Poster
#8 Old 20th Jun 2021 at 3:53 PM
Two quick questions for anybody interested in this before I put it in the queue: 1) Any preferences on which LTR types should be left symmetrical, or is the list in my last update (minus Romantic Interest, I changed my mine about that one) fine? and 2) Does anyone have time to test this a little, soon-ish? If not I'll just trust that my own testing was sufficient. (I feel bad for taking so long to wrap up the last testing thread I opened, and don't want to clutter up the feedback forum )
Field Researcher
#9 Old 20th Jun 2021 at 4:28 PM
Hey there lizcandor, excited to hear this mod about to be released!
Answers:
1) I think the LTR types that you listed are great!
2) I'd love to test this, I can do it this week, hit me up.
Field Researcher
Original Poster
#10 Old 20th Jun 2021 at 4:31 PM
Cool, I'll open a thread and @ you. Thanks!
Test Subject
#11 Old 23rd Jun 2021 at 9:03 AM
LTR types that you listed really great!
Back to top