public void OnSpawn(GameObject go) { Sensors component = go.GetComponent <Sensors>(); component.Add(new PathProberSensor(component)); component.Add(new SafeCellSensor(component)); component.Add(new IdleCellSensor(component)); component.Add(new PickupableSensor(component)); component.Add(new ClosestEdibleSensor(component)); component.Add(new BreathableAreaSensor(component)); component.Add(new AssignableReachabilitySensor(component)); component.Add(new ToiletSensor(component)); component.Add(new MingleCellSensor(component)); StateMachineController component2 = go.GetComponent <StateMachineController>(); RationalAi.Instance instance = new RationalAi.Instance(component2); instance.StartSM(); if (go.GetComponent <OxygenBreather>().GetGasProvider() == null) { go.GetComponent <OxygenBreather>().SetGasProvider(new GasBreatherFromWorldProvider()); } Navigator component3 = go.GetComponent <Navigator>(); component3.transitionDriver.overrideLayers.Add(new BipedTransitionLayer(component3, 3.325f, 2.5f)); component3.transitionDriver.overrideLayers.Add(new DoorTransitionLayer(component3)); component3.transitionDriver.overrideLayers.Add(new TubeTransitionLayer(component3)); component3.transitionDriver.overrideLayers.Add(new LadderDiseaseTransitionLayer(component3)); component3.transitionDriver.overrideLayers.Add(new ReactableTransitionLayer(component3)); component3.transitionDriver.overrideLayers.Add(new SplashTransitionLayer(component3)); ThreatMonitor.Instance sMI = go.GetSMI <ThreatMonitor.Instance>(); if (sMI != null) { sMI.def.fleethresholdState = Health.HealthState.Critical; } }
public static void Postfix(ref bool __result, ThreatMonitor.Instance __instance) { // First disable entirely if not activated if (!DangerousWorldOptions.Instance.AggroCrittersOption) { return; } DangerousWorldAggroCritters.AggroMonitor.Instance aggroMonitor = __instance.GetSMI <DangerousWorldAggroCritters.AggroMonitor.Instance>(); if (aggroMonitor != null && aggroMonitor.GetCurrentState() != aggroMonitor.sm.calm) { __result = aggroMonitor.WillAttack(); } }
public override void InitializeStates(out BaseState default_state) { default_state = plan; root.Enter("SetFleeTarget", delegate(Instance smi) { fleeToTarget.Set(CreatureHelpers.GetFleeTargetLocatorObject(smi.master.gameObject, smi.GetSMI <ThreatMonitor.Instance>().MainThreat), smi); }).ToggleStatusItem(CREATURES.STATUSITEMS.FLEEING.NAME, CREATURES.STATUSITEMS.FLEEING.TOOLTIP, category: Db.Get().StatusItemCategories.Main, icon: string.Empty, icon_type: StatusItem.IconType.Info, notification_type: NotificationType.Neutral, allow_multiples: false, render_overlay: default(HashedString), status_overlays: 129022, resolve_string_callback: null, resolve_tooltip_callback: null); plan.Enter(delegate(Instance smi) { ThreatMonitor.Instance sMI = smi.master.gameObject.GetSMI <ThreatMonitor.Instance>(); fleeToTarget.Set(CreatureHelpers.GetFleeTargetLocatorObject(smi.master.gameObject, sMI.MainThreat), smi); if ((Object)fleeToTarget.Get(smi) != (Object)null) { smi.GoTo(approach); } else { smi.GoTo(cower); } }); approach.InitializeStates(mover, fleeToTarget, cower, cower, null, NavigationTactics.ReduceTravelDistance).Enter(delegate(Instance smi) { PopFXManager.Instance.SpawnFX(PopFXManager.Instance.sprite_Plus, CREATURES.STATUSITEMS.FLEEING.NAME.text, smi.master.transform, 1.5f, false); }); cower.Enter(delegate(Instance smi) { string s = "DEFAULT COWER ANIMATION"; if (smi.Get <KBatchedAnimController>().HasAnimation("cower")) { s = "cower"; } else if (smi.Get <KBatchedAnimController>().HasAnimation("idle")) { s = "idle"; } else if (smi.Get <KBatchedAnimController>().HasAnimation("idle_loop")) { s = "idle_loop"; } smi.Get <KBatchedAnimController>().Play(s, KAnim.PlayMode.Loop, 1f, 0f); }).ScheduleGoTo(2f, behaviourcomplete); behaviourcomplete.BehaviourComplete(GameTags.Creatures.Flee, false); }
/// <summary> /// Finds threats for a Duplicant. /// </summary> /// <param name="instance">The threat monitor which is looking for threats.</param> /// <param name="threats">The location where threats will be stored.</param> /// <param name="navigator">The navigator to check threat reachability.</param> private static void FindThreatDuplicant(ThreatMonitor.Instance instance, List <FactionAlignment> threats, Navigator navigator) { if (instance.WillFight()) { var inst = FactionManager.Instance; // Skip faction 0 (Duplicant) as the Klei code does for (int i = (int)FactionID.Friendly; i < MAX_FACTION; i++) { foreach (var alignment in inst.GetFaction((FactionID)i).Members) { if (alignment.IsPlayerTargeted() && !alignment.health.IsDefeated() && navigator.CanReach(alignment.attackable)) { threats.Add(alignment); } } } } }
/// <summary> /// Applied before FindThreat runs. /// </summary> internal static bool Prefix(ThreatMonitor.Instance __instance, ref GameObject __result) { if (__instance.isMasterNull) { __result = null; } else { var threats = __instance.threats; var navigator = __instance.navigator; if (threats == null) { throw new ArgumentNullException("threats"); } threats.Clear(); if (NEEDS_THREAT_SEARCH == null) { InitThreatList(); } if (__instance.IAmADuplicant) { FindThreatDuplicant(__instance, threats, navigator); } else if (NEEDS_THREAT_SEARCH.Contains(__instance.alignment.Alignment)) { // This branch is never reachable as Duplicant, because the Duplicant // faction has Attack disposition to nothing FindThreatCritter(__instance, threats, navigator); } if (threats.Count < 1) { __result = null; } else { __result = __instance.PickBestTarget(threats); } } return(false); }
/// <summary> /// Finds threats for a critter. /// </summary> /// <param name="instance">The threat monitor which is looking for threats.</param> /// <param name="threats">The location where threats will be stored.</param> /// <param name="navigator">The navigator to check threat reachability.</param> private static void FindThreatCritter(ThreatMonitor.Instance instance, List <FactionAlignment> threats, Navigator navigator) { // Base game uses hard coded 20 here var extents = new Extents(Grid.PosToCell(instance.transform.position), 20); var myAlign = instance.alignment; var friendly = instance.def.friendlyCreatureTags; var gsp = GameScenePartitioner.Instance; var inst = FactionManager.Instance; var attackables = ListPool <ScenePartitionerEntry, ThreatMonitor> .Allocate(); gsp.GatherEntries(extents, gsp.attackableEntitiesLayer, attackables); foreach (var entry in attackables) { if (entry != null && entry.obj is FactionAlignment alignment && alignment != myAlign && alignment.IsAlignmentActive() && inst.GetDisposition( myAlign.Alignment, alignment.Alignment) == FactionManager.Disposition. Attack) { bool isFriendly = false; if (friendly != null) { // This list is only ever null or 1 element long in ONI foreach (var tag in friendly) { if (alignment.HasTag(tag)) { isFriendly = true; break; } } } if (!isFriendly && navigator.CanReach(alignment.attackable)) { threats.Add(alignment); } } } attackables.Recycle(); }