- Site Map >
- Modding and Creation >
- Sims 3 Creation >
- Modding Discussion >
- Problem with coding and definitions
- Site Map >
- Modding and Creation >
- Sims 3 Creation >
- Modding Discussion >
- Problem with coding and definitions
Replies: 18 (Who?), Viewed: 994 times.
#1
4th Oct 2020 at 5:54 PM
Posts: 175
Thanks: 175 in 1 Posts
Problem with coding and definitions
So... As I think some of you know, I'm working on my second mod, basically something that would allow every occult type and sims from the Young Adult Age to the Adult to also use the canes from Generations. Battery has been of great help to me, and thanks to him, I'm on the last stages of development of this mod. It works basically by overwriting the interactions and code of the cane with versions that allow for Young Adults or Above to use them.However, I ran into a certain problem. There's these two lines of code that give me errors:
Code:
this.mCane = this.Actor.GetActiveCane() ?? this.Actor.Inventory.Find<CyrusCane>();
Code:
this.mCane = this.Actor.GetActiveCane() ?? this.Actor.Inventory.Find<CyrusCane>();
Those, respectively, are lines 745 and and 152 from the code I've been developing. I have tried to use the mod without these lines, but the game just crashes when I try to purchase a cane from Buy Mode. I think the exact problem lies in the "GetActiveCane" thingie, that points to something in Sims3.Gameplay.Actors.Sim. How could I solve this problem?
To see the errors in context, here's the complete code:
Code:
using Sims3.Gameplay.Abstracts; using Sims3.Gameplay.Actors; using Sims3.Gameplay.ActorSystems; using Sims3.Gameplay.Autonomy; using Sims3.Gameplay.CAS; using Sims3.Gameplay.Core; using Sims3.Gameplay.EventSystem; using Sims3.Gameplay.Interactions; using Sims3.Gameplay.Interfaces; using Sims3.Gameplay.ObjectComponents; using Sims3.Gameplay.Pools; using Sims3.Gameplay.Skills; using Sims3.Gameplay.Socializing; using Sims3.Gameplay.ThoughtBalloons; using Sims3.Gameplay.Utilities; using Sims3.SimIFace; using Sims3.SimIFace.CustomContent; using Sims3.SimIFace.Enums; using Sims3.UI.Hud; using System; using System.Collections.Generic; using Sims3.Gameplay.Objects; namespace Cyrus.Sims3Game.CanesForEveryone { public class CyrusCane : Sims3.Gameplay.Objects.Cane { new public static bool IsAllowedToUseCane(Sim sim) { return sim.SimDescription.YoungAdultOrAbove; } public override string PropCaneName { get { return "accessoryCaneLlama"; } } new private sealed class UseCane : ImmediateInteraction<Sim, CyrusCane> { public static readonly InteractionDefinition Singleton = (InteractionDefinition)new CyrusCane.UseCane.Definition(); public override bool RunFromInventory() { if (this.Target.UsingCane) { if (this.Actor.Posture is CyrusCane.HoldingCanePosture) { if (!this.Actor.InteractionQueue.HasInteractionOfTypeAndTarget(CyrusCane.StopUsingCane.Singleton, (GameObject)this.Target)) { InteractionInstance instance = CyrusCane.StopUsingCane.Singleton.CreateInstance((IGameObject)this.Target, (IActor)this.Actor, new InteractionPriority(InteractionPriorityLevel.UserDirected), false, true); instance.Hidden = true; this.Actor.InteractionQueue.PushAsContinuation(instance, true); } } else this.Target.UsingCane = false; } else if (this.Actor.Posture is CyrusCane.HoldingCanePosture || this.Actor.Posture == this.Actor.Standing) { if (!this.Actor.InteractionQueue.HasInteractionOfTypeAndTarget(CyrusCane.StartUsingCane.Singleton, (GameObject)this.Target)) { InteractionInstance instance = CyrusCane.StartUsingCane.Singleton.CreateInstance((IGameObject)this.Target, (IActor)this.Actor, new InteractionPriority(InteractionPriorityLevel.UserDirected), false, true); instance.Hidden = true; this.Actor.InteractionQueue.PushAsContinuation(instance, true); } } else this.Target.UsingCane = true; return true; } [DoesntRequireTuning] private sealed class Definition : ImmediateInteractionDefinition<Sim, CyrusCane, CyrusCane.UseCane> { public override string GetInteractionName( Sim a, CyrusCane target, InteractionObjectPair interaction) { return target.UsingCane ? CyrusCane.LocalizeString(a.IsFemale, "StopUsingCane") : CyrusCane.LocalizeString(a.IsFemale, "StartUsingCane"); } public override bool Test( Sim a, CyrusCane target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback) { if (!Cane.IsAllowedToUseCane(a)) return false; if (a.SimDescription.YoungAdultOrAbove) return true; greyedOutTooltipCallback = InteractionInstance.CreateTooltipCallback(CyrusCane.LocalizeString((a.IsFemale ? 1 : 0) != 0, "AgeRestriction", (object)a)); return false; } } } new public sealed class HarassEveryone : TerrainInteraction, IRouteFromInventoryOrSelfWithoutCarrying { [Tunable] [TunableComment("Distance away from the cane that the sim will route to in order to pick it up.")] private static float kHarassEveryoneObjectSearchRadius = 5f; [TunableComment("Distance away from a random object the sim will route to in order to 'harass' it.")] [Tunable] private static float[] kHarassEveryoneObjectRouteRadiusRange = new float[2] { 0.5f, 3f }; [TunableComment("Chance a sim will harass a random object within the radius.")] [Tunable] private static float kChanceToHarassObject = 0.7f; public static readonly InteractionDefinition Singleton = (InteractionDefinition)new CyrusCane.HarassEveryone.Definition(); public CyrusCane mCane; public override ThumbnailKey GetIconKey() { return this.Actor.GetThumbnailKey(); } public override bool Run() { GameObject gameObject1 = (GameObject)null; if (RandomUtil.RandomChance01(CyrusCane.HarassEveryone.kChanceToHarassObject)) { LotLocation invalid = LotLocation.Invalid; int roomId = (int)World.GetRoomId(World.GetLotLocation(this.Destination, ref invalid), invalid); GameObject[] objects = Sims3.Gameplay.Queries.GetObjects<GameObject>(this.Destination, CyrusCane.HarassEveryone.kHarassEveryoneObjectSearchRadius); List<GameObject> randomList = new List<GameObject>(); foreach (GameObject gameObject2 in objects) { if (gameObject2.RoomId == roomId && !gameObject2.InUse && gameObject2 != this.Actor) randomList.Add(gameObject2); } if (randomList.Count > 0) gameObject1 = RandomUtil.GetRandomObjectFromList<GameObject>(randomList); } Route route = this.Actor.CreateRoute(); route.PlanToPointRadialRange(this.Destination, CyrusCane.HarassEveryone.kHarassEveryoneObjectRouteRadiusRange[0], CyrusCane.HarassEveryone.kHarassEveryoneObjectRouteRadiusRange[1], RouteDistancePreference.PreferNearestToRouteDestination, RouteOrientationPreference.NoPreference, 0UL, (int[])null); if (!this.Actor.DoRoute(route)) return false; if (gameObject1 != null) this.Actor.RouteTurnToFace(gameObject1.Position); else this.Actor.RouteTurnToFace(this.Destination + RandomUtil.GetRandomDirXZ()); if (this.Actor.Posture is SwimmingInPool) { this.Actor.PlayRouteFailure(); return false; } this.mCane = this.Actor.GetActiveCane() ?? this.Actor.Inventory.Find<CyrusCane>(); if (this.mCane == null) return false; this.mCane.CreatePropCane(); this.StandardEntry(); this.BeginCommodityUpdates(); this.EnterStateMachine("ElderCane", "Enter", "x"); this.SetActor(nameof(CyrusCane), (IHasScriptProxy)this.mCane.PropCane); this.mCurrentStateMachine.AddOneShotStateEnteredEventHandler("Harass Everyone", new SacsEventHandler(this.FadePropCaneIn)); if (!(this.Actor.Posture is CyrusCane.HoldingCanePosture)) this.mCurrentStateMachine.AddOneShotStateEnteredEventHandler("Exit", new SacsEventHandler(this.FadePropCaneOut)); if (gameObject1 != null) this.Actor.ThoughtBalloonManager.ShowBalloon(new ThoughtBalloonManager.BalloonData(gameObject1.GetThoughtBalloonThumbnailKey()) { BalloonType = ThoughtBalloonTypes.kThoughtBalloon, Duration = ThoughtBalloonDuration.Short, LowAxis = ThoughtBalloonAxis.kDislike }); this.AnimateSim("Harass Everyone"); EventTracker.SendEvent(EventTypeId.kHarassWithCane, (IActor)this.Actor); this.AnimateSim("Exit"); this.EndCommodityUpdates(true); this.StandardExit(); return true; } public override void Cleanup() { if (this.mCane != null && this.mCane != this.Actor.GetActiveCane()) this.mCane.DestroyPropCane(); base.Cleanup(); } private void FadePropCaneIn(StateMachineClient smc, IEvent evt) { this.mCane.PropCane.FadeIn(); } private void FadePropCaneOut(StateMachineClient smc, IEvent evt) { if (this.mCane.PropCane == null) return; this.mCane.PropCane.FadeOut(false, false); } private sealed class Definition : InteractionDefinition<Sim, Terrain, CyrusCane.HarassEveryone> { public override bool Test( Sim a, Terrain target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback) { return !(a.Posture is SwimmingInPool) && CyrusCane.IsAllowedToUseCane(a) && a.Inventory.FindAll<CyrusCane>(false).Count > 0; } public override InteractionTestResult Test( ref InteractionInstanceParameters parameters, ref GreyedOutTooltipCallback greyedOutTooltipCallback) { if (parameters.Hit.mType != GameObjectHitType.Terrain && parameters.Hit.mType != GameObjectHitType.LotTerrain && parameters.Hit.mType != GameObjectHitType.Object) return InteractionTestResult.Gen_BadTerrainType; InteractionTestResult interactionTestResult = base.Test(ref parameters, ref greyedOutTooltipCallback); if (interactionTestResult != InteractionTestResult.Pass) return interactionTestResult; if (!Terrain.GoHere.SharedGoHereTests(ref parameters)) return InteractionTestResult.GenericFail; Vector3 mPoint = parameters.Hit.mPoint; return parameters.Actor.CreateRoute().IsPointRoutable(parameters.Hit.mPoint) && !World.IsInPool(mPoint) ? InteractionTestResult.Pass : InteractionTestResult.GenericFail; } } } new public class HoldingCanePosture : Posture, IDisposable, IHaveCustomTransitionForNullPosturePreconditions { private Sim mActor; private Cane mCane; private bool mIsExiting; private HoldingCanePosture() { } public HoldingCanePosture(Sim actor, Cane cane, StateMachineClient smc) : base(smc) { this.mActor = actor; this.mCane = cane; this.mCane.UsingCane = true; this.mCane.AddToUseList(this.mActor); this.mActor.SimRoutingComponent.OnRouteActionsFinished -= new RoutingComponent.RouteActionsFinishedDelegate(this.OnSimRouteActionsFinished); this.mActor.SimRoutingComponent.OnRouteActionsFinished += new RoutingComponent.RouteActionsFinishedDelegate(this.OnSimRouteActionsFinished); this.mCane.CreatePropCane(); this.mCane.PropCane.ParentToSlot((IGameObject)this.mActor, Sim.ContainmentSlots.LeftHand); smc.SetActor("x", (IHasScriptProxy)this.mActor); smc.SetActor(nameof(Cane), (IHasScriptProxy)this.mCane.PropCane); smc.EnterState("x", "Enter"); smc.AddOneShotStateEnteredEventHandler("Loop", new SacsEventHandler(this.OnAnimationEvent)); smc.AddSynchronousOneShotScriptEventHandler(101U, new SacsEventHandler(this.OnAnimationEvent)); smc.AddSynchronousOneShotScriptEventHandler(102U, new SacsEventHandler(this.OnAnimationEvent)); } private void OnAnimationEvent(StateMachineClient smc, IEvent evt) { if (evt.EventId == 101U || evt.EventSubType == 3U) { this.mCane.PropCane.FadeIn(); } else { if (evt.EventId != 102U) return; this.mCane.PropCane.FadeOut(false, false); } } public void OnSimRouteActionsFinished(GameObject routingObject, bool routeSuccess) { InteractionInstance headInteraction = this.mActor.InteractionQueue.GetHeadInteraction(); InteractionInstance transitionInteraction = this.mActor.InteractionQueue.TransitionInteraction; if (this.mActor.Posture is CyrusCane.HoldingCanePosture) { switch (headInteraction) { case null: case Terrain.GoHere _: case CyrusCane.TraitHarassWithCane _: case CyrusCane.HarassEveryone _: case SocialInteraction _: break; default: goto label_3; } } if (!(headInteraction is IPopCanePostureOnInteractionRouteEnd) && !(transitionInteraction is IPopCanePostureOnInteractionRouteEnd)) return; label_3: if (this.mActor.HasExitReason()) return; this.mActor.PopPosture(); } public bool IsExiting { get { return this.mIsExiting; } } public override bool PerformIdleLogic { get { return false; } } public override bool AllowsReactionOverlay() { return false; } public override bool AllowsNormalSocials() { return true; } public override bool AllowsRouting() { return this.mActor.SimDescription.ToddlerOrAbove; } public override IGameObject Container { get { return (IGameObject)this.mActor; } } public override string Name { get { return Localization.LocalizeString(this.mActor.IsFemale, "Gameplay/Actors/Postures:HoldingCane"); } } public override bool Implicit { get { return !CyrusCane.kDebug; } } public override void PopulateInteractions() { } public override float Satisfaction(CommodityKind condition, IGameObject target) { switch (condition) { case CommodityKind.Standing: return 1f; case CommodityKind.HoldingCane: return 1f; case CommodityKind.TargetInInventory: return 1f; case CommodityKind.PreferIfCurrentPosture: return this.mActor.Posture is CyrusCane.HoldingCanePosture ? 1f : 0.0f; default: return 0.0f; } } public override bool Satisfies( PreconditionOptions options, IGameObject target, CommodityKind requiredCheck) { return options == null && requiredCheck == CommodityKind.None || base.Satisfies(options, target, requiredCheck); } public override InteractionInstance GetTransition( InteractionInstance interaction) { if (interaction.Target == this.mActor && !(interaction is IRouteFromInventoryOrSelfWithoutCarrying)) return this.GetStandingTransition(); return interaction.PosturePreconditions == null ? (InteractionInstance)null : Posture.FindTransitionInteraction(interaction, CommodityKind.None); } public override BridgeOrigin Idle() { base.Idle(); this.CurrentStateMachine.SetParameter("RestrictCaneIdles", false); GameObject objectOutOfWorld = Sims3.Gameplay.GlobalFunctions.CreateObjectOutOfWorld("elderCaneIdle_Jig", ProductVersion.EP4) as GameObject; this.mActor.SetHiddenFlags(HiddenFlags.Everything); if (!World.TestObjectPlacement(objectOutOfWorld.ObjectId, TestObjectPlacementBooleans.TemporaryPlacement, this.mActor.Position, this.mActor.ForwardVector)) this.CurrentStateMachine.SetParameter("RestrictCaneIdles", true); this.mActor.SetHiddenFlags(HiddenFlags.Nothing); objectOutOfWorld.Destroy(); this.CurrentStateMachine.RequestState("x", "Loop"); return new BridgeOrigin(this.CurrentStateMachine, "x", new string[1] { "HoldCane" }); } public override InteractionInstance GetStandingTransition() { CyrusCane.StopUsingCane instance = CyrusCane.StopUsingCane.Singleton.CreateInstance((IGameObject)this.mCane, (IActor)this.mActor, this.mActor.InheritedPriority(), false, true) as CyrusCane.StopUsingCane; instance.UnsetUsingCane = false; return (InteractionInstance)instance; } public override ScriptPosture GetSacsPostureParameter() { return ScriptPosture.Standing; } public override Posture OnReset(IGameObject objectBeingReset) { this.CleanUpPosture(); return (Posture)null; } public override void OnExitPosture() { if (this.mIsExiting) return; this.mIsExiting = true; if (this.CurrentStateMachine != null) this.CurrentStateMachine.RequestState(true, "x", "Exit"); this.CleanUpPosture(); } public override void Shoo(bool yield, List<Sim> shooedSims) { throw new Exception("The method or operation is not implemented."); } private void CleanUpPosture() { if (this.mCane.IsActorUsingMe(this.mActor)) this.mCane.RemoveFromUseList(this.mActor); this.mCane.DestroyPropCane(); if (this.CurrentStateMachine != null) { this.CurrentStateMachine.RemoveAllEventHandlers(); this.CurrentStateMachine.Dispose(); this.CurrentStateMachine = (StateMachineClient)null; } if (this.mActor.SimRoutingComponent == null) return; this.mActor.SimRoutingComponent.OnRouteActionsFinished -= new RoutingComponent.RouteActionsFinishedDelegate(this.OnSimRouteActionsFinished); } public override string ToString() { return "Holding Cane Posture"; } ~HoldingCanePosture() { this.Dispose(true); } public void Dispose() { this.Dispose(false); } private void Dispose(bool fromDtor) { if (this.CurrentStateMachine != null) { this.CurrentStateMachine.RemoveAllEventHandlers(); this.CurrentStateMachine.Dispose(); this.CurrentStateMachine = (StateMachineClient)null; } if (this.mActor.SimRoutingComponent != null) this.mActor.SimRoutingComponent.OnRouteActionsFinished -= new RoutingComponent.RouteActionsFinishedDelegate(this.OnSimRouteActionsFinished); if (fromDtor) return; GC.SuppressFinalize((object)this); } } new private sealed class SetWalkStyle : ImmediateInteraction<Sim, CyrusCane> { public static readonly InteractionDefinition Singleton = (InteractionDefinition)new CyrusCane.SetWalkStyle.Definition(); public override bool RunFromInventory() { this.Target.CurrentCaneWalkStyle = (this.InteractionDefinition as CyrusCane.SetWalkStyle.Definition).CaneWalkStyle; return true; } [DoesntRequireTuning] private sealed class Definition : ImmediateInteractionDefinition<Sim, CyrusCane, CyrusCane.SetWalkStyle> { public Sim.WalkStyle CaneWalkStyle; public Definition() { } public Definition(Sim.WalkStyle walkStyle) { this.CaneWalkStyle = walkStyle; } public override string GetInteractionName( Sim a, CyrusCane target, InteractionObjectPair interaction) { return this.CaneWalkStyle == CyrusCane.kSouthernGentlemanCaneWalk ? CyrusCane.LocalizeString(a.IsFemale, "SouthernGentleman") : Cane.LocalizeString(a.IsFemale, "Elderly"); } public override string[] GetPath(bool isFemale) { return new string[1] { CyrusCane.LocalizeString(isFemale, nameof (SetWalkStyle)) }; } public override bool Test( Sim a, CyrusCane target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback) { if (!Cane.IsAllowedToUseCane(a)) return false; if (!a.SimDescription.Elder) { greyedOutTooltipCallback = InteractionInstance.CreateTooltipCallback(CyrusCane.LocalizeString((a.IsFemale ? 1 : 0) != 0, "AgeRestriction", (object)a)); return false; } if (this.CaneWalkStyle != target.CurrentCaneWalkStyle) return true; greyedOutTooltipCallback = InteractionInstance.CreateTooltipCallback(CyrusCane.LocalizeString((a.IsFemale ? 1 : 0) != 0, "WalkStyleInUse", (object)a)); return false; } public override void AddInteractions( InteractionObjectPair iop, Sim actor, CyrusCane target, List<InteractionObjectPair> results) { CyrusCane.SetWalkStyle.Definition definition1 = new CyrusCane.SetWalkStyle.Definition(CyrusCane.kSouthernGentlemanCaneWalk); results.Add(new InteractionObjectPair((InteractionDefinition)definition1, (IGameObject)target)); CyrusCane.SetWalkStyle.Definition definition2 = new CyrusCane.SetWalkStyle.Definition(CyrusCane.kElderlyCaneWalk); results.Add(new InteractionObjectPair((InteractionDefinition)definition2, (IGameObject)target)); } } } new public sealed class StartUsingCane : Interaction<Sim, CyrusCane> { public static readonly InteractionDefinition Singleton = (InteractionDefinition)new CyrusCane.StartUsingCane.Definition(); public override bool RunFromInventory() { this.StandardEntry(false); this.BeginCommodityUpdates(); CyrusCane.StopUsingAnyActiveCanes(this.Actor); if (!(this.Actor.Posture is CyrusCane.HoldingCanePosture)) { this.Actor.Posture = (Posture)new CyrusCane.HoldingCanePosture(this.Actor, this.Target, StateMachineClient.Acquire((IHasScriptProxy)this.Actor, "ElderCane")); this.Actor.Posture.CurrentStateMachine.RequestState("x", "Pull Out Cane"); } this.EndCommodityUpdates(true); this.StandardExit(false, false); return true; } private sealed class Definition : InteractionDefinition<Sim, CyrusCane, CyrusCane.StartUsingCane> { public override bool Test( Sim a, CyrusCane target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback) { return true; } } } new public sealed class StopUsingCane : Interaction<Sim, CyrusCane> { public static readonly InteractionDefinition Singleton = (InteractionDefinition)new CyrusCane.StopUsingCane.Definition(); public bool UnsetUsingCane = true; public override bool RunFromInventory() { this.StandardEntry(false); this.BeginCommodityUpdates(); if (this.UnsetUsingCane) { CyrusCane.StopUsingAnyActiveCanes(this.Actor); this.Target.UsingCane = false; } else this.Actor.PopCanePostureIfNecessary(); this.EndCommodityUpdates(true); this.StandardExit(false, false); return true; } private sealed class Definition : InteractionDefinition<Sim, CyrusCane, CyrusCane.StopUsingCane> { public override bool Test( Sim a, CyrusCane target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback) { return true; } } } new public sealed class TraitHarassWithCane : Interaction<Sim, Sim>, IRouteFromInventoryOrSelfWithoutCarrying { private static TraitNames[] HarassTraits = new TraitNames[10] { TraitNames.Grumpy, TraitNames.Evil, TraitNames.MeanSpirited, TraitNames.Insane, TraitNames.HatesOutdoors, TraitNames.DislikesChildren, TraitNames.CantStandArt, TraitNames.Frugal, TraitNames.AntiTV, TraitNames.Neat }; [Tunable] [TunableComment("Value threshold of objects that a frugal sim will harass. Threshold is randomly chosen between these two values each time the interaction is run. If the value of an object is greater than the threshold, the sim will route over an complain about it.")] private static int[] kFrugalValueThreshold = new int[2] { 500, 1000 }; [TunableComment("Objects within this radius of the sim will be selected for the sim to complain about.")] [Tunable] private static float kObjectSearchRadius = 20f; [Tunable] [TunableComment("Radial route min/max that the sim will try to route to if the find good location route fails.")] private static float[] kObjectFallbackRouteRadius = new float[2] { 0.0f, 5f }; public static readonly ISoloInteractionDefinition Singleton = (ISoloInteractionDefinition)new CyrusCane.TraitHarassWithCane.Definition(); private string mIcon = string.Empty; private CyrusCane mCane; private GameObject mHarassmentObject; public override void ConfigureInteraction() { List<TraitNames> randomList1 = new List<TraitNames>(); foreach (TraitNames harassTrait in CyrusCane.TraitHarassWithCane.HarassTraits) { if (this.Actor.TraitManager.HasElement(harassTrait)) randomList1.Add(harassTrait); } if (randomList1.Count == 0) return; GameObject[] objects = Sims3.Gameplay.Queries.GetObjects<GameObject>(this.Actor.Position, CyrusCane.TraitHarassWithCane.kObjectSearchRadius); List<GameObject> randomList2 = new List<GameObject>(); CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction objectCheckFunction = (CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction)null; switch (RandomUtil.GetRandomObjectFromList<TraitNames>(randomList1)) { case TraitNames.AntiTV: objectCheckFunction = new CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction(this.AntiTVCheck); this.mIcon = "TraitGenius"; break; case TraitNames.CantStandArt: objectCheckFunction = new CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction(this.CantStandArtCheck); this.mIcon = "Art"; break; case TraitNames.DislikesChildren: objectCheckFunction = new CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction(this.DislikesChildrenCheck); this.mIcon = "TraitDislikesChildren"; break; case TraitNames.MeanSpirited: case TraitNames.Evil: case TraitNames.Grumpy: objectCheckFunction = new CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction(this.IsSimCheck); this.mIcon = "Random"; break; case TraitNames.Frugal: objectCheckFunction = new CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction(this.FrugalCheck); this.mIcon = "TraitFrugal"; break; case TraitNames.HatesOutdoors: objectCheckFunction = new CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction(this.HatesOutdoorsCheck); this.mIcon = "Great Outdoors"; break; case TraitNames.Insane: objectCheckFunction = new CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction(this.HatesOutdoorsCheck); this.mIcon = "Talk About Conspiracies"; break; case TraitNames.Neat: objectCheckFunction = new CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction(this.NeatCheck); this.mIcon = "Insult"; break; } foreach (GameObject gameObject in objects) { if (objectCheckFunction(gameObject) && this.Actor.IsGreetedOnLot(gameObject.LotCurrent)) randomList2.Add(gameObject); } this.mHarassmentObject = (GameObject)this.Actor; if (randomList2.Count <= 0) return; this.mHarassmentObject = RandomUtil.GetRandomObjectFromList<GameObject>(randomList2); } public override ThumbnailKey GetIconKey() { return this.mHarassmentObject != null ? this.mHarassmentObject.GetThumbnailKey() : base.GetIconKey(); } public override bool Run() { if (this.mHarassmentObject == null) return false; World.FindGoodLocationParams fglParams = new World.FindGoodLocationParams(this.mHarassmentObject.Position); fglParams.StartPosition = this.mHarassmentObject.Position; fglParams.RequiredRoomID = this.mHarassmentObject.RoomId; bool flag = false; Vector3 pos; if (Sims3.Gameplay.GlobalFunctions.FindGoodLocation((IGameObject)this.Actor, fglParams, out pos, out Vector3 _)) { Route route = this.Actor.CreateRoute(); route.PlanToPoint(pos); route.DoRouteFail = false; flag = this.Actor.DoRoute(route); } if (!flag) this.Actor.RouteToDynamicObjectRadiusWithCondition((IGameObject)this.mHarassmentObject, CyrusCane.TraitHarassWithCane.kObjectFallbackRouteRadius[0], Cane.TraitHarassWithCane.kObjectFallbackRouteRadius[1], (RouteCallback)null, (RouteCallbackCondition)null, Route.RouteOption.DoLineOfSightCheckUserOverride); this.Actor.RouteTurnToFace(this.mHarassmentObject.Position); if (this.Actor.Posture is SwimmingInPool) { this.Actor.PlayRouteFailure(); return false; } this.mCane = this.Actor.GetActiveCane() ?? this.Actor.Inventory.Find<CyrusCane>(); if (this.mCane == null) return false; if (!this.mCane.UsingCane) this.mCane.AddToUseList(this.Actor); this.mCane.CreatePropCane(); this.StandardEntry(); this.BeginCommodityUpdates(); this.EnterStateMachine("ElderCane", "Enter", "x"); this.SetActor(nameof(CyrusCane), (IHasScriptProxy)this.mCane.PropCane); this.mCurrentStateMachine.AddOneShotStateEnteredEventHandler("Harass Everyone", new SacsEventHandler(this.FadePropCaneIn)); if (!(this.Actor.Posture is CyrusCane.HoldingCanePosture)) this.mCurrentStateMachine.AddOneShotStateEnteredEventHandler("Exit", new SacsEventHandler(this.FadePropCaneOut)); ThoughtBalloonManager.BalloonData balloonData = ThoughtBalloonManager.GetBalloonData(this.mIcon, this.Actor); balloonData.BalloonType = ThoughtBalloonTypes.kThoughtBalloon; balloonData.LowAxis = ThoughtBalloonAxis.kDislike; balloonData.Duration = ThoughtBalloonDuration.Short; this.Actor.ThoughtBalloonManager.ShowBalloon(balloonData); this.AnimateSim("Harass Everyone"); this.AnimateSim("Exit"); this.EndCommodityUpdates(true); this.StandardExit(); return true; } public override void Cleanup() { if (this.mCane != null) { if (this.mCane.IsActorUsingMe(this.Actor) && !this.mCane.UsingCane) this.mCane.RemoveFromUseList(this.Actor); if (this.mCane != this.Actor.GetActiveCane()) this.mCane.DestroyPropCane(); } base.Cleanup(); } private void FadePropCaneIn(StateMachineClient smc, IEvent evt) { this.mCane.PropCane.FadeIn(); } private void FadePropCaneOut(StateMachineClient smc, IEvent evt) { if (this.mCane.PropCane == null) return; this.mCane.PropCane.FadeOut(false, false); } private bool IsSimCheck(GameObject obj) { return obj is Sim; } private bool HatesOutdoorsCheck(GameObject obj) { return obj.IsOutside && !obj.InUse && obj != this.Actor; } private bool DislikesChildrenCheck(GameObject obj) { return obj is Sim sim && sim.IsHuman && (sim.SimDescription.IsPregnant || sim.SimDescription.ChildOrBelow) && obj != this.Actor; } private bool CantStandArtCheck(GameObject obj) { switch (obj) { case IPainting _: case ISculpture _: return true; default: return obj is IPhotograph; } } private bool FrugalCheck(GameObject obj) { int num = RandomUtil.GetInt(CyrusCane.TraitHarassWithCane.kFrugalValueThreshold[0], CyrusCane.TraitHarassWithCane.kFrugalValueThreshold[1]); return obj.Value >= num; } private bool AntiTVCheck(GameObject obj) { switch (obj) { case ITelevision _: case IComputer _: return true; default: return obj is IStereo; } } private bool NeatCheck(GameObject obj) { if (obj is Sim sim) { if (sim.BuffManager.HasAnyElement(BuffNames.Smelly, BuffNames.Grungy)) return true; } CleanableComponent cleanable = obj.Cleanable; return cleanable != null && cleanable.VisuallyDirty; } public delegate bool HarassObjectCheckFunction(GameObject obj); private sealed class Definition : SoloSimInteractionDefinition<CyrusCane.TraitHarassWithCane> { public override bool Test( Sim a, Sim target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback) { return CyrusCane.IsAllowedToUseCane(a) && a.Inventory.ContainsType(typeof(CyrusCane), 1) && a.TraitManager.HasAnyElement(CyrusCane.TraitHarassWithCane.HarassTraits); } } } } }
Advertisement
#2
5th Oct 2020 at 2:57 PM
Posts: 562
Thanks: 3599 in 11 Posts
If you at the code for GetActiveCane, it actually returns a Cane object. And I think from what I understand of your project, you have actually made a new object CyrusCane:
Code:
So I think the best thing to do, would be to create a new GetActiveCane() function that will do exactly the same thing, but instead of using Cane, it will use CyrusCane. So it will return a CyrusCane type instead of Cane, and it will look for CyrusCanes in the Inventory too. Hopefully the item.UsingCane will be fine, because your CyrusCane object should have inherited that from the Cane, though I could be wrong :P
public Cane GetActiveCane() { if (base.Inventory != null) { List<Cane> list = base.Inventory.FindAll<Cane>(checkInUse: false); foreach (Cane item in list) { if (item.UsingCane) { return item; } } } return null; }
#3
5th Oct 2020 at 7:12 PM
Last edited by CyrusBanefort : 5th Oct 2020 at 8:23 PM.
Posts: 175
Thanks: 175 in 1 Posts
Quote: Originally posted by zoe22
If you at the code for GetActiveCane, it actually returns a Cane object. And I think from what I understand of your project, you have actually made a new object CyrusCane:
Code:
So I think the best thing to do, would be to create a new GetActiveCane() function that will do exactly the same thing, but instead of using Cane, it will use CyrusCane. So it will return a CyrusCane type instead of Cane, and it will look for CyrusCanes in the Inventory too. Hopefully the item.UsingCane will be fine, because your CyrusCane object should have inherited that from the Cane, though I could be wrong :P
public Cane GetActiveCane() { if (base.Inventory != null) { List<Cane> list = base.Inventory.FindAll<Cane>(checkInUse: false); foreach (Cane item in list) { if (item.UsingCane) { return item; } } } return null; } |
@zoe22 ,
That's what I'm trying to do currently. However, I'm also having problems with this. In a nutshell, what happens is that I paste the code, I get this error:
CS1061 'CyrusGetActiveCane' does not contain a definition for "Inventory" and no accessible extension method "Inventory" accepting a first argument of type 'CyrusGetActiveCane' could be found (are you missing a using directive or an assembly reference?)
When I try to use the entire thing's name found on IlSpy, I get this.
CS1061 'CyrusGetActiveCane' does not contain a definition for "Sims3" and no accessible extension method "Sims3" accepting a first argument of type 'CyrusGetActiveCane' could be found (are you missing a using directive or an assembly reference?)
Here's the original code:
Code:
public Cane GetActiveCane() { if (this.Inventory != null) { foreach (Cane cane in this.Inventory.FindAll<Cane>(false)) { if (cane.UsingCane) return cane; } } return (Cane) null; }
And here's my code:
Code:
using System; using System.Collections.Generic; using System.Text; using Sims3.Gameplay.Objects; using Sims3.Gameplay.Abstracts; using static Sims3.Gameplay.Abstracts.GameObject; using Sims3.Gameplay; namespace Cyrus.Sims3Game.CanesForEveryone { public class CyrusGetActiveCane { public CyrusCane GetActiveCane() { if (this.Inventory != null) { foreach (Cane cane in this.Inventory.FindAll<Cane>(false)) { if (cane.UsingCane) return cane; } } return (CyrusCane)null; } } }
EDIT: I also tried to do the following:
Code:
namespace Cyrus.Sims3Game.CanesForEveryone { public class CyrusGetActiveCane { public CyrusCane GetActiveCane() { if (GameObject.Inventory != null) { foreach (CyrusCane cane in this.Inventory.FindAll<CyrusCane>(false)) { if (cane.UsingCane) return cane; } } return (CyrusCane)null; } } }
But I get this error:
CS0120 An object reference is required for the non-static field "GameObject.Inventory", method, or property
EDIT 2: Ok, I managed to solve these new errors, but the original one persists even after I made this:
Code:
namespace Cyrus.Sims3Game.CanesForEveryone { public class CyrusGetActiveCane : Sims3.Gameplay.Actors.Sim { public CyrusCane GetActiveCane() { if (this.Inventory != null) { foreach (CyrusCane cane in this.Inventory.FindAll<CyrusCane>(false)) { if (cane.UsingCane) return cane; } } return (CyrusCane)null; } } }
#4
5th Oct 2020 at 8:41 PM
Posts: 562
Thanks: 3599 in 11 Posts
The original GetActiveCane() I think is referring to the Actor sim when it uses this as in this.Inventory, so because your code doesn't have that info, you need to tell it that the Inventory you are looking through is the sim's. So you could use an argument in the function public CyrusCane GetActiveCane(Sim sim), and call it in Run() as GetActiveCane(Actor). Then use sim.Inventory etc in the function.
Also, the object that you are looking for and want to return is a CyrusCane so you'll need to use:
So you would have something like this:
Hope this works!
edit: You might actually need the GetActiveCane class to be static, so it would be public static CyrusCane GetActiveCane(Sim sim). This is because it's not tied to any specific object, it just uses the Sim given and returns any cane that is being used by that sim. Originally the method was actually for the sim itself, which is why it used this.Inventory, as it was part of the Sim class itself.
Sorry if this is just confusing, honestly I don't always understand object oriented programming and static vs non static functions myself :P
But yeah, if you get an error saying it needs to be static, then you can just add that and hopefully it will be fine.
Also, the object that you are looking for and want to return is a CyrusCane so you'll need to use:
Code:
You could also just put the function in your CyrusCane class, rather than having a CyrusGetActiveCane class as well.foreach (CyrusCane cane in this.Inventory.FindAll<CyrusCane>(false))
So you would have something like this:
Code:
//references namespace Cyrus.Sims3Game.CanesForEveryone { public class CyrusCane : Sims3.Gameplay.Objects.Cane { public CyrusCane GetActiveCane(Sim sim) { if (sim.Inventory != null) { foreach (CyrusCane cane in this.Inventory.FindAll<CyrusCane>(false)) { if (cane.UsingCane) return cane; } } return null; } } //rest of CyrusCane code here... }
Hope this works!
edit: You might actually need the GetActiveCane class to be static, so it would be public static CyrusCane GetActiveCane(Sim sim). This is because it's not tied to any specific object, it just uses the Sim given and returns any cane that is being used by that sim. Originally the method was actually for the sim itself, which is why it used this.Inventory, as it was part of the Sim class itself.
Sorry if this is just confusing, honestly I don't always understand object oriented programming and static vs non static functions myself :P
But yeah, if you get an error saying it needs to be static, then you can just add that and hopefully it will be fine.
#5
5th Oct 2020 at 9:30 PM
Posts: 175
Thanks: 175 in 1 Posts
Quote: Originally posted by zoe22
The original GetActiveCane() I think is referring to the Actor sim when it uses this as in this.Inventory, so because your code doesn't have that info, you need to tell it that the Inventory you are looking through is the sim's. So you could use an argument in the function public CyrusCane GetActiveCane(Sim sim), and call it in Run() as GetActiveCane(Actor). Then use sim.Inventory etc in the function. Also, the object that you are looking for and want to return is a CyrusCane so you'll need to use:
Code:
You could also just put the function in your CyrusCane class, rather than having a CyrusGetActiveCane class as well.foreach (CyrusCane cane in this.Inventory.FindAll<CyrusCane>(false)) So you would have something like this:
Code:
//references namespace Cyrus.Sims3Game.CanesForEveryone { public class CyrusCane : Sims3.Gameplay.Objects.Cane { public CyrusCane GetActiveCane(Sim sim) { if (sim.Inventory != null) { foreach (CyrusCane cane in this.Inventory.FindAll<CyrusCane>(false)) { if (cane.UsingCane) return cane; } } return null; } } //rest of CyrusCane code here... } Hope this works! edit: You might actually need the GetActiveCane class to be static, so it would be public static CyrusCane GetActiveCane(Sim sim). This is because it's not tied to any specific object, it just uses the Sim given and returns any cane that is being used by that sim. Originally the method was actually for the sim itself, which is why it used this.Inventory, as it was part of the Sim class itself. Sorry if this is just confusing, honestly I don't always understand object oriented programming and static vs non static functions myself :P But yeah, if you get an error saying it needs to be static, then you can just add that and hopefully it will be fine. |
@zoe22 ,
Thank you very much for your help. How would the changed mCane thing look like? I admit, I'm very new to coding, and most of what I know comes from this site tutorials.
#6
6th Oct 2020 at 12:35 PM
Posts: 562
Thanks: 3599 in 11 Posts
Hmm I think you can leave the mCane as it is, as you have already defined it as a CyrusCane on line 115 here:
Like you did here:
So you might want to word search and find all instances of "this.mCane = " and if there is a case where the thing that is being assigned to this.mCane is a Cane not a CyrusCane, change it to CyrusCane. it looks like it's just HoldingCanePosture that needs to be changed to have a CyrusCane argument rather than a Cane, so:
Though I am thinking if there is an easier way to do this, if you are wanting to completely replace the original cane object. You might be able to create custom versions of all the interactions, and in the definition just change Test() to return true for all types of sims you want. I think you also need to fill in the GetInteractionName function rather than just leaving it, otherwise you will get a blank name on the pie menu. I can't remember if you need to add in the Run() function too and just put base.Run() in it, or if you can leave it and it will do that automatically. But it might be worth a shot if it saves all the code of rewriting every Run() and having the custom object to take into account.
If you did want to try this, you would need to make custom interaction classes derived from the original.
And use some pure modding to replace the original interactions OnPreLoad()
with:
@Battery helped me with this for my plumbing mod
But of course it's up to you, especially as you have come so far with this way, and you might be close to having it work perfectly so *shrug*
Code:
and 652 as well actually. So as long as when you are assigning something to it, what you are assigning is a CyrusCane rather than a Cane object, I think it should be fine.public CyrusCane mCane;
Like you did here:
Code:
The reason I think it wasn't working is because originally this.Actor.GetActiveCane() would return a Cane rather than a CyrusCane, and so once you remake a GetActiveCane function that returns a CyrusCane, you won't have that problem. Though actually if the function is static, you won't need the this next to the GetActiveCane(). this.mCane = this.Actor.GetActiveCane() ?? this.Actor.Inventory.Find<CyrusCane>();
So you might want to word search and find all instances of "this.mCane = " and if there is a case where the thing that is being assigned to this.mCane is a Cane not a CyrusCane, change it to CyrusCane. it looks like it's just HoldingCanePosture that needs to be changed to have a CyrusCane argument rather than a Cane, so:
Code:
And hopefully that will work :ppublic HoldingCanePosture(Sim actor, CyrusCane cane, StateMachineClient smc) ...
Though I am thinking if there is an easier way to do this, if you are wanting to completely replace the original cane object. You might be able to create custom versions of all the interactions, and in the definition just change Test() to return true for all types of sims you want. I think you also need to fill in the GetInteractionName function rather than just leaving it, otherwise you will get a blank name on the pie menu. I can't remember if you need to add in the Run() function too and just put base.Run() in it, or if you can leave it and it will do that automatically. But it might be worth a shot if it saves all the code of rewriting every Run() and having the custom object to take into account.
If you did want to try this, you would need to make custom interaction classes derived from the original.
Code:
public class CustomUseCane : UseCane { public new static readonly InteractionDefinition Singleton = new Definition(); public sealed new class Definition : InteractionDefinition<Sim, Cane, CustomUseCane> { public override string GetInteractionName(Sim a, Cane target, InteractionObjectPair interaction) { return Localization.LocalizeString("...interaction name..."); } public override bool Test(Sim a, Cane target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback) { return true; } } public override bool Run() { base.Run() } }
And use some pure modding to replace the original interactions OnPreLoad()
with:
Code:
That way, you'd just be using the original Cane object and using interactions with definitions that allow more sims to use the canes. And you don't need to mess around with so much code.UseCane.Singleton = new UseCane.Definition();
@Battery helped me with this for my plumbing mod
But of course it's up to you, especially as you have come so far with this way, and you might be close to having it work perfectly so *shrug*
#7
6th Oct 2020 at 3:40 PM
Last edited by CyrusBanefort : 6th Oct 2020 at 3:58 PM.
Posts: 175
Thanks: 175 in 1 Posts
Quote: Originally posted by zoe22
Hmm I think you can leave the mCane as it is, as you have already defined it as a CyrusCane on line 115 here:
Code:
and 652 as well actually. So as long as when you are assigning something to it, what you are assigning is a CyrusCane rather than a Cane object, I think it should be fine.public CyrusCane mCane; Like you did here:
Code:
The reason I think it wasn't working is because originally this.Actor.GetActiveCane() would return a Cane rather than a CyrusCane, and so once you remake a GetActiveCane function that returns a CyrusCane, you won't have that problem. Though actually if the function is static, you won't need the this next to the GetActiveCane(). this.mCane = this.Actor.GetActiveCane() ?? this.Actor.Inventory.Find<CyrusCane>(); So you might want to word search and find all instances of "this.mCane = " and if there is a case where the thing that is being assigned to this.mCane is a Cane not a CyrusCane, change it to CyrusCane. it looks like it's just HoldingCanePosture that needs to be changed to have a CyrusCane argument rather than a Cane, so:
Code:
And hopefully that will work :ppublic HoldingCanePosture(Sim actor, CyrusCane cane, StateMachineClient smc) ... Though I am thinking if there is an easier way to do this, if you are wanting to completely replace the original cane object. You might be able to create custom versions of all the interactions, and in the definition just change Test() to return true for all types of sims you want. I think you also need to fill in the GetInteractionName function rather than just leaving it, otherwise you will get a blank name on the pie menu. I can't remember if you need to add in the Run() function too and just put base.Run() in it, or if you can leave it and it will do that automatically. But it might be worth a shot if it saves all the code of rewriting every Run() and having the custom object to take into account. If you did want to try this, you would need to make custom interaction classes derived from the original.
Code:
public class CustomUseCane : UseCane { public new static readonly InteractionDefinition Singleton = new Definition(); public sealed new class Definition : InteractionDefinition<Sim, Cane, CustomUseCane> { public override string GetInteractionName(Sim a, Cane target, InteractionObjectPair interaction) { return Localization.LocalizeString("...interaction name..."); } public override bool Test(Sim a, Cane target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback) { return true; } } public override bool Run() { base.Run() } } And use some pure modding to replace the original interactions OnPreLoad() with:
Code:
That way, you'd just be using the original Cane object and using interactions with definitions that allow more sims to use the canes. And you don't need to mess around with so much code.UseCane.Singleton = new UseCane.Definition(); @Battery helped me with this for my plumbing mod But of course it's up to you, especially as you have come so far with this way, and you might be close to having it work perfectly so *shrug* |
@zoe22 ,
Yeah, my current problem is that the new GetActiveCane does not appear on VS suggestions - Just the original. I did try to simply replace the interactions im the initial phase of the mod, but errors were also abound.
EDIT: Also, when I try writing this
Code:
this.mCane = CyrusSim.GetActiveCane() ?? this.Actor.Inventory.Find<CyrusCane>();
CyrusSim being the class I put the GetActiveCane under, I get this error, even after turning the GetActiveCane static:
CS0120 C# An object reference is required for the "Sim.GetActiveCane()" non-static field, method, or property
#8
6th Oct 2020 at 4:05 PM
Posts: 562
Thanks: 3599 in 11 Posts
Hmm that's weird that it doesn't like it. You could call it something else and see if that works? Also, you will need to tell the GetActiveCane function what sim it is checking the cane for, so make sure to pass in the Actor sim in there
Space Pony
#9
6th Oct 2020 at 5:14 PM
Posts: 433
Thanks: 792 in 6 Posts
could you attach the *.cs file so that we can get an overview of your code ?
E: since you seem to have "working" code in addition to your codefile the package would be helpful
E: since you seem to have "working" code in addition to your codefile the package would be helpful
#10
6th Oct 2020 at 5:15 PM
Last edited by CyrusBanefort : 7th Oct 2020 at 2:46 AM.
Posts: 175
Thanks: 175 in 1 Posts
@zoe22 ,
Ok, I managed to complete the code. Now, I'm trying to make it actually work in-game.
Basically, my method to replace the interactions and everything is to create a default replacement objk, referencing the CyrusCane class - But (I don't know if it is because of this, or the code, or something completely different) the game keeps crashing when I try to purchase a Llama Cane from Buy Mode. Any idea why? Do I need to create a entirely new object or something?
Here's the (hopefully) final version of the code:
EDIT: Oh wait, I solved it. It was the namespace, my bad for not seeing that part of the tutorial. So... I'm trying to have the interactions to appear, but I'm not managing to do it. What should I do? I even added this:
But the interactions still didn't appear.
Ok, I managed to complete the code. Now, I'm trying to make it actually work in-game.
Basically, my method to replace the interactions and everything is to create a default replacement objk, referencing the CyrusCane class - But (I don't know if it is because of this, or the code, or something completely different) the game keeps crashing when I try to purchase a Llama Cane from Buy Mode. Any idea why? Do I need to create a entirely new object or something?
Here's the (hopefully) final version of the code:
Code:
using Sims3.Gameplay.Abstracts; using Sims3.Gameplay.Actors; using Sims3.Gameplay.ActorSystems; using Sims3.Gameplay.Autonomy; using Sims3.Gameplay.CAS; using Sims3.Gameplay.Core; using Sims3.Gameplay.EventSystem; using Sims3.Gameplay.Interactions; using Sims3.Gameplay.Interfaces; using Sims3.Gameplay.ObjectComponents; using Sims3.Gameplay.Pools; using Sims3.Gameplay.Skills; using Sims3.Gameplay.Socializing; using Sims3.Gameplay.ThoughtBalloons; using Sims3.Gameplay.Utilities; using Sims3.SimIFace; using Sims3.SimIFace.CustomContent; using Sims3.SimIFace.Enums; using Sims3.UI.Hud; using System; using System.Collections.Generic; using Sims3.Gameplay.Objects; namespace Cyrus.Sims3Game.CanesForEveryone { public class CyrusCane : Sims3.Gameplay.Objects.Cane { new public static bool IsAllowedToUseCane(Sim sim) { return sim.SimDescription.YoungAdultOrAbove; } public override string PropCaneName { get { return "accessoryCaneLlama"; } } public class CyrusSim : Sims3.Gameplay.Actors.Sim { public static CyrusCane NewGetActiveCane(Sim sim) { if (sim.Inventory != null) { foreach (CyrusCane cane in sim.Inventory.FindAll<CyrusCane>(false)) { if (cane.UsingCane) return cane; } } return null; } } new public bool UsingCane { get { return this.mUseCane; } set { if (this.mUseCane == value) return; if (this.ItemComp.InventoryParent != null && this.ItemComp.InventoryParent.Owner is Sim owner && owner.SimRoutingComponent != null) { owner.SimRoutingComponent.OnCarSequenceFinished -= new SimRoutingComponent.CarSequenceEvent(Cane.CarSequenceFinishedCallback); if (value) owner.SimRoutingComponent.OnCarSequenceFinished += new SimRoutingComponent.CarSequenceEvent(Cane.CarSequenceFinishedCallback); } this.mUseCane = value; } } new public static CyrusCane GetActiveCaneForActor(Sim sim) { if (sim != null && sim.Inventory != null) { List<CyrusCane> list = sim.Inventory.FindAll<CyrusCane>(checkInUse: false); foreach (CyrusCane item in list) { if (item.UsingCane) { return item; } } } return null; } new private sealed class UseCane : ImmediateInteraction<Sim, CyrusCane> { public static readonly InteractionDefinition Singleton = (InteractionDefinition)new CyrusCane.UseCane.Definition(); public override bool RunFromInventory() { if (this.Target.UsingCane) { if (this.Actor.Posture is CyrusCane.HoldingCanePosture) { if (!this.Actor.InteractionQueue.HasInteractionOfTypeAndTarget(CyrusCane.StopUsingCane.Singleton, (GameObject)this.Target)) { InteractionInstance instance = CyrusCane.StopUsingCane.Singleton.CreateInstance((IGameObject)this.Target, (IActor)this.Actor, new InteractionPriority(InteractionPriorityLevel.UserDirected), false, true); instance.Hidden = true; this.Actor.InteractionQueue.PushAsContinuation(instance, true); } } else this.Target.UsingCane = false; } else if (this.Actor.Posture is CyrusCane.HoldingCanePosture || this.Actor.Posture == this.Actor.Standing) { if (!this.Actor.InteractionQueue.HasInteractionOfTypeAndTarget(CyrusCane.StartUsingCane.Singleton, (GameObject)this.Target)) { InteractionInstance instance = CyrusCane.StartUsingCane.Singleton.CreateInstance((IGameObject)this.Target, (IActor)this.Actor, new InteractionPriority(InteractionPriorityLevel.UserDirected), false, true); instance.Hidden = true; this.Actor.InteractionQueue.PushAsContinuation(instance, true); } } else this.Target.UsingCane = true; return true; } [DoesntRequireTuning] private sealed class Definition : ImmediateInteractionDefinition<Sim, CyrusCane, CyrusCane.UseCane> { public override string GetInteractionName( Sim a, CyrusCane target, InteractionObjectPair interaction) { return target.UsingCane ? CyrusCane.LocalizeString(a.IsFemale, "StopUsingCane") : CyrusCane.LocalizeString(a.IsFemale, "StartUsingCane"); } public override bool Test( Sim a, CyrusCane target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback) { if (!CyrusCane.IsAllowedToUseCane(a)) return false; if (a.SimDescription.YoungAdultOrAbove) return true; greyedOutTooltipCallback = InteractionInstance.CreateTooltipCallback(CyrusCane.LocalizeString((a.IsFemale ? 1 : 0) != 0, "AgeRestriction", (object)a)); return false; } } } new public sealed class HarassEveryone : TerrainInteraction, IRouteFromInventoryOrSelfWithoutCarrying { [Tunable] [TunableComment("Distance away from the cane that the sim will route to in order to pick it up.")] public static float kHarassEveryoneObjectSearchRadius = 5f; [TunableComment("Distance away from a random object the sim will route to in order to 'harass' it.")] [Tunable] public static float[] kHarassEveryoneObjectRouteRadiusRange = new float[2] { 0.5f, 3f }; [TunableComment("Chance a sim will harass a random object within the radius.")] [Tunable] public static float kChanceToHarassObject = 0.7f; public static readonly InteractionDefinition Singleton = (InteractionDefinition)new CyrusCane.HarassEveryone.Definition(); public CyrusCane mCane; public override ThumbnailKey GetIconKey() { return this.Actor.GetThumbnailKey(); } public override bool Run() { GameObject gameObject1 = (GameObject)null; if (RandomUtil.RandomChance01(CyrusCane.HarassEveryone.kChanceToHarassObject)) { LotLocation invalid = LotLocation.Invalid; int roomId = (int)World.GetRoomId(World.GetLotLocation(this.Destination, ref invalid), invalid); GameObject[] objects = Sims3.Gameplay.Queries.GetObjects<GameObject>(this.Destination, CyrusCane.HarassEveryone.kHarassEveryoneObjectSearchRadius); List<GameObject> randomList = new List<GameObject>(); foreach (GameObject gameObject2 in objects) { if (gameObject2.RoomId == roomId && !gameObject2.InUse && gameObject2 != this.Actor) randomList.Add(gameObject2); } if (randomList.Count > 0) gameObject1 = RandomUtil.GetRandomObjectFromList<GameObject>(randomList); } Route route = this.Actor.CreateRoute(); route.PlanToPointRadialRange(this.Destination, CyrusCane.HarassEveryone.kHarassEveryoneObjectRouteRadiusRange[0], CyrusCane.HarassEveryone.kHarassEveryoneObjectRouteRadiusRange[1], RouteDistancePreference.PreferNearestToRouteDestination, RouteOrientationPreference.NoPreference, 0UL, (int[])null); if (!this.Actor.DoRoute(route)) return false; if (gameObject1 != null) this.Actor.RouteTurnToFace(gameObject1.Position); else this.Actor.RouteTurnToFace(this.Destination + RandomUtil.GetRandomDirXZ()); if (this.Actor.Posture is SwimmingInPool) { this.Actor.PlayRouteFailure(); return false; } this.mCane = CyrusSim.NewGetActiveCane(Actor) ?? this.Actor.Inventory.Find<CyrusCane>(); if (this.mCane == null) return false; this.mCane.CreatePropCane(); this.StandardEntry(); this.BeginCommodityUpdates(); this.EnterStateMachine("ElderCane", "Enter", "x"); this.SetActor(nameof(CyrusCane), (IHasScriptProxy)this.mCane.PropCane); this.mCurrentStateMachine.AddOneShotStateEnteredEventHandler("Harass Everyone", new SacsEventHandler(this.FadePropCaneIn)); if (!(this.Actor.Posture is CyrusCane.HoldingCanePosture)) this.mCurrentStateMachine.AddOneShotStateEnteredEventHandler("Exit", new SacsEventHandler(this.FadePropCaneOut)); if (gameObject1 != null) this.Actor.ThoughtBalloonManager.ShowBalloon(new ThoughtBalloonManager.BalloonData(gameObject1.GetThoughtBalloonThumbnailKey()) { BalloonType = ThoughtBalloonTypes.kThoughtBalloon, Duration = ThoughtBalloonDuration.Short, LowAxis = ThoughtBalloonAxis.kDislike }); this.AnimateSim("Harass Everyone"); EventTracker.SendEvent(EventTypeId.kHarassWithCane, (IActor)this.Actor); this.AnimateSim("Exit"); this.EndCommodityUpdates(true); this.StandardExit(); return true; } public override void Cleanup() { if (this.mCane != null && this.mCane != this.Actor.GetActiveCane()) this.mCane.DestroyPropCane(); base.Cleanup(); } private void FadePropCaneIn(StateMachineClient smc, IEvent evt) { this.mCane.PropCane.FadeIn(); } private void FadePropCaneOut(StateMachineClient smc, IEvent evt) { if (this.mCane.PropCane == null) return; this.mCane.PropCane.FadeOut(false, false); } private sealed class Definition : InteractionDefinition<Sim, Terrain, CyrusCane.HarassEveryone> { public override bool Test( Sim a, Terrain target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback) { return !(a.Posture is SwimmingInPool) && CyrusCane.IsAllowedToUseCane(a) && a.Inventory.FindAll<CyrusCane>(false).Count > 0; } public override InteractionTestResult Test( ref InteractionInstanceParameters parameters, ref GreyedOutTooltipCallback greyedOutTooltipCallback) { if (parameters.Hit.mType != GameObjectHitType.Terrain && parameters.Hit.mType != GameObjectHitType.LotTerrain && parameters.Hit.mType != GameObjectHitType.Object) return InteractionTestResult.Gen_BadTerrainType; InteractionTestResult interactionTestResult = base.Test(ref parameters, ref greyedOutTooltipCallback); if (interactionTestResult != InteractionTestResult.Pass) return interactionTestResult; if (!Terrain.GoHere.SharedGoHereTests(ref parameters)) return InteractionTestResult.GenericFail; Vector3 mPoint = parameters.Hit.mPoint; return parameters.Actor.CreateRoute().IsPointRoutable(parameters.Hit.mPoint) && !World.IsInPool(mPoint) ? InteractionTestResult.Pass : InteractionTestResult.GenericFail; } } } new public class HoldingCanePosture : Posture, IDisposable, IHaveCustomTransitionForNullPosturePreconditions { public Sim mActor; public CyrusCane mCane; public bool mIsExiting; private HoldingCanePosture() { } public HoldingCanePosture(Sim actor, CyrusCane cane, StateMachineClient smc) : base(smc) { this.mActor = actor; this.mCane = cane; this.mCane.UsingCane = true; this.mCane.AddToUseList(this.mActor); this.mActor.SimRoutingComponent.OnRouteActionsFinished -= new RoutingComponent.RouteActionsFinishedDelegate(this.OnSimRouteActionsFinished); this.mActor.SimRoutingComponent.OnRouteActionsFinished += new RoutingComponent.RouteActionsFinishedDelegate(this.OnSimRouteActionsFinished); this.mCane.CreatePropCane(); this.mCane.PropCane.ParentToSlot((IGameObject)this.mActor, Sim.ContainmentSlots.LeftHand); smc.SetActor("x", (IHasScriptProxy)this.mActor); smc.SetActor(nameof(CyrusCane), (IHasScriptProxy)this.mCane.PropCane); smc.EnterState("x", "Enter"); smc.AddOneShotStateEnteredEventHandler("Loop", new SacsEventHandler(this.OnAnimationEvent)); smc.AddSynchronousOneShotScriptEventHandler(101U, new SacsEventHandler(this.OnAnimationEvent)); smc.AddSynchronousOneShotScriptEventHandler(102U, new SacsEventHandler(this.OnAnimationEvent)); } private void OnAnimationEvent(StateMachineClient smc, IEvent evt) { if (evt.EventId == 101U || evt.EventSubType == 3U) { this.mCane.PropCane.FadeIn(); } else { if (evt.EventId != 102U) return; this.mCane.PropCane.FadeOut(false, false); } } public void OnSimRouteActionsFinished(GameObject routingObject, bool routeSuccess) { InteractionInstance headInteraction = this.mActor.InteractionQueue.GetHeadInteraction(); InteractionInstance transitionInteraction = this.mActor.InteractionQueue.TransitionInteraction; if (this.mActor.Posture is CyrusCane.HoldingCanePosture) { switch (headInteraction) { case null: case Terrain.GoHere _: case CyrusCane.TraitHarassWithCane _: case CyrusCane.HarassEveryone _: case SocialInteraction _: break; default: goto label_3; } } if (!(headInteraction is IPopCanePostureOnInteractionRouteEnd) && !(transitionInteraction is IPopCanePostureOnInteractionRouteEnd)) return; label_3: if (this.mActor.HasExitReason()) return; this.mActor.PopPosture(); } public bool IsExiting { get { return this.mIsExiting; } } public override bool PerformIdleLogic { get { return false; } } public override bool AllowsReactionOverlay() { return false; } public override bool AllowsNormalSocials() { return true; } public override bool AllowsRouting() { return this.mActor.SimDescription.ToddlerOrAbove; } public override IGameObject Container { get { return (IGameObject)this.mActor; } } public override string Name { get { return Localization.LocalizeString(this.mActor.IsFemale, "Gameplay/Actors/Postures:HoldingCane"); } } public override bool Implicit { get { return !CyrusCane.kDebug; } } public override void PopulateInteractions() { } public override float Satisfaction(CommodityKind condition, IGameObject target) { switch (condition) { case CommodityKind.Standing: return 1f; case CommodityKind.HoldingCane: return 1f; case CommodityKind.TargetInInventory: return 1f; case CommodityKind.PreferIfCurrentPosture: return this.mActor.Posture is CyrusCane.HoldingCanePosture ? 1f : 0.0f; default: return 0.0f; } } public override bool Satisfies( PreconditionOptions options, IGameObject target, CommodityKind requiredCheck) { return options == null && requiredCheck == CommodityKind.None || base.Satisfies(options, target, requiredCheck); } public override InteractionInstance GetTransition( InteractionInstance interaction) { if (interaction.Target == this.mActor && !(interaction is IRouteFromInventoryOrSelfWithoutCarrying)) return this.GetStandingTransition(); return interaction.PosturePreconditions == null ? (InteractionInstance)null : Posture.FindTransitionInteraction(interaction, CommodityKind.None); } public override BridgeOrigin Idle() { base.Idle(); this.CurrentStateMachine.SetParameter("RestrictCaneIdles", false); GameObject objectOutOfWorld = Sims3.Gameplay.GlobalFunctions.CreateObjectOutOfWorld("elderCaneIdle_Jig", ProductVersion.EP4) as GameObject; this.mActor.SetHiddenFlags(HiddenFlags.Everything); if (!World.TestObjectPlacement(objectOutOfWorld.ObjectId, TestObjectPlacementBooleans.TemporaryPlacement, this.mActor.Position, this.mActor.ForwardVector)) this.CurrentStateMachine.SetParameter("RestrictCaneIdles", true); this.mActor.SetHiddenFlags(HiddenFlags.Nothing); objectOutOfWorld.Destroy(); this.CurrentStateMachine.RequestState("x", "Loop"); return new BridgeOrigin(this.CurrentStateMachine, "x", new string[1] { "HoldCane" }); } public override InteractionInstance GetStandingTransition() { CyrusCane.StopUsingCane instance = CyrusCane.StopUsingCane.Singleton.CreateInstance((IGameObject)this.mCane, (IActor)this.mActor, this.mActor.InheritedPriority(), false, true) as CyrusCane.StopUsingCane; instance.UnsetUsingCane = false; return (InteractionInstance)instance; } public override ScriptPosture GetSacsPostureParameter() { return ScriptPosture.Standing; } public override Posture OnReset(IGameObject objectBeingReset) { this.CleanUpPosture(); return (Posture)null; } public override void OnExitPosture() { if (this.mIsExiting) return; this.mIsExiting = true; if (this.CurrentStateMachine != null) this.CurrentStateMachine.RequestState(true, "x", "Exit"); this.CleanUpPosture(); } public override void Shoo(bool yield, List<Sim> shooedSims) { throw new Exception("The method or operation is not implemented."); } private void CleanUpPosture() { if (this.mCane.IsActorUsingMe(this.mActor)) this.mCane.RemoveFromUseList(this.mActor); this.mCane.DestroyPropCane(); if (this.CurrentStateMachine != null) { this.CurrentStateMachine.RemoveAllEventHandlers(); this.CurrentStateMachine.Dispose(); this.CurrentStateMachine = (StateMachineClient)null; } if (this.mActor.SimRoutingComponent == null) return; this.mActor.SimRoutingComponent.OnRouteActionsFinished -= new RoutingComponent.RouteActionsFinishedDelegate(this.OnSimRouteActionsFinished); } public override string ToString() { return "Holding Cane Posture"; } ~HoldingCanePosture() { this.Dispose(true); } public void Dispose() { this.Dispose(false); } private void Dispose(bool fromDtor) { if (this.CurrentStateMachine != null) { this.CurrentStateMachine.RemoveAllEventHandlers(); this.CurrentStateMachine.Dispose(); this.CurrentStateMachine = (StateMachineClient)null; } if (this.mActor.SimRoutingComponent != null) this.mActor.SimRoutingComponent.OnRouteActionsFinished -= new RoutingComponent.RouteActionsFinishedDelegate(this.OnSimRouteActionsFinished); if (fromDtor) return; GC.SuppressFinalize((object)this); } } new private sealed class SetWalkStyle : ImmediateInteraction<Sim, CyrusCane> { public static readonly InteractionDefinition Singleton = (InteractionDefinition)new CyrusCane.SetWalkStyle.Definition(); public override bool RunFromInventory() { this.Target.CurrentCaneWalkStyle = (this.InteractionDefinition as CyrusCane.SetWalkStyle.Definition).CaneWalkStyle; return true; } [DoesntRequireTuning] private sealed class Definition : ImmediateInteractionDefinition<Sim, CyrusCane, CyrusCane.SetWalkStyle> { public Sim.WalkStyle CaneWalkStyle; public Definition() { } public Definition(Sim.WalkStyle walkStyle) { this.CaneWalkStyle = walkStyle; } public override string GetInteractionName( Sim a, CyrusCane target, InteractionObjectPair interaction) { return this.CaneWalkStyle == CyrusCane.kSouthernGentlemanCaneWalk ? CyrusCane.LocalizeString(a.IsFemale, "SouthernGentleman") : Cane.LocalizeString(a.IsFemale, "Elderly"); } public override string[] GetPath(bool isFemale) { return new string[1] { CyrusCane.LocalizeString(isFemale, nameof (SetWalkStyle)) }; } public override bool Test( Sim a, CyrusCane target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback) { if (!Cane.IsAllowedToUseCane(a)) return false; if (!a.SimDescription.Elder) { greyedOutTooltipCallback = InteractionInstance.CreateTooltipCallback(CyrusCane.LocalizeString((a.IsFemale ? 1 : 0) != 0, "AgeRestriction", (object)a)); return false; } if (this.CaneWalkStyle != target.CurrentCaneWalkStyle) return true; greyedOutTooltipCallback = InteractionInstance.CreateTooltipCallback(CyrusCane.LocalizeString((a.IsFemale ? 1 : 0) != 0, "WalkStyleInUse", (object)a)); return false; } public override void AddInteractions( InteractionObjectPair iop, Sim actor, CyrusCane target, List<InteractionObjectPair> results) { CyrusCane.SetWalkStyle.Definition definition1 = new CyrusCane.SetWalkStyle.Definition(CyrusCane.kSouthernGentlemanCaneWalk); results.Add(new InteractionObjectPair((InteractionDefinition)definition1, (IGameObject)target)); CyrusCane.SetWalkStyle.Definition definition2 = new CyrusCane.SetWalkStyle.Definition(CyrusCane.kElderlyCaneWalk); results.Add(new InteractionObjectPair((InteractionDefinition)definition2, (IGameObject)target)); } } } new public sealed class StartUsingCane : Interaction<Sim, CyrusCane> { public static readonly InteractionDefinition Singleton = (InteractionDefinition)new CyrusCane.StartUsingCane.Definition(); public override bool RunFromInventory() { this.StandardEntry(false); this.BeginCommodityUpdates(); CyrusCane.StopUsingAnyActiveCanes(this.Actor); if (!(this.Actor.Posture is CyrusCane.HoldingCanePosture)) { this.Actor.Posture = (Posture)new CyrusCane.HoldingCanePosture(this.Actor, this.Target, StateMachineClient.Acquire((IHasScriptProxy)this.Actor, "ElderCane")); this.Actor.Posture.CurrentStateMachine.RequestState("x", "Pull Out Cane"); } this.EndCommodityUpdates(true); this.StandardExit(false, false); return true; } private sealed class Definition : InteractionDefinition<Sim, CyrusCane, CyrusCane.StartUsingCane> { public override bool Test( Sim a, CyrusCane target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback) { return true; } } } new public sealed class StopUsingCane : Interaction<Sim, CyrusCane> { public static readonly InteractionDefinition Singleton = (InteractionDefinition)new CyrusCane.StopUsingCane.Definition(); public bool UnsetUsingCane = true; public override bool RunFromInventory() { this.StandardEntry(false); this.BeginCommodityUpdates(); if (this.UnsetUsingCane) { CyrusCane.StopUsingAnyActiveCanes(this.Actor); this.Target.UsingCane = false; } else this.Actor.PopCanePostureIfNecessary(); this.EndCommodityUpdates(true); this.StandardExit(false, false); return true; } private sealed class Definition : InteractionDefinition<Sim, CyrusCane, CyrusCane.StopUsingCane> { public override bool Test( Sim a, CyrusCane target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback) { return true; } } } new public sealed class TraitHarassWithCane : Interaction<Sim, Sim>, IRouteFromInventoryOrSelfWithoutCarrying { public static TraitNames[] HarassTraits = new TraitNames[10] { TraitNames.Grumpy, TraitNames.Evil, TraitNames.MeanSpirited, TraitNames.Insane, TraitNames.HatesOutdoors, TraitNames.DislikesChildren, TraitNames.CantStandArt, TraitNames.Frugal, TraitNames.AntiTV, TraitNames.Neat }; [Tunable] [TunableComment("Value threshold of objects that a frugal sim will harass. Threshold is randomly chosen between these two values each time the interaction is run. If the value of an object is greater than the threshold, the sim will route over an complain about it.")] public static int[] kFrugalValueThreshold = new int[2] { 500, 1000 }; [TunableComment("Objects within this radius of the sim will be selected for the sim to complain about.")] [Tunable] public static float kObjectSearchRadius = 20f; [Tunable] [TunableComment("Radial route min/max that the sim will try to route to if the find good location route fails.")] public static float[] kObjectFallbackRouteRadius = new float[2] { 0.0f, 5f }; public static readonly ISoloInteractionDefinition Singleton = (ISoloInteractionDefinition)new CyrusCane.TraitHarassWithCane.Definition(); private string mIcon = string.Empty; private CyrusCane mCane; private GameObject mHarassmentObject; public override void ConfigureInteraction() { List<TraitNames> randomList1 = new List<TraitNames>(); foreach (TraitNames harassTrait in CyrusCane.TraitHarassWithCane.HarassTraits) { if (this.Actor.TraitManager.HasElement(harassTrait)) randomList1.Add(harassTrait); } if (randomList1.Count == 0) return; GameObject[] objects = Sims3.Gameplay.Queries.GetObjects<GameObject>(this.Actor.Position, CyrusCane.TraitHarassWithCane.kObjectSearchRadius); List<GameObject> randomList2 = new List<GameObject>(); CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction objectCheckFunction = (CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction)null; switch (RandomUtil.GetRandomObjectFromList<TraitNames>(randomList1)) { case TraitNames.AntiTV: objectCheckFunction = new CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction(this.AntiTVCheck); this.mIcon = "TraitGenius"; break; case TraitNames.CantStandArt: objectCheckFunction = new CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction(this.CantStandArtCheck); this.mIcon = "Art"; break; case TraitNames.DislikesChildren: objectCheckFunction = new CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction(this.DislikesChildrenCheck); this.mIcon = "TraitDislikesChildren"; break; case TraitNames.MeanSpirited: case TraitNames.Evil: case TraitNames.Grumpy: objectCheckFunction = new CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction(this.IsSimCheck); this.mIcon = "Random"; break; case TraitNames.Frugal: objectCheckFunction = new CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction(this.FrugalCheck); this.mIcon = "TraitFrugal"; break; case TraitNames.HatesOutdoors: objectCheckFunction = new CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction(this.HatesOutdoorsCheck); this.mIcon = "Great Outdoors"; break; case TraitNames.Insane: objectCheckFunction = new CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction(this.HatesOutdoorsCheck); this.mIcon = "Talk About Conspiracies"; break; case TraitNames.Neat: objectCheckFunction = new CyrusCane.TraitHarassWithCane.HarassObjectCheckFunction(this.NeatCheck); this.mIcon = "Insult"; break; } foreach (GameObject gameObject in objects) { if (objectCheckFunction(gameObject) && this.Actor.IsGreetedOnLot(gameObject.LotCurrent)) randomList2.Add(gameObject); } this.mHarassmentObject = (GameObject)this.Actor; if (randomList2.Count <= 0) return; this.mHarassmentObject = RandomUtil.GetRandomObjectFromList<GameObject>(randomList2); } public override ThumbnailKey GetIconKey() { return this.mHarassmentObject != null ? this.mHarassmentObject.GetThumbnailKey() : base.GetIconKey(); } public override bool Run() { if (this.mHarassmentObject == null) return false; World.FindGoodLocationParams fglParams = new World.FindGoodLocationParams(this.mHarassmentObject.Position); fglParams.StartPosition = this.mHarassmentObject.Position; fglParams.RequiredRoomID = this.mHarassmentObject.RoomId; bool flag = false; Vector3 pos; if (Sims3.Gameplay.GlobalFunctions.FindGoodLocation((IGameObject)this.Actor, fglParams, out pos, out Vector3 _)) { Route route = this.Actor.CreateRoute(); route.PlanToPoint(pos); route.DoRouteFail = false; flag = this.Actor.DoRoute(route); } if (!flag) this.Actor.RouteToDynamicObjectRadiusWithCondition((IGameObject)this.mHarassmentObject, CyrusCane.TraitHarassWithCane.kObjectFallbackRouteRadius[0], Cane.TraitHarassWithCane.kObjectFallbackRouteRadius[1], (RouteCallback)null, (RouteCallbackCondition)null, Route.RouteOption.DoLineOfSightCheckUserOverride); this.Actor.RouteTurnToFace(this.mHarassmentObject.Position); if (this.Actor.Posture is SwimmingInPool) { this.Actor.PlayRouteFailure(); return false; } this.mCane = CyrusSim.NewGetActiveCane(Actor) ?? this.Actor.Inventory.Find<CyrusCane>(); if (this.mCane == null) return false; if (!this.mCane.UsingCane) this.mCane.AddToUseList(this.Actor); this.mCane.CreatePropCane(); this.StandardEntry(); this.BeginCommodityUpdates(); this.EnterStateMachine("ElderCane", "Enter", "x"); this.SetActor(nameof(CyrusCane), (IHasScriptProxy)this.mCane.PropCane); this.mCurrentStateMachine.AddOneShotStateEnteredEventHandler("Harass Everyone", new SacsEventHandler(this.FadePropCaneIn)); if (!(this.Actor.Posture is CyrusCane.HoldingCanePosture)) this.mCurrentStateMachine.AddOneShotStateEnteredEventHandler("Exit", new SacsEventHandler(this.FadePropCaneOut)); ThoughtBalloonManager.BalloonData balloonData = ThoughtBalloonManager.GetBalloonData(this.mIcon, this.Actor); balloonData.BalloonType = ThoughtBalloonTypes.kThoughtBalloon; balloonData.LowAxis = ThoughtBalloonAxis.kDislike; balloonData.Duration = ThoughtBalloonDuration.Short; this.Actor.ThoughtBalloonManager.ShowBalloon(balloonData); this.AnimateSim("Harass Everyone"); this.AnimateSim("Exit"); this.EndCommodityUpdates(true); this.StandardExit(); return true; } public override void Cleanup() { if (this.mCane != null) { if (this.mCane.IsActorUsingMe(this.Actor) && !this.mCane.UsingCane) this.mCane.RemoveFromUseList(this.Actor); if (this.mCane != this.Actor.GetActiveCane()) this.mCane.DestroyPropCane(); } base.Cleanup(); } private void FadePropCaneIn(StateMachineClient smc, IEvent evt) { this.mCane.PropCane.FadeIn(); } private void FadePropCaneOut(StateMachineClient smc, IEvent evt) { if (this.mCane.PropCane == null) return; this.mCane.PropCane.FadeOut(false, false); } private bool IsSimCheck(GameObject obj) { return obj is Sim; } private bool HatesOutdoorsCheck(GameObject obj) { return obj.IsOutside && !obj.InUse && obj != this.Actor; } private bool DislikesChildrenCheck(GameObject obj) { return obj is Sim sim && sim.IsHuman && (sim.SimDescription.IsPregnant || sim.SimDescription.ChildOrBelow) && obj != this.Actor; } private bool CantStandArtCheck(GameObject obj) { switch (obj) { case IPainting _: case ISculpture _: return true; default: return obj is IPhotograph; } } private bool FrugalCheck(GameObject obj) { int num = RandomUtil.GetInt(CyrusCane.TraitHarassWithCane.kFrugalValueThreshold[0], CyrusCane.TraitHarassWithCane.kFrugalValueThreshold[1]); return obj.Value >= num; } private bool AntiTVCheck(GameObject obj) { switch (obj) { case ITelevision _: case IComputer _: return true; default: return obj is IStereo; } } private bool NeatCheck(GameObject obj) { if (obj is Sim sim) { if (sim.BuffManager.HasAnyElement(BuffNames.Smelly, BuffNames.Grungy)) return true; } CleanableComponent cleanable = obj.Cleanable; return cleanable != null && cleanable.VisuallyDirty; } public delegate bool HarassObjectCheckFunction(GameObject obj); private sealed class Definition : SoloSimInteractionDefinition<CyrusCane.TraitHarassWithCane> { public override bool Test( Sim a, Sim target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback) { return CyrusCane.IsAllowedToUseCane(a) && a.Inventory.ContainsType(typeof(CyrusCane), 1) && a.TraitManager.HasAnyElement(CyrusCane.TraitHarassWithCane.HarassTraits); } } } } }
EDIT: Oh wait, I solved it. It was the namespace, my bad for not seeing that part of the tutorial. So... I'm trying to have the interactions to appear, but I'm not managing to do it. What should I do? I even added this:
Code:
public override void OnStartup() { base.OnStartup(); base.AddInteraction(UseCane.Singleton); base.AddInteraction(HarassEveryone.Singleton); base.AddInteraction(SetWalkStyle.Singleton); base.AddInteraction(StartUsingCane.Singleton); base.AddInteraction(StopUsingCane.Singleton); }
But the interactions still didn't appear.
#11
7th Oct 2020 at 11:59 AM
Posts: 562
Thanks: 3599 in 11 Posts
Ah yeah you will need the OnStartup method. After base.OnStartup() you will need to add RemoveAllInteractions(); to get rid of the original ones. You might want to leave it at that to see if all the interactions are being removed successfully before adding on your custom ones.
When you say the interactions don't appear, what actually happens? When you hover over the cane, does it have the namespace like Sims3.Gameplay... ? If so, I think that means that the objk isn't right.
You could always try with a cloned cane to make sure it works before replacing the original, to make sure the problem is with the code and not the default replacement itself.
You probably just missed Battery's post, but maybe you could post the cs file and package ?
When you say the interactions don't appear, what actually happens? When you hover over the cane, does it have the namespace like Sims3.Gameplay... ? If so, I think that means that the objk isn't right.
You could always try with a cloned cane to make sure it works before replacing the original, to make sure the problem is with the code and not the default replacement itself.
You probably just missed Battery's post, but maybe you could post the cs file and package ?
#12
7th Oct 2020 at 3:52 PM
Posts: 175
Thanks: 175 in 1 Posts
@zoe22 and @Battery ,
Yeah, I did miss Battery's post. My bad. Here's the link for the class and package:
https://mega.nz/folder/ycQE1bxJ#HIRMF1U68ajYV6ouz4AvRA
Yeah, I did miss Battery's post. My bad. Here's the link for the class and package:
https://mega.nz/folder/ycQE1bxJ#HIRMF1U68ajYV6ouz4AvRA
Space Pony
#13
7th Oct 2020 at 5:24 PM
Last edited by Battery : 7th Oct 2020 at 5:37 PM.
Posts: 433
Thanks: 792 in 6 Posts
Hey @CyrusBanefort,
i just took a look at your code public class CyrusSim : Sims3.Gameplay.Actors.Sim wont work as you intend since you are not creating a new type of sim that is used anywhere in game i would recommend just casting the original returntype and do a null check
E: and im not able to compile your code without errors
E2: you are not following the c# .net 2.0 spec, for instance you are using the nameof operator which is part of .net 4.0
i just took a look at your code public class CyrusSim : Sims3.Gameplay.Actors.Sim wont work as you intend since you are not creating a new type of sim that is used anywhere in game i would recommend just casting the original returntype and do a null check
E: and im not able to compile your code without errors
E2: you are not following the c# .net 2.0 spec, for instance you are using the nameof operator which is part of .net 4.0
#14
7th Oct 2020 at 5:54 PM
Posts: 175
Thanks: 175 in 1 Posts
@Battery ,
That about the nameof operator... That's interesting. I use two decompilers to open the game's dlls, one is IlSpy, to get the code most accurate to the original one, and DotPeek, to get the parts that won't compile with IlSpy. Is there something more that deviates from the net 2.0 spec in the code?
That about the nameof operator... That's interesting. I use two decompilers to open the game's dlls, one is IlSpy, to get the code most accurate to the original one, and DotPeek, to get the parts that won't compile with IlSpy. Is there something more that deviates from the net 2.0 spec in the code?
Space Pony
#15
7th Oct 2020 at 6:01 PM
Posts: 433
Thanks: 792 in 6 Posts
Hmm ilspy should be fine for everything
what does not decompile correctly with it ?
what does not decompile correctly with it ?
#16
7th Oct 2020 at 6:07 PM
Posts: 175
Thanks: 175 in 1 Posts
Quote: Originally posted by Battery
Hmm ilspy should be fine for everything what does not decompile correctly with it ? |
@Battery ,
For example, I get those errors when opening the run() function of the TraitHarassWithCane class:
Code:
public override bool Run() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Expected O, but got Unknown if (mHarassmentObject == null) { return false; } FindGoodLocationParams fglParams = default(FindGoodLocationParams); ((FindGoodLocationParams)(ref fglParams))..ctor(mHarassmentObject.Position); fglParams.StartPosition = mHarassmentObject.Position; fglParams.RequiredRoomID = mHarassmentObject.RoomId; bool flag = false; if (GlobalFunctions.FindGoodLocation(Actor, fglParams, out Vector3 pos, out Vector3 _)) { Route val = Actor.CreateRoute(); val.PlanToPoint(pos); val.set_DoRouteFail(false); flag = Actor.DoRoute(val); } if (!flag) { Actor.RouteToDynamicObjectRadiusWithCondition(mHarassmentObject, kObjectFallbackRouteRadius[0], kObjectFallbackRouteRadius[1], null, null, (RouteOption)65536); } Actor.RouteTurnToFace(mHarassmentObject.Position); if (Actor.Posture is SwimmingInPool) { Actor.PlayRouteFailure(); return false; } mCane = (Actor.GetActiveCane() ?? Actor.Inventory.Find<Cane>()); if (mCane == null) { return false; } if (!mCane.UsingCane) { mCane.AddToUseList(Actor); } mCane.CreatePropCane(); StandardEntry(); BeginCommodityUpdates(); EnterStateMachine("ElderCane", "Enter", "x"); SetActor("Cane", (IHasScriptProxy)(object)mCane.PropCane); mCurrentStateMachine.AddOneShotStateEnteredEventHandler("Harass Everyone", (SacsEventHandler)(object)new SacsEventHandler(FadePropCaneIn)); if (!(Actor.Posture is HoldingCanePosture)) { mCurrentStateMachine.AddOneShotStateEnteredEventHandler("Exit", (SacsEventHandler)(object)new SacsEventHandler(FadePropCaneOut)); } ThoughtBalloonManager.BalloonData balloonData = ThoughtBalloonManager.GetBalloonData(mIcon, Actor); balloonData.BalloonType = ThoughtBalloonTypes.kThoughtBalloon; balloonData.LowAxis = ThoughtBalloonAxis.kDislike; balloonData.Duration = ThoughtBalloonDuration.Short; Actor.ThoughtBalloonManager.ShowBalloon(balloonData); AnimateSim("Harass Everyone"); AnimateSim("Exit"); EndCommodityUpdates(succeeded: true); StandardExit(); return true; }
Space Pony
#17
7th Oct 2020 at 6:12 PM
Posts: 433
Thanks: 792 in 6 Posts
Hmm i think i have heared of that before but cant remember what remedys it did you load all references into ilspy ?
#18
7th Oct 2020 at 6:27 PM
Posts: 175
Thanks: 175 in 1 Posts
@Battery , yeah, looks like it was that. I loaded the other libraries in IlSpy and the problem was solved.
Sockpuppet
#19
12th Oct 2020 at 1:22 PM
Posts: 2
Quote: Originally posted by CyrusBanefort
@Battery , For example, I get those errors when opening the run() function of the TraitHarassWithCane class:
Code:
public override bool Run() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Expected O, but got Unknown if (mHarassmentObject == null) { return false; } FindGoodLocationParams fglParams = default(FindGoodLocationParams); ((FindGoodLocationParams)(ref fglParams))..ctor(mHarassmentObject.Position); fglParams.StartPosition = mHarassmentObject.Position; fglParams.RequiredRoomID = mHarassmentObject.RoomId; bool flag = false; if (GlobalFunctions.FindGoodLocation(Actor, fglParams, out Vector3 pos, out Vector3 _)) { Route val = Actor.CreateRoute(); val.PlanToPoint(pos); val.set_DoRouteFail(false); flag = Actor.DoRoute(val); } if (!flag) { Actor.RouteToDynamicObjectRadiusWithCondition(mHarassmentObject, kObjectFallbackRouteRadius[0], kObjectFallbackRouteRadius[1], null, null, (RouteOption)65536); } Actor.RouteTurnToFace(mHarassmentObject.Position); if (Actor.Posture is SwimmingInPool) { Actor.PlayRouteFailure(); return false; } mCane = (Actor.GetActiveCane() ?? Actor.Inventory.Find<Cane>()); if (mCane == null) { return false; } if (!mCane.UsingCane) { mCane.AddToUseList(Actor); } mCane.CreatePropCane(); StandardEntry(); BeginCommodityUpdates(); EnterStateMachine("ElderCane", "Enter", "x"); SetActor("Cane", (IHasScriptProxy)(object)mCane.PropCane); mCurrentStateMachine.AddOneShotStateEnteredEventHandler("Harass Everyone", (SacsEventHandler)(object)new SacsEventHandler(FadePropCaneIn)); if (!(Actor.Posture is HoldingCanePosture)) { mCurrentStateMachine.AddOneShotStateEnteredEventHandler("Exit", (SacsEventHandler)(object)new SacsEventHandler(FadePropCaneOut)); } ThoughtBalloonManager.BalloonData balloonData = ThoughtBalloonManager.GetBalloonData(mIcon, Actor); balloonData.BalloonType = ThoughtBalloonTypes.kThoughtBalloon; balloonData.LowAxis = ThoughtBalloonAxis.kDislike; balloonData.Duration = ThoughtBalloonDuration.Short; Actor.ThoughtBalloonManager.ShowBalloon(balloonData); AnimateSim("Harass Everyone"); AnimateSim("Exit"); EndCommodityUpdates(succeeded: true); StandardExit(); return true; } |
Give a try to C# Decompiler Online. Usually it works for me.
Who Posted
|