Replies: 3 (Who?), Viewed: 288 times.
Virtual gardener
staff: administrator
Original Poster
#1 Old 8th Jan 2021 at 6:02 PM
Default NameComponent causing null errors
Hey everyone!

Been working on a journal mod and one of the things is that I want it so that sims can 'own' their journal. I've done the name changing before for the patterns, however this time around it seems to return null references. 

Here's how i'm doing it:

Code:
//Inside run()
base.Target.mOwnerDescId = base.Actor.SimDescription;
print("mOwnerDescId exists " + base.Target.mOwnerDescId.FirstName); // This returns the first name of the sim. So this isn't the issue.
base.Target.NameComponent.mName = base.Target.mOwnerDescId.FirstName + " Journal";

// Used to do this but thta gives the same error:
base.Target.NameComponent.SetName(base.Target.mOwnerDescId.FirstName + " Journal");
Now, for debugging purposes, I ended up doing this:

Code:
            if(base.Target.NameComponent.mName != "")
                {
                    print("Setting target");
                    base.Target.NameComponent.mName = base.Target.mOwnerDescId.FirstName + " Journal";
                    print("Target component set");
                }
                else
                {
                    print("Component couldn't be set");
                    base.Actor.AddExitReason(ExitReason.FailedToStart);
                    return false;
                }
Unfortunately, it seems to already not like the code at the 'if' statement already. So the sim, when the code reaches the if statements, gets resetted. I'm just not sure what I'm doing wrong? 
Advertisement
Field Researcher
#2 Old 8th Jan 2021 at 7:55 PM
This might sound obvious but did you add the component before ? (the half done getter below migh also help)

Code:
        		Sims3.Gameplay.ObjectComponents.NameComponent objectNameComponent = Target.NameComponent;
        		if(objectNameComponent == null)
        		{
        			Target.AddComponent<Sims3.Gameplay.ObjectComponents.NameComponent>;
        		}


Quote:
it seems to already not like the code at the 'if' statement already

Sure if the Component is already null you cant access the mName field
Virtual gardener
staff: administrator
Original Poster
#3 Old 8th Jan 2021 at 9:16 PM
Quote:
Originally Posted by Battery
This might sound obvious but did you add the component before ? (the half done getter below migh also help)

Code:
              Sims3.Gameplay.ObjectComponents.NameComponent objectNameComponent = Target.NameComponent;
              if(objectNameComponent == null)
              {
                 Target.AddComponent<Sims3.Gameplay.ObjectComponents.NameComponent>;
              }



Sure if the Component is already null you cant access the mName field
Thatttt actually makes a lot of sense! I think what initially instantiated it for the patterns was that I created them on world build. The journal on the other hand isn't exactly done the same way. Let me try that.

EDIT: that worked! Now I do have a whole different thing to fix, but at least it got me one step further from debugging the interaction. Thank you!
Virtual gardener
staff: administrator
Original Poster
#4 Old 10th Jan 2021 at 4:27 PM
Just in case anyone seeing this thread is wondering how to change the original's object's name (So that you end up with objects like "Sim's name's car" or such, here's the code, but a bit more complex to create a custom one:


The complexer and less limited to creating your own naming component:
Code:
 public class LyraleiJournal : GameObject, ICarryable
    {
        public class JournalNameComponent : NameComponent
        {
            public JournalNameComponent()
            {
            }
            public JournalNameComponent(GameObject o)
                : base(o)
            {
            }
            public JournalNameComponent(GameObject o, bool isBuildBuyNameOnly)
                : base(o)
            {
            }
            public JournalNameComponent(GameObject o, string randomNameGenerator)
                : base(o)
            {
            }
            public override string GetDefaultName()
            {
                LyraleiJournal journal = base.Owner as LyraleiJournal;
                if (journal == null)
                {
                    return string.Empty;
                }
                return journal.NameComponent.Name;
            }
        }

public string mJournalOwnerFirstName = "";

// Calling it inside an interaction:
public class SetJournalOwner : ImmediateInteraction<Sim, LyraleiJournal>
        {
         // Assuming we already added the definition, getInteractionName and Test here...
         public override bool Run()
         {
            base.StandardEntry();
            // I'm using this variable to save the actor's first name eventually... 
                base.Target.mOwnerDescId = base.Actor.SimDescription;
            // ALTERNATIVELY: A quicker way to gain the first name of a sim when you just need their first name:
            base.Target.mJournalOwnerFirstName = base.Actor.SimDescription.FirstName;
            
            // Here we set a new name. 
            //NOTE: if you're using the alternative way of getting the sim's first name, replace it with "base.Target.mJournalOwnerFirstName" instead, rather than    base.Target.mOwnerDescId.FirstName.
                base.Target.NameComponent.SetName(base.Target.mOwnerDescId.FirstName + " Journal");
         }
      }
   }

public override void OnStartup()
{
   base.AddComponent<JournalNameComponent>(new object[0]);
   base.OnStartup();
}

// I usually add this, but this is optional. Basically, this says if the cursor hovers over the object, we see the name tooltip coming up.
        public override string ToTooltipString()
        {
            string name = base.NameComponent.Name;
            return name ?? base.ToTooltipString();
        }


The quick and dirty way:

Code:
// ALLL this code is of course wrapped around your general public class, just like in the first example where it is LyraleisJournal 

public string mJournalOwnerFirstName = "";

// Calling it inside an interaction:
public class SetJournalOwner : ImmediateInteraction<Sim, LyraleiJournal>
        {
         // Assuming we already added the definition, getInteractionName and Test here...
         public override bool Run()
         {
            base.StandardEntry();
            // I'm using this variable to save the actor's first name eventually... 
                base.Target.mOwnerDescId = base.Actor.SimDescription;
            // ALTERNATIVELY: A quicker way to gain the first name of a sim when you just need their first name:
            base.Target.mJournalOwnerFirstName = base.Actor.SimDescription.FirstName;
            
            // Here we set a new name. 
            //NOTE: if you're using the alternative way of getting the sim's first name, replace it with "base.Target.mJournalOwnerFirstName" instead, rather than    base.Target.mOwnerDescId.FirstName.
                base.Target.NameComponent.SetName(base.Target.mOwnerDescId.FirstName + " Journal");
         }
      }
   }

public override void OnStartup()
{
   base.AddComponent<NameComponent>(new object[0]);
   base.OnStartup();
}
        public override string ToTooltipString()
        {
            string name = base.NameComponent.Name;
            return name ?? base.ToTooltipString();
        }
Hope this helps anyone!
Back to top