using System.Collections.Generic; using System.Globalization; public class EAISetNearestEntityAsTargetFatZombieRebirth : EAITarget { public override void Init(EntityAlive _theEntity) { base.Init(_theEntity, 25f, true); this.MutexBits = 1; this.sorter = new EAISetNearestEntityAsTargetSorter(_theEntity); } public override void SetData(DictionarySave data) { base.SetData(data); this.targetClasses = new List(); string text; if (data.TryGetValue("class", out text)) { string[] array = text.Split(new char[] { ',' }); for (int i = 0; i < array.Length; i += 3) { EAISetNearestEntityAsTargetFatZombieRebirth.TargetClass targetClass; targetClass.type = EntityFactory.GetEntityType(array[i]); targetClass.hearDistMax = 0f; if (i + 1 < array.Length) { targetClass.hearDistMax = StringParsers.ParseFloat(array[i + 1], 0, -1, NumberStyles.Any); } targetClass.seeDistMax = 0f; if (i + 2 < array.Length) { targetClass.seeDistMax = StringParsers.ParseFloat(array[i + 2], 0, -1, NumberStyles.Any); } if (targetClass.type == typeof(EntityPlayer)) { this.playerTargetClassIndex = this.targetClasses.Count; } this.targetClasses.Add(targetClass); } } } public override bool CanExecute() { if (this.theEntity.distraction != null) { return false; } this.FindTarget(); if (!this.closeTargetEntity) { return false; } this.targetEntity = this.closeTargetEntity; this.targetPlayer = (this.closeTargetEntity as EntityPlayer); return true; } private void FindTarget() { this.closeTargetDist = float.MaxValue; this.closeTargetEntity = null; float seeDistance = this.theEntity.GetSeeDistance(); for (int i = 0; i < this.targetClasses.Count; i++) { EAISetNearestEntityAsTargetFatZombieRebirth.TargetClass targetClass = this.targetClasses[i]; float num = seeDistance; if (targetClass.seeDistMax > 0f) { num = Utils.FastMin(num, targetClass.seeDistMax * this.theEntity.senseScale); } //Log.Out("FindTarget Distance1: " + num); ulong worldTime = GameManager.Instance.World.worldTime; ValueTuple valueTuple = GameUtils.WorldTimeToElements(worldTime); num = (int)(valueTuple.Item1 * 1.5) + 20; //Log.Out("FindTarget Distance2: " + num); if (targetClass.type == typeof(EntityVehicle) && !RebirthUtilities.IsHordeNight()) { //Log.Out("EAISetNearestEntityAsTargetFatZombieRebirth-FindTarget EntityVehicle"); this.theEntity.world.GetEntitiesInBounds(targetClass.type, BoundsUtils.ExpandBounds(this.theEntity.boundingBox, num, 4f, num), EAISetNearestEntityAsTargetFatZombieRebirth.list); EAISetNearestEntityAsTargetFatZombieRebirth.list.Sort(this.sorter); int j = 0; while (j < EAISetNearestEntityAsTargetFatZombieRebirth.list.Count) { EntityAlive entityAlive = (EntityAlive)EAISetNearestEntityAsTargetFatZombieRebirth.list[j]; if (entityAlive.EntityName == "vehicleBicycle" || entityAlive.EntityClass.entityClassName == "vehicleBicycle" || entityAlive.Health == 0) { break; } //Log.Out("EAISetNearestEntityAsTargetFatZombieRebirth-FindTarget entityAlive: " + entityAlive.EntityName); float distance = this.theEntity.GetDistance(entityAlive); if (distance < this.closeTargetDist) { // Log.Out("EAISetNearestEntityAsTargetFatZombieRebirth-FindTarget EntityVehicle 1"); this.closeTargetDist = distance; this.closeTargetEntity = entityAlive; this.lastSeenPos = entityAlive.position; break; } break; } EAISetNearestEntityAsTargetFatZombieRebirth.list.Clear(); } else if (targetClass.type == typeof(EntityPlayer)) { this.FindTargetPlayer(num); if (this.theEntity.noisePlayer && this.theEntity.noisePlayer != this.closeTargetEntity) { if (this.closeTargetEntity) { if (this.theEntity.noisePlayerVolume >= this.theEntity.noiseWake) { Vector3 position = this.theEntity.noisePlayer.position; float magnitude = (this.theEntity.position - position).magnitude; if (magnitude < this.closeTargetDist) { this.closeTargetDist = magnitude; this.closeTargetEntity = this.theEntity.noisePlayer; } } } else if (!this.theEntity.IsSleeping) { this.SeekNoise(this.theEntity.noisePlayer); } } if (this.closeTargetEntity && base.check(this.closeTargetEntity)) { EntityPlayer entityPlayer = (EntityPlayer)this.closeTargetEntity; if (entityPlayer.IsBloodMoonDead && entityPlayer.currentLife >= 0.5f) { Log.Out("Player {0}, living {1}, lost BM immunity", new object[] { entityPlayer.GetDebugName(), entityPlayer.currentLife * 60f }); entityPlayer.IsBloodMoonDead = false; } } } else if (!this.theEntity.IsSleeping && !this.theEntity.HasInvestigatePosition) { this.theEntity.world.GetEntitiesInBounds(targetClass.type, BoundsUtils.ExpandBounds(this.theEntity.boundingBox, num, 4f, num), EAISetNearestEntityAsTargetFatZombieRebirth.list); EAISetNearestEntityAsTargetFatZombieRebirth.list.Sort(this.sorter); int j = 0; while (j < EAISetNearestEntityAsTargetFatZombieRebirth.list.Count) { EntityAlive entityAlive = (EntityAlive)EAISetNearestEntityAsTargetFatZombieRebirth.list[j]; if (!(entityAlive is EntityDrone) && base.check(entityAlive)) { float distance = this.theEntity.GetDistance(entityAlive); if (distance < this.closeTargetDist) { this.closeTargetDist = distance; this.closeTargetEntity = entityAlive; this.lastSeenPos = entityAlive.position; break; } break; } else { j++; } } EAISetNearestEntityAsTargetFatZombieRebirth.list.Clear(); } } } private void SeekNoise(EntityPlayer player) { float num = (player.position - this.theEntity.position).magnitude; if (this.playerTargetClassIndex >= 0) { float num2 = this.targetClasses[this.playerTargetClassIndex].hearDistMax; if (num2 > 0f) { num2 *= this.theEntity.senseScale; if (num > num2) { return; } } } num *= 0.9f; if (num > this.manager.noiseSeekDist) { num = this.manager.noiseSeekDist; } if (this.theEntity.IsBloodMoon) { num = this.manager.noiseSeekDist * 0.25f; } Vector3 breadcrumbPos = player.GetBreadcrumbPos(num * base.RandomFloat); int ticks = this.theEntity.CalcInvestigateTicks((int)(30f + base.RandomFloat * 30f) * 20, player); this.theEntity.SetInvestigatePosition(breadcrumbPos, ticks, true); float time = Time.time; if (this.senseSoundTime - time < 0f) { this.senseSoundTime = time + 10f + base.RandomFloat * 10f; this.theEntity.PlayOneShot(this.theEntity.soundSense, false); } } private void FindTargetPlayer(float seeDist) { if (this.theEntity.IsSleeperPassive) { return; } string rebirthFeralSense = RebirthVariables.customFeralSense; int currentDay = GameUtils.WorldTimeToDays(GameManager.Instance.World.worldTime); bool randomValid = rebirthFeralSense == "random" && currentDay == RebirthManager.nextFeralSenseDay; if (randomValid && GameManager.Instance.World.IsDaytime() && RebirthManager.nextFeralSensePeriod == 1) { randomValid = false; } if (randomValid && !GameManager.Instance.World.IsDaytime() && RebirthManager.nextFeralSensePeriod == 2) { randomValid = false; } bool isValidFeralSense = (rebirthFeralSense == "always") || (GameManager.Instance.World.IsDaytime() && rebirthFeralSense == "dayonly") || (!GameManager.Instance.World.IsDaytime() && rebirthFeralSense == "nightonly") || randomValid; string rebirthPOISense = RebirthVariables.customPOISense; bool POISense = (rebirthPOISense == "always") || (GameManager.Instance.World.IsDaytime() && rebirthPOISense == "dayonly") || (!GameManager.Instance.World.IsDaytime() && rebirthPOISense == "nightonly"); if (isValidFeralSense || (this.theEntity.IsSleeper && POISense)) { seeDist = 200; this.theEntity.SetMaxViewAngle(360); } this.theEntity.world.GetEntitiesInBounds(typeof(EntityPlayer), BoundsUtils.ExpandBounds(this.theEntity.boundingBox, seeDist, seeDist, seeDist), EAISetNearestEntityAsTargetFatZombieRebirth.list); if (!this.theEntity.IsSleeping) { for (int i = 0; i < EAISetNearestEntityAsTargetFatZombieRebirth.list.Count; i++) { EntityPlayer entityPlayer = (EntityPlayer)EAISetNearestEntityAsTargetFatZombieRebirth.list[i]; if (entityPlayer.IsAlive() && !entityPlayer.IsIgnoredByAI()) { float distance = this.theEntity.GetDistance(entityPlayer); if (distance < this.closeTargetDist && this.theEntity.CanSee(entityPlayer) && this.theEntity.CanSeeStealth(distance, entityPlayer.Stealth.lightLevel)) { this.closeTargetDist = distance; this.closeTargetEntity = entityPlayer; } } } EAISetNearestEntityAsTargetFatZombieRebirth.list.Clear(); return; } EAISetNearestEntityAsTargetFatZombieRebirth.list.Sort(this.sorter); EntityPlayer x = null; float num = float.MaxValue; bool flag = false; if (this.theEntity.noisePlayer != null) { if (this.theEntity.noisePlayerVolume >= this.theEntity.noiseWake) { x = this.theEntity.noisePlayer; num = this.theEntity.noisePlayerDistance; } else if (this.theEntity.noisePlayerVolume >= this.theEntity.noiseGroan) { flag = true; } } for (int j = 0; j < EAISetNearestEntityAsTargetFatZombieRebirth.list.Count; j++) { EntityPlayer entityPlayer2 = (EntityPlayer)EAISetNearestEntityAsTargetFatZombieRebirth.list[j]; if (this.theEntity.CanSee(entityPlayer2) && !entityPlayer2.IsIgnoredByAI()) { float distance2 = this.theEntity.GetDistance(entityPlayer2); int sleeperDisturbedLevel = this.theEntity.GetSleeperDisturbedLevel(distance2, entityPlayer2.Stealth.lightLevel); if (sleeperDisturbedLevel >= 2) { if (distance2 < num) { x = entityPlayer2; num = distance2; } } else if (sleeperDisturbedLevel >= 1) { flag = true; } } } EAISetNearestEntityAsTargetFatZombieRebirth.list.Clear(); if (x != null) { this.closeTargetDist = num; this.closeTargetEntity = x; return; } if (flag) { this.theEntity.Groan(); return; } this.theEntity.Snore(); } public override void Start() { this.theEntity.SetAttackTarget(this.targetEntity, 200); this.theEntity.ConditionalTriggerSleeperWakeUp(); base.Start(); } public override bool Continue() { if (this.targetEntity.IsDead() || this.theEntity.distraction != null) { if (this.theEntity.GetAttackTarget() == this.targetEntity) { this.theEntity.attackTarget = (EntityAlive) null; } return false; } this.findTime += 0.05f; if (this.findTime > 2f) { this.findTime = 0f; this.FindTarget(); if (this.closeTargetEntity && this.closeTargetEntity != this.targetEntity) { return false; } } if (this.theEntity.GetAttackTarget() != this.targetEntity) { return false; } if (base.check(targetEntity) && (this.targetPlayer == null || this.theEntity.CanSeeStealth(this.theEntity.GetDistance(this.targetEntity), this.targetPlayer.Stealth.lightLevel))) { this.theEntity.SetAttackTarget(this.targetEntity, 600); this.lastSeenPos = this.targetEntity.position; return true; } if (this.theEntity.GetDistanceSq(this.lastSeenPos) < 2.25f) { this.lastSeenPos = Vector3.zero; } this.theEntity.attackTarget = (EntityAlive) null; int num = this.theEntity.CalcInvestigateTicks(Constants.cEnemySenseMemory * 20, this.targetEntity); if (this.lastSeenPos != Vector3.zero) { this.theEntity.SetInvestigatePosition(this.lastSeenPos, num, true); } if (this.targetPlayer) { if (this.theEntity.entityType == EntityType.Zombie) { num /= 6; } this.theEntity.SetAlertTicks(num); } return false; } public override void Reset() { this.targetEntity = null; this.targetPlayer = null; } public override string ToString() { return string.Format("{0}, {1}", base.ToString(), this.targetEntity ? this.targetEntity.EntityName : ""); } private List targetClasses; private int playerTargetClassIndex = -1; private float closeTargetDist; private EntityAlive closeTargetEntity; private EntityAlive targetEntity; private EntityPlayer targetPlayer; private Vector3 lastSeenPos; private float findTime; private float senseSoundTime; private EAISetNearestEntityAsTargetSorter sorter; private static List list = new List(); private struct TargetClass { public Type type; public float hearDistMax; public float seeDistMax; } }