- Site Map >
- Modding and Creation >
- Sims 3 Creation >
- Modding Discussion >
- Posture problems
- Site Map >
- Modding and Creation >
- Sims 3 Creation >
- Modding Discussion >
- Posture problems
Replies: 1 (Who?), Viewed: 586 times.
#1
30th Jul 2022 at 5:50 PM
Last edited by lizcandor : 30th Jul 2022 at 9:59 PM.


I've been editing the posture preconditions for a bunch of interactions in bulk on preload (looping through InteractionTuning.sAllTunings.Values and changing the posture precondition fields of all interactions with "GoHere" or "Watch" in their names, to add an entry for the CommodityKind I created to go with InWheelchairPosture), but this doesn't seem to be enough to keep the sim seated. I'm kind of stuck. Is there an additional component I'm missing in the game's decision about which postures are and aren't compatible with whatever interaction a sim is trying to do? Code for InWheelchairPosture is in the spoiler if it's any use.
Code:
public class InWheelchairPosture : Posture, ISeatedSocialPosture, ISeatPosture, ICountsAsSittingForCarry, IDoNotGoToStandingOnTransitionFailed { public IGameObject mContainer; public ObjectGuid mContainerGuid; public Sim mSim; public PartReference<SitData> Part; public Sim Sim => mSim; public bool ContainerIsBarStool => Container is IChairBarStool; public override bool PerformIdleLogic => false; public override IGameObject Container { get { if (mContainer == null && mContainerGuid.IsValid) { IScriptProxy proxy = Simulator.GetProxy(mContainerGuid); if (proxy == null) { return null; } mContainer = proxy.Target as IGameObject; } return mContainer; } } public override string Name => "InWheelchair"; public Seat Seat { get { return Part.Target as Seat; } set { mContainer = value.Host; CurrentStateMachine.SetActor("sitTemplate", mContainer); CurrentStateMachine.SetActor("seatOrigin", mContainer); CurrentStateMachine.SetActor("surface", mSim); Part.Target = value; } } public bool SimIsTalkingToOtherSim { get { if (mSim.GroupTalkCurrentSpeaker == mSim) { return mSim.GroupTalkSimToTalkTo != mSim; } return true; } } public bool SimCanUseSofaChats { get { if (Container is GameObject gameObj) { ISittable sittable = SittingHelpers.CastToSittable(gameObj); if (sittable != null && sittable.GetIdleStateName(mSim) == "sitting_idle_living") { InteractionInstance runningInteraction = mSim.InteractionQueue.RunningInteraction; if (runningInteraction != null && runningInteraction.Target is ICantUseAnimatedSittingSocialsWhenUsing) { return false; } return true; } } return false; } } public InWheelchairPosture() { } public InWheelchairPosture(IGameObject container, Sim sim, StateMachineClient smc, SitData sitPart) : base(smc) { mContainer = container; mContainerGuid = container.ObjectId; mSim = sim; Part.SetTarget(sitPart); smc.AddPersistentStateEnteredEventHandler("motiveDistress", sim.IdleManager.OnEnterDistressIdle); smc.AddPersistentStateEnteredEventHandler(SittingHelpers.CastToSittable(container as GameObject).GetIdleStateName(mSim), TriggerFacialIdle); smc.AddPersistentStateEnteredEventHandler("Sit", CancelSittingOverlay); mSim.SimRoutingComponent.DisableDynamicFootprint(); if (container.SculptureComponent != null && container.SculptureComponent.Material == SculptureComponent.SculptureMaterial.Ice) { mSim.BuffManager.AddElementPaused(BuffNames.Chilly, Origin.FromSittingOnIce); } } public void TriggerFacialIdle(StateMachineClient smc, IEvent evt) { mSim.IdleManager.OnExitDistressIdle(smc, evt); mSim.PlayFacialIdle(smc, evt); } public void CancelSittingOverlay(StateMachineClient smc, IEvent evt) { mSim.OverlayComponent.StopAllOverlays(); } public override void PopulateInteractions() { AddSocialInteraction(StartSeatedCuddleA.Singleton); AddSocialInteraction(CallOver_Seated.Singleton); if (GameUtils.IsInstalled(ProductVersion.EP3)) { AddSocialInteraction(MakeMoveSimA.Singleton); AddInteraction(MakeMoveSimA.Singleton, mSim); } AddInteraction(StartSeatedCuddleA.Singleton, mSim); AddInteraction(CuddleSeatedKiss.Singleton, mSim); AddInteraction(CuddleSeatedMakeOut.Singleton, mSim); if (GameUtils.IsInstalled(ProductVersion.EP5)) { AddInteraction(SitOnSim.Singleton, mSim); } } public override bool AllowsReactionOverlay() { return true; } public override bool AllowsNormalSocials() { return true; } public override bool AllowsRouting() { return true; } public override void AddInteractions(IActor actor, IActor target, List<InteractionObjectPair> results) { if (AllowsNormalSocials() && actor.Posture.AllowsNormalSocials()) { SocialComponent.AddInteractionsForSeatedSocialPosture(actor, target, results, base.Interactions); } } public override bool Compatible(Posture currentPosture) { if (currentPosture.Satisfies(CommodityKind.CarryingChild, null) || currentPosture.Satisfies(CommodityKind.CarryingObject, null) || currentPosture.Satisfies(CommodityKind.CarryingPet, null) || currentPosture.Satisfies(CommodityKind.CarryingHoloPet, null) || currentPosture.Satisfies(CommodityKind.Sitting, null)) { return true; } return base.Compatible(currentPosture); } public override bool Satisfies(PreconditionOptions options, IGameObject target, CommodityKind requiredCheck) { if (PreviousPosture != null) { if (PreviousPosture is SimCarryingObjectPosture) { if (options != null && !options.ContainsCheck(CommodityKind.CarryingObject)) { return false; } } else if (requiredCheck == CommodityKind.MayCarryChild && PreviousPosture.Satisfies(CommodityKind.CarryingHoloPet, null)) { requiredCheck = CommodityKind.None; } } return base.Satisfies(options, target, requiredCheck); } public override float Satisfaction(CommodityKind condition, IGameObject target) { switch (condition) { case (CommodityKind)51330370: return 1f; case CommodityKind.Sitting: return 1f; case CommodityKind.MayCarryChild: return 1f; case CommodityKind.InFrontOfSurfaceForTarget: if (target.IsObjectInFrontOfMe(Container)) { return 1f; } return 0f; case CommodityKind.ChairNotScootedIntoSurface: if (Container is IChairDining chairDining2 && !chairDining2.IsScootedIn()) { return 1f; } return 1f; case CommodityKind.ChairScootedIntoSurface: if (Container is IChairBarStool) { return 1f; } if (Container is IChairDining chairDining && chairDining.IsScootedIn()) { return 1f; } return 0f; case CommodityKind.ChairIsNotBarstool: if (Container is IChairBarStool) { return 0f; } return 1f; case CommodityKind.IsTarget: if (target == Container) { return 1f; } return 0f; case CommodityKind.IsTargetGroup: { IHasSeatingGroup hasSeatingGroup = target as IHasSeatingGroup; IHasSeatingGroup hasSeatingGroup2 = Container as IHasSeatingGroup; if (hasSeatingGroup != null && hasSeatingGroup2 != null && hasSeatingGroup.SeatingGroup == hasSeatingGroup2.SeatingGroup) { return 1f; } return 0f; } case CommodityKind.IsTargetGroupAndHasTwoSeats: { IHasSeatingGroup hasSeatingGroup3 = target as IHasSeatingGroup; IHasSeatingGroup hasSeatingGroup4 = Container as IHasSeatingGroup; if (hasSeatingGroup3 != null && hasSeatingGroup4 != null && hasSeatingGroup3.SeatingGroup == hasSeatingGroup4.SeatingGroup) { Seat seat = hasSeatingGroup4.SeatingGroup[mSim]; if (PartData.CanBeUsedBy(seat.Left, mSim) || PartData.CanBeUsedBy(seat.Right, mSim)) { return 1f; } } return 0f; } case CommodityKind.NextToTarget: if (Container is IHasSeatingGroup hasSeatingGroup5 && hasSeatingGroup5.SeatingGroup[target as Sim] != null) { return 1f; } return 0f; case CommodityKind.MutualFacing: return GameObject.MutuallyFacing(Container, target); case CommodityKind.CanGroupChat: { InteractionInstance headInteraction = mSim.InteractionQueue.GetHeadInteraction(); if (headInteraction != null && headInteraction.InteractionDefinition is SeatedSocialInteractionA.SeatedDefinition seatedDefinition && seatedDefinition.IsLongRange) { if (mSim.Posture != null && mSim.Posture.Container == Container) { return 1f; } return 0f; } IGameObject gameObject = null; Sim sim2 = target as Sim; if (sim2 != null) { gameObject = sim2.Posture.Container; } if (gameObject == Container) { return 1f; } if (gameObject.Parent == Container.Parent && Container.Parent != null) { return 1f; } if (Container.RoomId == target.RoomId && Container.GetDistanceToObject(target) < Sim.MaxDistanceForGroupTalk && Container.PointIsInVisionCone(target.Position) && (sim2.Posture is Sim.StandingPosture || target.PointIsInVisionCone(Container.Position))) { return 1f; } return 0f; } case CommodityKind.ContainerParentedToTarget: if (target != null && Container.Parent != target) { return 0f; } return 1f; case CommodityKind.ContainerParentedToExtendedTarget: if (target is IExtendableObject extendableObject && extendableObject.IsParentedExtended(Container)) { return 1f; } return 0f; case CommodityKind.PreferIfCurrentPosture: if (mSim.Posture is InWheelchairPosture) { return 1f; } return 0f; case CommodityKind.FacingTarget: return Container.ObjectFacingMe(target); case CommodityKind.NextToSim: { IChairOwningEatingSurface chairOwningEatingSurface = Container.Parent as IChairOwningEatingSurface; Sim sim = target.Parent as Sim; if (chairOwningEatingSurface == null || sim == null || !chairOwningEatingSurface.HasRelativeSittingAtSurface(sim)) { return 0.5f; } return 1f; } default: return 0f; } } public InteractionInstance GetSitAngleTransition(InteractionInstance interaction) { return SittingHelpers.CastToSittable(Container as GameObject)?.GetSitAngleTransition(interaction); } public override InteractionInstance GetTransition(InteractionInstance interaction) { if (Instantiator.kDebugging) StyledNotification.Show(new StyledNotification.Format("Called GetTransition", mSim.ObjectId, StyledNotification.NotificationStyle.kSimTalking)); if (PreviousPosture is SimCarryingObjectPosture && !interaction.PosturePreconditions.ContainsCheck(CommodityKind.CarryingObject)) { return PreviousPosture.GetStandingTransition(); } foreach (PreconditionSet set in interaction.PosturePreconditions.Sets) { if (set.Commodity != CommodityKind.Sitting || set.Commodity!= (CommodityKind)51330370) { continue; } bool flag = true; foreach (CommodityKind condition in set.Conditions) { if (condition != CommodityKind.ChairNotScootedIntoSurface && condition != CommodityKind.ChairScootedIntoSurface) { flag = Satisfies(condition, interaction.Target); if (!flag) { break; } } } if (flag) { InteractionInstance sitAngleTransition = GetSitAngleTransition(interaction); if (sitAngleTransition != null) { return sitAngleTransition; } } } return base.GetTransition(interaction); } public override InteractionInstance GetStandingTransition() { if(Instantiator.kDebugging) StyledNotification.Show(new StyledNotification.Format("Called GetStandingTransition", mSim.ObjectId, StyledNotification.NotificationStyle.kSimTalking)); Stand stand = new Stand(); InteractionObjectPair iop = new InteractionObjectPair(Stand.Singleton, Container); InteractionInstanceParameters parameters = new InteractionInstanceParameters(iop, mSim, mSim.InheritedPriority(), autonomous: false, cancellableByPlayer: false); stand.Init(ref parameters); return stand; } public override BridgeOrigin Idle() { base.Idle(); if (!(Container is GameObject gameObject)) { return mSim.BridgeOrigin; } ISittable sittable = SittingHelpers.CastToSittable(gameObject); if (mSim == IntroTutorial.TutorialSim && gameObject is ICouch) { IntroTutorial.StateComplete(TutorialStates.SatOnCouch); } if (sittable == null) { return mSim.BridgeOrigin; } CurrentStateMachine.SetParameter("EnjoyingMusic", mSim.BuffManager.HasElement(BuffNames.EnjoyingMusic)); CurrentStateMachine.RequestState(yield: true, "x", sittable.GetIdleStateName(mSim), DriverRequestFlags.kRequestEmulateEdith, -1); return new BridgeOrigin(CurrentStateMachine, "x", true, sittable.GetSitStateName()); } public override ScriptPosture GetSacsPostureParameter() { return ScriptPosture.NoAnimation; } public override void Shoo(bool yield, List<Sim> shooedSims) { throw new Exception("The method or operation is not implemented."); } public override StateMachineClient GetPostureStateMachine(PostureInteractions interaction, GetStateMachineDelegate GetInteractionStateMachine) { StateMachineClient stateMachineClient = GetInteractionStateMachine(); stateMachineClient.SetActor("sitTemp", Container); stateMachineClient.SetParameter("sitTemplateSuffix", Part.Target.IKSuffix); return stateMachineClient; } public override Posture OnReset(IGameObject objectBeingReset) { SitData target = Part.Target; if (target != null && Container != null && Container.PartComponent != null) { target.SetContainedSim(null, Container.PartComponent); } if (Container != null && Container.IsActorUsingMe(Sim)) { Container.SetObjectToReset(); } if (CurrentStateMachine != null) { CurrentStateMachine.Dispose(); CurrentStateMachine = null; } mSim.BuffManager.RemoveElement(BuffNames.Comfy); return null; } public override void OnExitPosture() { IntroTutorial.StateComplete(TutorialStates.ActionCancelled); mSim.SimRoutingComponent.EnableDynamicFootprint(); mSim.BuffManager.UnpauseBuff(BuffNames.Chilly); base.OnExitPosture(); } public override void PlayScheduledIdle(IdleAnimationData idleAnimData, string jazzStateNamePrefix, bool isDistressIdle) { if (isDistressIdle) { mSim.IdleManager.StopFacialIdle(isJazzGraph: true); mSim.Posture.CurrentStateMachine.RequestState(yield: true, "x", "motiveDistress", DriverRequestFlags.kShortest); } } public override bool ReactionAllowed() { return mSim.IsPet; } public override string ToString() { return "Sitting on " + mContainer.ToString(); } public virtual void OnSeatVacated() { } public void EnsureSeatPosture() { if (Satisfies(CommodityKind.Sitting, null)) { BridgeOrigin bridgeOrigin = mSim.BridgeOrigin; if (bridgeOrigin != null) { mSim.BridgeOrigin = null; bridgeOrigin.MakeOrSkipRequest(yield: true, CurrentStateMachine); } CurrentStateMachine.RequestState(yield: true, "x", "sitting_living", DriverRequestFlags.kShortest); } } public override bool GroupTalkStartTalking() { if (SimCanUseSofaChats) { if (SimIsTalkingToOtherSim) { BridgeOrigin bridgeOrigin = mSim.BridgeOrigin; if (bridgeOrigin != null) { mSim.BridgeOrigin = null; bridgeOrigin.MakeOrSkipRequest(yield: true, CurrentStateMachine); } CurrentStateMachine.SetActor("sitTemplate", mContainer); CurrentStateMachine.SetActor("seatOrigin", mContainer); CurrentStateMachine.SetActor("surface", mSim); CurrentStateMachine.RequestState(yield: true, "x", "Talk", DriverRequestFlags.kQuickExit); return true; } mSim.LoopIdle(); } return false; } public override bool GroupTalkStartListening() { if (SimCanUseSofaChats) { if (SimIsTalkingToOtherSim) { BridgeOrigin bridgeOrigin = mSim.BridgeOrigin; if (bridgeOrigin != null) { mSim.BridgeOrigin = null; bridgeOrigin.MakeOrSkipRequest(yield: true, CurrentStateMachine); } CurrentStateMachine.SetActor("sitTemplate", mContainer); CurrentStateMachine.SetActor("seatOrigin", mContainer); CurrentStateMachine.SetActor("surface", mSim); CurrentStateMachine.RequestState("x", "Listen"); } else { mSim.LoopIdle(); } } return false; } public override bool GroupTalkPlayResponse(ReactionTypes response) { if (SimCanUseSofaChats && SimIsTalkingToOtherSim) { return true; } return false; } public override void GroupTalkStopTalking() { if (!SimCanUseSofaChats) { return; } if (SimIsTalkingToOtherSim) { BridgeOrigin bridgeOrigin = mSim.BridgeOrigin; if (bridgeOrigin != null) { mSim.BridgeOrigin = null; bridgeOrigin.MakeOrSkipRequest(yield: true, CurrentStateMachine); } CurrentStateMachine.SetActor("sitTemplate", mContainer); CurrentStateMachine.SetActor("seatOrigin", mContainer); CurrentStateMachine.SetActor("surface", mSim); CurrentStateMachine.RequestState("x", "Listen"); } else { mSim.LoopIdle(); } } public override void GroupTalkStopListening() { if (SimCanUseSofaChats && !SimIsTalkingToOtherSim) { mSim.LoopIdle(); } } }
Edit: Looks like I've fixed this at least in the one case I was testing - problem was with the values I'd given to my new posture precondition entries when I was making the ITUN edits (0 when they should have been 1), and then with the combination of the commodities I'd set InWheelchairPosture to satisfy and the interaction I was using to test it (I was testing by having the sim watch TV, and that interaction assumes the sim is in SittingPosture if their posture satisfies the Sitting commodity kind, which was causing a null value error here. So solution was to either derive InWheelchairPosture from SittingPosture, or make InWheelchairPosture not satisfy Sitting).
#2
31st Jul 2022 at 1:12 PM

I've now got the posture and a super rudimentary custom walkstyle down (it's a new walkstyle, which I'll put notes on how to make in another post once I'm more confident it works, but it just uses the same walking animations as the original walkstyle it copied for now because I had some animation difficulties that I will also ask about later) so I'm now working on getting the sim in the wheelchair to 1) route properly and 2) take the chair with them when they do. Right now, the sim routes to their destination but leaves the chair behind; and then when they reach where they were going, they disappear, and reappear sitting in the chair again. But then focusing the camera on that sim focuses on the spot they routed to, not where it looks like they are; and when I cancel the InWheelChair posture, the sim shoots across the ground as soon as they finish the standing-up animation, to stand in the spot they routed to.
Has anyone seen this before?
Has anyone seen this before?
Who Posted
|