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
Mad Poster
Original Poster
#1 Old 30th Oct 2021 at 2:26 AM
Default Rotating a sim
So I'm working on a mod that lets sims sleep on the blocked side of a double bed.
How the mod works is that I snap the sim to the entry slot of the blocked side, then play the single animation of napping on a bed. Then handle raising the energy of the sim in code, so this is actually fakesleeping.

The mod is working fine, for the exception that if the bed's right side is blocked, the sim will sleep upside down.



1. I have no idea why the sim sleeps like this when snapping him to the right side.
2. I can't find anything in the napping on bed interaction that would explain this.
3. Is there a way to either mirror the napping animation or to rotate the sim in the direction of the arrow so I could flip him over?
Advertisement
Virtual gardener
staff: administrator
#2 Old 31st Oct 2021 at 1:33 PM
Heya!

I had something similar with the sheep mod, where my sims would be talking to the sheep but facing away Given the fact that you mentioned the entry slot, I think I might know the issue.

So when we're creating new slots or editing slots, you basically want the slot Matrix inside the RSTL to have the 1's the same way as here:

Code:
      X: Rot1: -1; Rot2: 0; Rot3: 0; Pos: 0
      Y: Rot1: 0; Rot2: 1; Rot3: 0; Pos: 0
      Z: Rot1: 0; Rot2: 0; Rot3: -1; Pos: 1,45964


the -1 here is also super important! because those make it so that your sim is actually not rotated to a positive angle. For some reason, slots are always rotated the negative way around :p

here's what the Rig's matix looks like (since that needs to be the same!)

Code:
Name:	_route_0_N
Hashed:	0x5D2145D9
Absolute Transform (RSLT):
X:[ 1,00000, 0,00000, 0,00000] Pos: 0,00000
Y:[ 0,00000, 0,00000,-1,00000] Pos: 0,45964
Z:[ 0,00000, 1,00000, 0,00000] Pos: 1,54500

Absolute Transform Inverse (SKIN):
[ 1,00000, 0,00000, 0,00000]
[ 0,00000, 0,00000,-1,00000]
[ 0,00000, 1,00000, 0,00000]
[ 0,00000,-1,54500, 0,45964]


After that, that should fix it! Alternatively, although this doesn't always work, once your sim is snapped onto the bed, you could always do:

Code:
// First parameter is a float, but as regular directions go, can only go 360 degrees 
sim.SetRotation(180);
Mad Poster
Original Poster
#3 Old 1st Nov 2021 at 4:03 PM
Hi Lyralei, and thank you for replying

The slots in question are EA slots, because I add the Squeeze In - interaction to EA double beds.
If I understand correctly, your methods modifies the actual slots?

I have to try the rotating method again. I've tried it but couldn't understand how is the sim rotating. It didn't seem to use any logical math I think it's because I don't know what is the zero positition, from which the anglerotation measured.

I've had some success with modifying the sim's position on the bed, but because the bed can be anywhere in the world facing any directoin I haven't yet figured out how to know what is the bed's rotation or how to know where it's facing. I've found the routing codes that let sims route and face the object, but what ever math EA is doing with the Vectors is beyond me.

Now I'm thinking about comparing the bed's position and the left side's entry slot' sposition, to determine how much should I move the sim if I want him to be on the right side. But let's see how that goes.
Virtual gardener
staff: administrator
#4 Old 3rd Nov 2021 at 3:25 PM
Quote: Originally posted by ani_
Hi Lyralei, and thank you for replying

The slots in question are EA slots, because I add the Squeeze In - interaction to EA double beds.
If I understand correctly, your methods modifies the actual slots?

I have to try the rotating method again. I've tried it but couldn't understand how is the sim rotating. It didn't seem to use any logical math I think it's because I don't know what is the zero positition, from which the anglerotation measured.

I've had some success with modifying the sim's position on the bed, but because the bed can be anywhere in the world facing any directoin I haven't yet figured out how to know what is the bed's rotation or how to know where it's facing. I've found the routing codes that let sims route and face the object, but what ever math EA is doing with the Vectors is beyond me.

Now I'm thinking about comparing the bed's position and the left side's entry slot' sposition, to determine how much should I move the sim if I want him to be on the right side. But let's see how that goes.


Ohh! Allright! I initially thought you made some custom ones

Yeah in that case rotate function might be helpful, but that is if you know the forward vector of the bed + which way the sim is currently facing. However, assuming that, when the bed is diagonally and the sim still is sleeping the other way around, i'd just simply do:

Code:
base.Actor.SetRotation(180f);


Otherwise, you might end up having to rotate it on a Matrix4x4 method in your code, as the Quatenion way of doing it (while possible) also has a bit of a headachy-mathy way of figuring out by how much it needs to be rotated for the source object (sim) to face the target (bed)
Senior Moderator
staff: senior moderator
#5 Old 4th Nov 2021 at 1:02 PM Last edited by zoe22 : 4th Nov 2021 at 1:13 PM.
I wonder if it's actually the animation that's the problem - I haven't checked, but I'm guessing there must be two napping animations, one for each side of the bed. If the sim is on one side rather than the other, maybe you need to set a parameter in the jazz script and use the mirrored anim instead?

edit: Okay so I can't see anything either about a mirrored nap animation, though there seems to be a mirrored relax one? So I'm confused as to how the napping interaction does it :p
Virtual gardener
staff: administrator
#6 Old 4th Nov 2021 at 2:31 PM
Quote: Originally posted by zoe22
I wonder if it's actually the animation that's the problem - I haven't checked, but I'm guessing there must be two napping animations, one for each side of the bed. If the sim is on one side rather than the other, maybe you need to set a parameter in the jazz script and use the mirrored anim instead?

edit: Okay so I can't see anything either about a mirrored nap animation, though there seems to be a mirrored relax one? So I'm confused as to how the napping interaction does it :p


That's actually not a bad thought, because initially, it doesn't have to be a slot that the sim snaps onto. In this case, it can be an IK target that's rotating it (or maybe the lack of data that makes it flip the sim ) I don't think you saw anything in the animation itself about that? Otherwise, that might be nice to check as well!

Although the way EA coded the whole bed interaction stuff is just... very complicated from what it needs to be (I'm assuming they started working on the whole bed interactions before they figured out the boilerplate of how to do interactions) So I haven't been able to find anything in the code that says "hey here we flip the sim/rotate it".
Virtual gardener
staff: administrator
#7 Old 4th Nov 2021 at 2:43 PM
I was just thinking about this because I think Zoe is on the right path of that it might be the animations. If Relax has 2 different animations, then either there's one for sleep as well, or in some way they're 'mirroring' the animations indeed.

Because indeed, the reason its flipped that way, is because of the fact that (and this can be read from the source code) the game figures out which bedside is available/routable and pre-sets the animations to work for that bedside. Now, in your code, you're making it so that, even if the bed is against a wall, that the sim can still go to sleep on it, meaning that initially the bed can only be "accessed" by one side, and therefore it's expecting that the sim will be sleeping on that side as well. So when you snap that sim to the other side of the bed, they're going to be sleeping upside down.

Soooo, knowing that the "enter bed" interaction has all that code to figure out where the sim has to go, I'm assuming that in the Jazz script for the bed there's a value of 'mirroring' things. I can't remember if this is true, but I do remember that Jazzscripts can mirror animations without needing 2 clip files. I'll have to check out the Jazz script for that though but I remember seeing something like that when I was checking out the napping on couches for someone.

So I'll check and see if that's the case! because then the fix is even simpler than rotating the sim.
Virtual gardener
staff: administrator
#8 Old 4th Nov 2021 at 7:28 PM
Allright so I did find the thing I remembered correctly :p

here's the jazz snippet that mirrors stuff:

Code:
    State "Un-Reverse Mirror for Single Bed"
    {
        Transitions to "Choose Get In"
        Transitions to "JustMakeBed"
        Select on Parameter "MakeOppositeSide"
        {
            Value "yes"
            {
                Select on Parameter "IsMirrored"
                {
                    Value "no"
                    {
                        Actor Operation None on "bed"
                    }
                    Value "yes"
                    {
                        Actor Operation SetMirror on "bed"
                    }
                }
            }
        }
    }


Now, thw question of course is, how do we tell the jazz script that if the sim is entering the right side, but sleeps on the "wrong" side? It's not that difficult really as telling the jazz script.

So in your Run() function I'd simply do this:

Code:
//Pretending Routing code is here...

/*
* I'd 100% recommend first getting any data (and I assume you already do since you already have a sim snapped to an unroutable side of the bed ) and from there do an if statement to help the logic of "Empty side, but unroutable sim. We need to mirror the animations!"
*/

// mCurrentStateMachine will get the interaction's statemachine. This will be bedrelax statemachine. TRUE == is Mirrored, FALSE == not mirrored!
base.mCurrentStateMachine.SetParameter("IsMirrored", true); 

// And now You call your napping statemachine/animation 

// If For some reason this doesn't work, however... Do this instead:

/*
*               <! --- Here we're canceling the Relax Statemachine and redo this. It will result in the sim standing for a really brief moment
*		BedData partContaining = base.Target.GetPartContaining(base.Actor);
*		if (partContaining != null)
*		{
*			if (base.Actor.Posture is SleepingPosture)
*			{
*				StateMachineClient stateMachine = partContaining.StateMachine;
*				if (stateMachine != null)
*				{
*					stateMachine.RequestState("x", "ExitRelax");
*					partContaining.StateMachine = null;
*				}
*				partContaining.BedMade = true;
*			}
*			mEntryStateName = "Enter_OnBed_" + partContaining.StateNameSuffix;
*			mEntryPart = partContaining;
*			return true;
*		}
*      StateMachineClient mCurrentStateMachine = partContaining.StateMachine;

*	mCurrentStateMachine = StateMachineClient.Acquire(base.Actor, "BedRelax", AnimationPriority);
*	mCurrentStateMachine.SetActor("x", base.Actor);
*	mCurrentStateMachine.SetActor("bed", base.Target.Container); // Originally base.Container but I don't know your code so I'm assuming you need Target.

*      <------ Wrap this around your blocked bedside if statement to return the right boolean! ---------->
*	mCurrentStateMachine.SetParameter("IsMirrored", true/false);

*	mCurrentStateMachine.SetParameter("IkSuffix", base.target.mEntryPart.IkSuffix);
*	mCurrentStateMachine.SetParameter("IsBedMade", base.target.mEntryPart.BedMade);
*	mCurrentStateMachine.SetParameter("IsTent", base.target.mEntryPart is TentData);
*	mCurrentStateMachine.SetParameter("IsTrashBed", base.target.mEntryPart.IsTrashBed);
*	mCurrentStateMachine.SetParameter("IsUpperBunk", false);
*	mCurrentStateMachine.SetParameter("MakeOppositeSide", false);
*	mCurrentStateMachine.SetParameter("isIgloo", base.target.mEntryPart is IglooData);
*	mCurrentStateMachine.SetParameter("IsDreamPod", base.target.mEntryPart is BedDreamPod.DreamPodData);

*      <------ StateNameSuffix is the name of the bedside it's entering. Keep that in mind! This will trigger the mirrored code as well inside the Jazz script  ---------->
*      mCurrentStateMachine.EnterState("x", "Enter_BedRelax_" + base.target.mEntryPart.StateNameSuffix);
*      mCurrentStateMachine.RequestState("x", "Relax");

*      <------ I don't know if you need this, but I'll add it for your first run Otherwise, comment this out if you're using this snippet  ---------->
*      RelaxingPosture relaxingPosture = (RelaxingPosture)(s.Posture = new RelaxingPosture(base.target.Container as Bed, base.Actor, base.target.mEntryPart));
*	relaxingPosture.PostEnterContainer();

*	base.LowerPriority();
*	base.Actor.InteractionQueue.Add(YOURNAPINTERACTION.Singleton.CreateInstance(base.Target, base.Actor, base.GetPriority(), true, true));
*	base.RaisePriority();

*/


The last commented out bit is not ideal, but because of the way that the interactions are chained (and I'm not familiar with your code), that is a potential plan b if re-setting the parameters while the jazz script is already activated is not doing it. The reason why you need to redo the state machine animations is that on Enter Relax, the game tells it whether it needs to enter it from "Route0" or "route1" and those are the entry bit of the jazz script. We cannot in any way enter a state that doesn't have an 'Entry' parameter. Alternatively, you can always create your own custom jazz script for this But that really depends on what you wanna do.
Mad Poster
Original Poster
#9 Old 13th Nov 2021 at 7:25 AM
Thank you guys for helping me out I'll have to try this out and return back.
Haven't been on my simming computer for a while that's why I haven not even checked had the conversation gone forward.
Back to top