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
Lab Assistant
Original Poster
#1 Old 24th Jan 2021 at 3:45 PM
Default What is the code that makes Imaginary Friends invisible?
So, as some of you might know, I'm working on a ghost overhaul. I've been wanting to make ghosts be visible only to certain sims, like ghost hunters and all that. To achieve this objective, I plan on trying to use the Imaginary Friend code. I'm searching for what makes them invisible in Ilspy, but I can't find the exact piece of code that produces this effect. Could someone help me?
Advertisement
Space Pony
#2 Old 24th Jan 2021 at 5:35 PM
Quote: Originally posted by CyrusBanefort
So, as some of you might know, I'm working on a ghost overhaul. I've been wanting to make ghosts be visible only to certain sims, like ghost hunters and all that. To achieve this objective, I plan on trying to use the Imaginary Friend code. I'm searching for what makes them invisible in Ilspy, but I can't find the exact piece of code that produces this effect. Could someone help me?


I think what you're looking for is Sims3.Gameplay.ActorSystems.OccultImaginaryFriend.RefreshVisibility(), which is called any time the selected Sim changes through an event listener on kEventSimSelected.

Code:
public bool RefreshVisibility(bool immediate)
{
    if (this.mSimDescription == null)
    {
        return false;
    }
    Sim createdSim = this.mSimDescription.CreatedSim;
    if (createdSim == null)
    {
        return false;
    }
    bool flag = false;
    if (this.IsReal)
    {
        flag = true;
    }
    else
    {
        Sim selectedActor = PlumbBob.SelectedActor;
        SimDescription simDescription = (selectedActor == null) ? null : selectedActor.SimDescription;
        if (simDescription != null && (simDescription.SimDescriptionId == this.mOwnerSimDescId || selectedActor == createdSim))
        {
            flag = true;
        }
        else
        {
            SimDescription simDescription2 = SimDescription.Find(this.mOwnerSimDescId);
            Sim sim = (simDescription2 == null) ? null : simDescription2.CreatedSim;
            if (sim != null && sim.IsDying())
            {
                flag = true;
            }
        }
    }
    float fadeTime = immediate ? 0f : GameObject.kGlobalObjectFadeTime;
    if (flag)
    {
        createdSim.FadeIn(false, fadeTime);
    }
    else
    {
        createdSim.FadeOut(false, false, fadeTime);
    }
    Audio.MuteAllSounds(createdSim.ObjectId, !flag);
    return flag;
}


Basically, if the selected Sim is either the owner of the imaginary friend or the imaginary friend itself (or if the owner is dying, for some reason), then Sim.FadeIn() is called on the imaginary friend to show it if it's already hidden. Otherwise, Sim.FadeOut() is called to hide it if it's not already hidden. The sounds that the imaginary friend is making are also muted or unmuted accordingly.

You could probably copy most of this function and just replace "simDescription.SimDescriptionId == this.mOwnerSimDescId" with whatever condition you want on the selected actor. You might also consider removing the death check.

"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
Lab Assistant
Original Poster
#3 Old 24th Jan 2021 at 6:08 PM
@gamefreak130 , how could I set multiple independent conditions to the visibility of the ghosts? I have three methods to see ghosts in mind: Having a certain custom moodlet, being in the Ghost Hunter career and reaching level 5 in the spellcasting skill.
Space Pony
#4 Old 24th Jan 2021 at 8:22 PM
Quote: Originally posted by CyrusBanefort
@gamefreak130 , how could I set multiple independent conditions to the visibility of the ghosts? I have three methods to see ghosts in mind: Having a certain custom moodlet, being in the Ghost Hunter career and reaching level 5 in the spellcasting skill.


Just keep chaining the conditions using the or (||) operator like so:

Code:
if (simDescription != null && (simDescription.Occupation is GhostHunter || simDescription.SkillManager?.GetElement(SkillNames.Spellcraft)?.SkillLevel >= 5 
                                || simDescription.CreatedSim.BuffManager?.HasElement(yourBuffGuid) || selectedActor == createdSim))


If the simDescription exists (is not null), and any one of the conditions in the inner parentheses is true, then the if statement will proceed, setting "flag" to true and fading in the ghost.

"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
Lab Assistant
Original Poster
#5 Old 24th Jan 2021 at 9:23 PM
@gamefreak130 , thanks for the help. Just one more thing... How could I make this affect ghosts, in specific? It would be every ghost in the game, naturally.
Lab Assistant
Original Poster
#6 Old 25th Jan 2021 at 5:10 PM
Default Where do I need to put this?
Basically, this is the code to turn every ghost on the world invisible, except for themselves and to sims with certain conditions. It's almost done, I just need to create the moodlet that is one of the conditions -- But I don't know where exactly I need to put it. Is it inside a class?

Code:
public bool RefreshVisibility(bool immediate)
{
	if (mSimDescription == null)
	{
		return false;
	}
	Sim ghostSim = mSimDescription.IsGhost;
	if (ghostSim == null)
	{
		return false;
	}
	bool flag = false;
	if (IsReal)
	{
		flag = true;
	}
	else
	{
		Sim selectedActor = PlumbBob.SelectedActor;
		SimDescription simDescription = (selectedActor == null) ? null : selectedActor.SimDescription;
		if (simDescription != null && (simDescription.Occupation is GhostHunter || simDescription.SkillManager?.GetElement(SkillNames.Spellcraft)?.SkillLevel >= 5 || simDescription.CreatedSim.BuffManager?.HasElement(yourBuffGuid) || selectedActor == ghostSim))
		{
			flag = true;
		}
	}
	float fadeTime = immediate ? 0f : GameObject.kGlobalObjectFadeTime;
	if (flag)
	{
		createdSim.FadeIn(false, fadeTime);
	}
	else
	{
		createdSim.FadeOut(false, false, fadeTime);
	}
	Audio.MuteAllSounds(createdSim.ObjectId, !flag);
	return flag;
}
Lab Assistant
Original Poster
#7 Old 27th Jan 2021 at 3:52 PM
Default How to make this work?
Basically, I'm almost done in the process of making ghost sims invisible... And now I'm getting error CS0029 when trying to compile this exact line:

Code:
Sim createdSim = mSimDescription.IsGhost;


What should I do? Context:

Code:
public class Visibility
	{
		public bool RefreshVisibility(bool immediate)
{
	if (mSimDescription == null)
	{
		return false;
	}
	Sim createdSim = mSimDescription.IsGhost;
	if (createdSim == null)
	{
		return false;
	}
	bool flag = false;
	if (IsReal)
	{
		flag = true;
	}
	else
	{
		Sim selectedActor = PlumbBob.SelectedActor;
		SimDescription simDescription = (selectedActor == null) ? null : selectedActor.SimDescription;
		if (simDescription != null && (simDescription.Occupation is GhostHunter || (simDescription.SkillManager.HasElement(SkillNames.Spellcraft) && simDescription.SkillManager.GetElement(SkillNames.Spellcraft).SkillLevel >= 5) || simDescription.CreatedSim.BuffManager.HasElement(0x15DABBECF72A9084) || selectedActor == createdSim))
		{
			flag = true;
		}
	}
	float fadeTime = immediate ? 0f : GameObject.kGlobalObjectFadeTime;
	if (flag)
	{
		createdSim.FadeIn(false, fadeTime);
	}
	else
	{
		createdSim.FadeOut(false, false, fadeTime);
	}
	Audio.MuteAllSounds(createdSim.ObjectId, !flag);
	return flag;
}
		public SimDescription mSimDescription;
		
		public bool IsReal
{
	get
	{
		return mIsReal;
	}
	set
	{
		mIsReal = value;
	}
}
		public bool mIsReal;
	}
Virtual gardener
staff: administrator
#8 Old 28th Jan 2021 at 2:36 PM
It's actually quite an easy one to fix

So, just for other people to understand what the CS0029 error is, it's an error when you're trying to assign a value to a variable but both have a different type.

For instance, this will give you an CS0029 error:

Code:
string iAmAString = "Hello!";
int iAmInt = iAmAString
Of course, the reason why this won't work is that we're trying to assign a string to an int! Which obviously won't work

The same thing is the case when assigning a SimDescription type to a Sim. Because the Sim is the "Whole" sim and the SimDescription is... well, how you'd "Describe" the sim as their being (Career, traits, skills, lovers, etc). At least that's how I remember them. So Assigning Sim to a Simdescription won't work like you did here:

Code:
Sim createdSim = mSimDescription.IsGhost;
Now, there are 2 choices you can make here. Either do:

SimDescription createdSim = mSimDescription.IsGhost;

OR do this:

Code:
Sim createdSim = null;

//Later on in your code when you need CreatedSim you do:
createdSim = base.Actor;
if(createdSim.SimDescription.IsGhost)
{
   blah blah blah
}
I will say, I'm a bit confused as to how CreatedSim knows whether it's a ghost, since there isn't anything like looping through all sims in the town and seeing if they're a ghost and saving them in a List or something. Or whether this is a social interaction, but i do hope this helps!
Lab Assistant
Original Poster
#9 Old 28th Jan 2021 at 7:29 PM
Default Calling upon a custom RefreshVisibility Code Snippet to make sims invisible
Thanks to my frequent posts in this forum, I think it's almost common knowledge what I'm trying to do - In a nutshell, making ghosts invisible except for a few circunstances. The code is done, I think - I only need to know now how to apply it.

Code:
public bool RefreshVisibility(bool immediate)
{
	if (targetDescription == null)
	{
		return false;
	}
	Sim createdSim = targetDescription.CreatedSim;
	if (createdSim == null)
	{
		return false;
	}
	bool flag = false;
	if (!targetDescription.IsGhost)
	{
		flag = false;
	}
	else
	{
		Sim selectedActor = PlumbBob.SelectedActor;
		SimDescription simDescription = (selectedActor == null) ? null : selectedActor.SimDescription;
		if (simDescription != null && (simDescription.Occupation is GhostHunter || (simDescription.SkillManager.HasElement(SkillNames.Spellcraft) && simDescription.SkillManager.GetElement(SkillNames.Spellcraft).SkillLevel >= 5) || simDescription.CreatedSim.BuffManager.HasElement(0x15DABBECF72A9084) || selectedActor == createdSim))
		{
			flag = true;
		}
	}
	float fadeTime = immediate ? 0f : GameObject.kGlobalObjectFadeTime;
	if (flag)
	{
		createdSim.FadeIn(false, fadeTime);
	}
	else
	{
		createdSim.FadeOut(false, false, fadeTime);
	}
	Audio.MuteAllSounds(createdSim.ObjectId, !flag);
	return flag;
}

		public SimDescription mSimDescription;
		
		public SimDescription targetDescription;
	}


Is there anything here that would be prejudicial to my goal? Or is everything okay, and how could I call upon it to create the desired effect?
Virtual gardener
staff: administrator
#10 Old 28th Jan 2021 at 8:03 PM
I think you basically would want to do the following:

Code:
public static void OnWorldLoadFinishedHandler(object sender, System.EventArgs e)
        {
            foreach (Sim sim in Sims3.Gameplay.Queries.GetObjects<Sim>())
           {
              if (sim != null && sim.SimDescription.IsGhost)
               {
                   RefreshVisibility(true);
               }
            }
       }


For more info on global mods I'd check this out: http://www.simlogical.com/ContentUp..._script_mod.pdf
Lab Assistant
Original Poster
#11 Old 28th Jan 2021 at 8:34 PM
@Lyralei , I'm getting error CS0120 when trying to use the RefreshVisibility boolean. What should I do?
Virtual gardener
staff: administrator
#12 Old 28th Jan 2021 at 9:34 PM
Quote: Originally posted by CyrusBanefort
@Lyralei , I'm getting error CS0120 when trying to use the RefreshVisibility boolean. What should I do?
The first thing you can do (but I would not recommend for any game objects or sims interactions) change the function to a static function

Code:
public static bool RefreshVisibility(bool immediate)

If it were to be an interaction, I'd suggest doing ' base.target.FUNCTIONNAME' or 'base.actor.FUNCTIONNAME'
Lab Assistant
Original Poster
#13 Old 28th Jan 2021 at 10:57 PM
@Lyralei , the problem is... That it isn't exactly an interaction. It would work every time the selected sim changes - And I don't know exactly how to call upon such a thing. I tried this method that you suggested, but it gave me no results.
Virtual gardener
staff: administrator
#14 Old 29th Jan 2021 at 10:33 AM Last edited by Lyralei : 29th Jan 2021 at 10:53 AM.
Quote: Originally posted by CyrusBanefort
@Lyralei , the problem is... That it isn't exactly an interaction. It would work every time the selected sim changes - And I don't know exactly how to call upon such a thing. I tried this method that you suggested, but it gave me no results.
Yeah I was already thinking how this was going to work with sims, but from the looks of it, you used the ImaginaryOccult code right?

So, if I were you, I'd modify the invisible code thing a bit more to parse in a sim as well in your parameters. That way, you don't necessarily need the whole 'createdSim' stuff you're defining (which was useful in the case of an Occult, since you'd already have that kind of data).

Here's what I'd change:

Code:
public bool RefreshVisibility(bool immediate, Sim sim)
{
   if (sim == null)
   {
      return false;
   }
   bool flag = false;
  if (!sim.SimDescription.IsGhost)
   {
      flag = false;
   }
   else
   {
            // THis should probably need some testing, but I can see that this could work.

      Sim selectedActor = PlumbBob.SelectedActor;
      SimDescription simDescription = (selectedActor == null) ? null : selectedActor.SimDescription;
      if (simDescription != null && (simDescription.Occupation is GhostHunter || (simDescription.SkillManager.HasElement(SkillNames.Spellcraft) && simDescription.SkillManager.GetElement(SkillNames.Spellcraft).SkillLevel >= 5) || simDescription.CreatedSim.BuffManager.HasElement(0x15DABBECF72A9084) || selectedActor == createdSim))
      {
         flag = true;
      }
   }
   float fadeTime = immediate ? 0f : GameObject.kGlobalObjectFadeTime;
   if (flag)
   {
      sim.FadeIn(false, fadeTime);
   }
   else
   {
       sim.FadeOut(false, false, fadeTime);
   }
   Audio.MuteAllSounds( sim.ObjectId, !flag);
   return flag;
}
}


And then basically you do this:

Code:
public static void OnWorldLoadFinishedHandler(object sender, System.EventArgs e)
        {
            foreach (Sim sim in Sims3.Gameplay.Queries.GetObjects<Sim>())
           {
            // Either this:

              if (sim != null && sim.SimDescription.IsGhost)
            // Or this:

            if (sim != null)

               {
                   RefreshVisibility(true, sim);
               }
            }
       }


And voila! I did make an error yesterday thinking that true means it's invisible, but it's actually the opposite. So if we put in false then the sim will turn invisible. Keep that in mind though! 

Now I can see instances where a sim would need to see them, which means we need to set it back to 'true'. I'd say for those instances try looking into Broadcaster stuff

EDIT: I went a bit back to some older threads you made to get a better understanding of how this needs to work, but I did come across this interesting thread: https://modthesims.info/showthread....172#post5706172

Where this code is, in the case of the OccultImaginaryfriend code is always being executed for when a sim is selected (And has an Imaginary friend, hence the 'owner' variable). Instead, I'd turn the thought around. Figure out who happen to be ghosts and give them a broadcaster, so when people are around them, you execute the RefreshVisibility code (Where we also do checks of course if the sim in the broadcast area can even see them). And there you go!

The broadcast would then be the thing you'd want to add to the onWorldFinished code, rather than the RefreshVisbility. ANd then just execute the RefreshVisibilty code inside the broadcaster

Make sure you check this thread for that where we've discussed it before: https://modthesims.info/showthread.php?t=651733
Lab Assistant
Original Poster
#15 Old 30th Jan 2021 at 1:23 PM
Default Adding Solo Interactions
I'm trying to make my custom haunt interaction appear to all ghost sims. However, the problem is that it is a solo interaction, and thus, it cannot be loaded the same way as others, apparently, I think it's because of this line of code:

Code:
new public static ISoloInteractionDefinition Singleton = new Definition();


Thus, when I try doing this on the instantiator class:

Code:
sim.AddInteraction(CyrusHaunt.Singleton, true);


I get error CS1503. How could I fix this?
Virtual gardener
staff: administrator
#16 Old 30th Jan 2021 at 4:55 PM
Quote: Originally posted by CyrusBanefort
I'm trying to make my custom haunt interaction appear to all ghost sims. However, the problem is that it is a solo interaction, and thus, it cannot be loaded the same way as others, apparently, I think it's because of this line of code:

Code:
new public static ISoloInteractionDefinition Singleton = new Definition();


Thus, when I try doing this on the instantiator class:

Code:
sim.AddInteraction(CyrusHaunt.Singleton, true);


I get error CS1503. How could I fix this?
There's actually a function that does that for you within the SIm class. So you'd want to do this instead:

sim.AddSoloInteractions(CyrusHaunt.Singleton);

Which I think will fix the Error as well. Else I assume it's because of the type the Definition is derived from. Make sure it's this:

public class Definition : SoloSimInteractionDefinition<CyrusHaunt>
Lab Assistant
Original Poster
#17 Old 30th Jan 2021 at 6:43 PM
Default Why my instantiator class makes the ground interactions disappear?
Basically, I'm trying to make the game load my custom buffs, but when I try do that (And only when there's buffs involved -- If I try to use the instantiator class only to load my custom interactions, everything goes fine) the ground interactions (go here, for example) simply do not show up, no matter how many times I click in the ground. What's happening? And how could I fix this?

Here's the class:

Code:
public class Test
		{
			[Tunable]
	   		internal static bool kInstantiator;

      static Test()
			{
				World.sOnWorldLoadFinishedEventHandler = (EventHandler)Delegate.Combine(World.sOnWorldLoadFinishedEventHandler, new EventHandler(OnWorldFinishedLoading));
				LoadSaveManager.ObjectGroupsPreLoad += OnPreLoad;
			}

			private static void OnWorldFinishedLoading(object sender, EventArgs e)
			{
				AlarmManager.Global.AddAlarm(1f, TimeUnit.Minutes, Start, "Start", AlarmType.NeverPersisted, null);
				EventTracker.AddListener(EventTypeId.kEventSimSelected, OnSelectedSimChanged);
			}
			public static void OnPreLoad()
 			{
 			new BuffBooter().LoadBuffData();
 			}
			private static void Start()
			{
				Sim[] objects = Sims3.Gameplay.Queries.GetObjects<Sim>();
				foreach (Sim sim in objects)
				{
					if (sim != null && sim.IsHuman && !sim.IsRobot && !sim.IsEP11Bot)
					{
						sim.AddInteraction(PossessInteraction.Singleton, true);
						sim.AddInteraction(CyrusHaunt.Singleton, true);
					}
				}
			}
			public static ListenerAction OnSelectedSimChanged(Event e)
{
    Sim[] sims = Sims3.Gameplay.Queries.GetObjects<Sim>();
    foreach (Sim sim in sims)
    {
        Visibility.RefreshVisibility(sim.SimDescription, false);
    }
    return ListenerAction.Keep;
}
Virtual gardener
staff: administrator
#18 Old 31st Jan 2021 at 10:11 AM
Hey @CyrusBanefort !

I merged a few of your threads together that are about this specific interaction. Since it wasn't easy as the person helping what changed and how to help you with any questions. Plus! It makes it easier for you to track down what was going on. 

But just know, it's fine to dedicate one thread to even a project, like Alunn does with their Yoga mod: https://modthesims.info/showthread.php?t=646330

It might be 4 pages long, but it's great stuff and information that's been given!  

Also, not to sound mean here whatsoever, and I know that as a beginner it's easier to ask here since it's a sims-code-related issue, but getting errors like a CS1503 errors and such, is a great resource to learn about coding  Or, in fact, learning to understand and read code. It's a hard thing to do at first, but it teaches your brain to read an error you have, you google it and StackOverflow has allll sorts of issues. But where the trick comes in (And teaching your brain with the logistics of coding, which is a skill altogether by itself) is to see what fixed things for them and how to apply something similar to your code. In fact, it even helps growing in programming to a degree where you find yourself writing most of the code yourself eventually, no matter which programmer language or thing you make it for (websites, games, apps). I do that all the time and that helped me tremendously when starting out sims coding and C#.  So google first, if you really can't figure it out (which I totally get, I have that too occasionally and spend hours getting it to work lol) then of course it's cool to ask!

Hopefully, this doesn't sound like a personal attack or anything, I totally understand that it's hard to code and especially for Ts3! (Also a thank you can be lovely as well for the ones helping out )

But to get to your question:
Does nraas Errortrap give you any errors when the game loads? or Nraas traveler? because usually that indicates that there's some code it's not liking. What happens if you change the sOnWorldLoadFinishedEventHandler stuff into this instead:
Code:
            World.sOnWorldLoadFinishedEventHandler += new EventHandler(OnWorldLoadFinished);


because else you're creating a whole new event handler and overriding the current one, which I don't think will work with other global mods. 

Hope this helps a bit!
Lab Assistant
Original Poster
#19 Old 31st Jan 2021 at 10:23 AM
Quote: Originally posted by Lyralei
Hey @CyrusBanefort !

I merged a few of your threads together that are about this specific interaction. Since it wasn't easy as the person helping what changed and how to help you with any questions. Plus! It makes it easier for you to track down what was going on. 

But just know, it's fine to dedicate one thread to even a project, like Alunn does with their Yoga mod: https://modthesims.info/showthread.php?t=646330

It might be 4 pages long, but it's great stuff and information that's been given!  

Also, not to sound mean here whatsoever, and I know that as a beginner it's easier to ask here since it's a sims-code-related issue, but getting errors like a CS1503 errors and such, is a great resource to learn about coding  Or, in fact, learning to understand and read code. It's a hard thing to do at first, but it teaches your brain to read an error you have, you google it and StackOverflow has allll sorts of issues. But where the trick comes in (And teaching your brain with the logistics of coding, which is a skill altogether by itself) is to see what fixed things for them and how to apply something similar to your code. In fact, it even helps growing in programming to a degree where you find yourself writing most of the code yourself eventually, no matter which programmer language or thing you make it for (websites, games, apps). I do that all the time and that helped me tremendously when starting out sims coding and C#.  So google first, if you really can't figure it out (which I totally get, I have that too occasionally and spend hours getting it to work lol) then of course it's cool to ask!

Hopefully, this doesn't sound like a personal attack or anything, I totally understand that it's hard to code and especially for Ts3! (Also a thank you can be lovely as well for the ones helping out )

But to get to your question:
Does nraas Errortrap give you any errors when the game loads? or Nraas traveler? because usually that indicates that there's some code it's not liking. What happens if you change the sOnWorldLoadFinishedEventHandler stuff into this instead:
Code:
            World.sOnWorldLoadFinishedEventHandler += new EventHandler(OnWorldLoadFinished);


because else you're creating a whole new event handler and overriding the current one, which I don't think will work with other global mods. 

Hope this helps a bit!


Ah, sorry if I did not thank the people who helped. Somehow, my mind thought it would be better to not populate the thread with things not relevant to the topic, but I think it's fine now. Just thanking you for all the help 'till now. Well, I'll try doing this -- But I think there's some problem that goes deeper than that. I tried some solutions already, like making another class to put the instantiator on, but the problem persisted. There's not a error or anything, it just simply does not work. The buff even does not appear in MasterController's list. If I reckon correctly, errortrap did not tell me about anything in particular - Could be that I'm confusing myself, so I'll see about that. Perhaps this could be something related about having two instantiators in the same assembly? I'll also try creating a new assembly, adding it as a reference in this assembly and see if it will work.
Virtual gardener
staff: administrator
#20 Old 31st Jan 2021 at 10:27 AM
Quote: Originally posted by CyrusBanefort
Ah, sorry if I did not thank the people who helped. Somehow, my mind thought it would be better to not populate the thread with things not relevant to the topic, but I think it's fine now. Just thanking you for all the help 'till now. Well, I'll try doing this -- But I think there's some problem that goes deeper than that. I tried some solutions already, like making another class to put the instantiator on, but the problem persisted. There's not a error or anything, it just simply does not work. The buff even does not appear in MasterController's list. If I reckon correctly, errortrap did not tell me about anything in particular - Could be that I'm confusing myself, so I'll see about that. Perhaps this could be something related about having two instantiators in the same assembly? I'll also try creating a new assembly, adding it as a reference in this assembly and see if it will work.
techically you should indeed be able to do this with one instantiator  But weird that Error trap didn't catch anything! 

personally, Whenever it does this to me where things get unclickable and stuff, I usually refer back to this and start out clean again: http://www.simlogical.com/ContentUp..._script_mod.pdf
Lab Assistant
Original Poster
#21 Old 31st Jan 2021 at 12:50 PM
It seems that the problem comes from another one of the mods that I'm using. I've tried running the game only with the Ghost Overhaul, and the interactions appear normally. I don't know why this is happening, so, to avoid other problems, I will limit myself to using the moodlets already in the game. I'm open to suggestions to which moodlet should be used to see the ghosts without having level 5 in Spellcasting or being a Ghost Hunter.
Lab Assistant
Original Poster
#22 Old 31st Jan 2021 at 5:54 PM Last edited by CyrusBanefort : 31st Jan 2021 at 7:48 PM.
Default Final Stages of Development
Okay, the mod is going smoothly. I have only two more systems to work into, excluding the reaction broadcaster for ghosts:

1: Making it so sims cannot autonomously start interactions with ghosts, to finish the visibility issue. (How could I do this? ITUNs, XMLs?

2: A idea that I got from the newest stuff pack in TS4 - A seance table that would allow for communing with otherwordly spirits and the summoning of them. Also, need ideas of what could be used to make this. Don't know if this could be possible.

We're almost there. Thanks for all the help I've got so far.
Virtual gardener
staff: administrator
#23 Old 1st Feb 2021 at 10:16 AM
Quote: Originally posted by CyrusBanefort
Okay, the mod is going smoothly. I have only two more systems to work into, excluding the reaction broadcaster for ghosts:

1: Making it so sims cannot autonomously start interactions with ghosts, to finish the visibility issue. (How could I do this? ITUNs, XMLs?
it's indeed the ITUN  I always check this tutorial to see what needs changing since I can never remember, It's also a great reference post: http://www.simlogical.com/ContentUp...Explanation.pdf

Quote:
2: A idea that I got from the newest stuff pack in TS4 - A seance table that would allow for communing with otherwordly spirits and the summoning of them. Also, need ideas of what could be used to make this. Don't know if this could be possible.
TS3 came with something like-wise but with a different usage (Telling your future, etc) but I think with cloning it you can do it probably: https://store.thesims3.com/setsProd...=OFB-SIM3:48033
Lab Assistant
Original Poster
#24 Old 1st Feb 2021 at 11:01 AM Last edited by CyrusBanefort : 1st Feb 2021 at 4:35 PM.
Thank you. Would it be fine to clone the Soothsayer's Crystal ball, since its an store item?

EDIT: So, I can't find out how to exactly only disallow the autonomy specifically to ghosts from the documentation, as I want the interactions to still be available to be user directed. What I can see is how to completely disallow the interaction for a certain occult.

Any idea what makes Imaginary Friends not interact autonomously with those who are not their owner?

EDIT2: Nevermind, I found it.

EDIT3: Ok, did my own version of the CanSocializeWith function.

Code:
public static class CanSocialize
{
	public static bool CanSocializeWith(SimDescription targetDescription, Sim otherSim)
{
	if (!targetDescription.IsGhost)
	{
		return true;
	}
	if (otherSim == null)
	{
		return true;
	}
	SimDescription simDescription = otherSim.SimDescription;
	if (simDescription == targetDescription)
	{
		return true;
	}
	if (simDescription != null && (simDescription.Occupation is GhostHunter || (simDescription.SkillManager.HasElement(SkillNames.Spellcraft) && simDescription.SkillManager.GetElement(SkillNames.Spellcraft).SkillLevel >= 5) || simDescription.CreatedSim.BuffManager.HasElement(0x15DABBECF72A9084)))
	{
		return true;
	}
	return false;
}
}


Just need to figure out how to instantiate it in the game. I tried doing this in the instantiator class:

Code:
foreach (Sim sim in sims)
    			{
        			Visibility.RefreshVisibility(sim.SimDescription, false);
        			CanSocialize.CanSocializeWith(sim.SimDescription, false);
    			}


Thought it would work, since the RefreshVisibility function is also a boolean, but it did not accept it.

EDIT4: Also tried doing this:

Code:
public static class CanSocialize
{
	public static bool CanSocializeWith(Sim otherSim, bool immediate)
{
	SimDescription simDescription = otherSim.SimDescription;
	if (simDescription.IsGhost)
	{
		return true;
	}
	if (otherSim == null)
	{
		return true;
	}
	
	if (simDescription == mSimDescription)
	{
		return true;
	}
	if (simDescription != null && (simDescription.Occupation is GhostHunter || (simDescription.SkillManager.HasElement(SkillNames.Spellcraft) && simDescription.SkillManager.GetElement(SkillNames.Spellcraft).SkillLevel >= 5) || simDescription.CreatedSim.BuffManager.HasElement(0x15DABBECF72A9084)))
	{
		return true;
	}
	return false;
}
	public static SimDescription mSimDescription;
}


It let me compile when I did this

Code:
CanSocialize.CanSocializeWith(sim, false);


However, nothing happened. The interactions continued to be autonomous. Also tried with only the sim otherSim argument, also to no avail. I'm starting to think that's not what makes the Imaginary Friend not interact with other sims.

EDIT5: Apparently, the code for making Imaginary Friends not interact with other sims is built into the interactions itself. So, I will need another plan.
Lab Assistant
Original Poster
#25 Old 1st Feb 2021 at 5:14 PM Last edited by CyrusBanefort : 1st Feb 2021 at 9:09 PM.
So... I think both copying the code from the Imaginary Friend occult and using ITUN files is out of question. What should I do? It's still very strange for sims to randomly start chatting with something that they cannot see.

EDIT: Is it possible to add a listener that checks if the sim is trying to interact with another?

EDIT2: I found something that might be able to help me. I found a eventlistener called OnSocialization. My aim is to change these two pieces of code:

Code:
public static bool CanSimSocializeWithSim(Sim actor, Sim target)
{
	OccultImaginaryFriend occult;
	if (TryGetOccultFromSim(actor, out occult) && !occult.CanSocializeWith(target))
	{
		return false;
	}
	OccultImaginaryFriend occult2;
	if (TryGetOccultFromSim(target, out occult2) && !occult2.CanSocializeWith(actor))
	{
		return false;
	}
	return true;
}


and

Code:
public static bool TryGetOccultFromSim(Sim sim, out OccultImaginaryFriend occult)
{
	if (sim != null && sim.SimDescription.IsImaginaryFriend)
	{
		occult = (sim.OccultManager.GetOccultType(OccultTypes.ImaginaryFriend) as OccultImaginaryFriend);
		return occult != null;
	}
	occult = null;
	return false;
}


In something that could be used by ghosts, using the first boolean to cancel social interactions in case the sim isn't who I want to be, but I need help. I think if I finish these two interactions, the most difficult part of the mod is done, and I only need to focus on interactions.
Page 1 of 2
Back to top