using System; using System.Collections.Generic; using System.Globalization; using UnityEngine; using UnityEngine.Scripting; [Preserve] public class EAISetNearestEntityAsTargetCompanion : 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) { //Log.Out("EAISetNearestEntityAsTargetCompanion-SetData START"); base.SetData(data); this.targetClasses = new List(); string text; if (data.TryGetValue("class", out text)) { //Log.Out("EAISetNearestEntityAsTargetCompanion-SetData 1"); string[] array = text.Split(',', StringSplitOptions.None); for (int i = 0; i < array.Length; i += 3) { //Log.Out("EAISetNearestEntityAsTargetCompanion-SetData i: " + i); EAISetNearestEntityAsTargetCompanion.TargetClass targetClass; targetClass.type = EntityFactory.GetEntityType(array[i]); targetClass.hearDistMax = 0f; if (i + 1 < array.Length) { //Log.Out("EAISetNearestEntityAsTargetCompanion-SetData 2"); targetClass.hearDistMax = StringParsers.ParseFloat(array[i + 1], 0, -1, NumberStyles.Any); } if (targetClass.hearDistMax == 0f) { //Log.Out("EAISetNearestEntityAsTargetCompanion-SetData 3"); targetClass.hearDistMax = 50f; } targetClass.seeDistMax = 0f; if (i + 2 < array.Length) { //Log.Out("EAISetNearestEntityAsTargetCompanion-SetData 4"); targetClass.seeDistMax = StringParsers.ParseFloat(array[i + 2], 0, -1, NumberStyles.Any); } if (targetClass.type == typeof(EntityPlayer)) { //Log.Out("EAISetNearestEntityAsTargetCompanion-SetData 5"); this.playerTargetClassIndex = this.targetClasses.Count; } this.targetClasses.Add(targetClass); } //Log.Out("EAISetNearestEntityAsTargetCompanion-SetData 6"); } } public bool NPCEAICanProceed() { bool result = true; if (this.theEntity.Buffs.GetCustomVar("onMission") == 1f || this.theEntity.Buffs.GetCustomVar("$FR_NPC_Respawn") == 1f || this.theEntity.Buffs.GetCustomVar("$FR_NPC_Hidden") == 1f ) { //Log.Out("EAISetNearestEntityAsTargetCompanion-NPCEAICanProceed 1"); return false; } bool stopAttacking = this.theEntity.Buffs.HasBuff("FuriousRamsayBuffPauseAttack") || this.theEntity.Buffs.HasBuff("buffNPCModStopAttacking") || this.theEntity.Buffs.HasBuff("FuriousRamsayStandStill"); if (stopAttacking) { //Log.Out("EAISetNearestEntityAsTargetCompanion-NPCEAICanProceed 2"); this.theEntity.SetRevengeTarget(null); this.theEntity.SetAttackTarget(null, 0); return false; } return result; } public override bool CanExecute() { if (!NPCEAICanProceed()) { return false; } this.FindTarget(); if (!this.closeTargetEntity) { //Log.Out($"! closeTargetEntity: {closeTargetEntity}"); return false; } this.targetEntity = this.closeTargetEntity; this.targetPlayer = (this.closeTargetEntity as EntityPlayer); //Log.Out("EAISetNearestEntityAsTargetCompanion-CanExecute this.targetEntity: " + this.targetEntity.EntityClass.entityClassName); return true; } private void FindTarget() { //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget START"); this.closeTargetDist = float.MaxValue; this.closeTargetEntity = null; float seeDistance = RebirthVariables.customDistanceHunting; //this.theEntity.GetSeeDistance(); if (this.theEntity.Buffs.HasBuff("buffNPCModFullControlMode") && this.theEntity.Buffs.GetCustomVar("CurrentOrder") == (int)EntityUtilities.Orders.Follow) { seeDistance = RebirthVariables.customDistanceFullControl; } //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget this.targetClasses.Count " + this.targetClasses.Count); for (int i = 0; i < this.targetClasses.Count; i++) { //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget i: " + i); EAISetNearestEntityAsTargetCompanion.TargetClass targetClass = this.targetClasses[i]; float num = 100; //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget seeDistance " + seeDistance); //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget targetClass.seeDistMax " + targetClass.seeDistMax); //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget num " + num); //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget this.theEntity.IsSleeping " + this.theEntity.IsSleeping); //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget this.theEntity.HasInvestigatePosition " + this.theEntity.HasInvestigatePosition); bool hasInvestigatePosition = false; // this.theEntity.HasInvestigatePosition; if (!this.theEntity.IsSleeping && !hasInvestigatePosition) { //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget 1"); this.theEntity.world.GetEntitiesInBounds(targetClass.type, BoundsUtils.ExpandBounds(this.theEntity.boundingBox, num, num, num), EAISetNearestEntityAsTargetCompanion.list); EAISetNearestEntityAsTargetCompanion.list.Sort(this.sorter); int j = 0; //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget EAISetNearestEntityAsTargetCompanion.list.Count " + EAISetNearestEntityAsTargetCompanion.list.Count); while (j < EAISetNearestEntityAsTargetCompanion.list.Count) { EntityAlive entityAlive = (EntityAlive)EAISetNearestEntityAsTargetCompanion.list[j]; //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget j: " + j + " / entityAlive: " + entityAlive.EntityClass.entityClassName); //if (!(entityAlive is EntityDrone)) { //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget 2"); bool check = base.check(entityAlive); bool shouldAttack = RebirthUtilities.VerifyFactionStanding(this.theEntity, entityAlive); //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget check: " + check); //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget shouldAttack: " + shouldAttack); if (!check && entityAlive.entityId != this.theEntity.entityId && shouldAttack) { int OwnerID = (int)this.theEntity.Buffs.GetCustomVar("$Leader"); if (OwnerID > 0) { //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget HAS OWNER"); EntityPlayer entityPlayer = (EntityPlayer)this.theEntity.world.GetEntity(OwnerID); if (entityPlayer != null) { //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget FOUND OWNER"); if (entityPlayer.CanEntityBeSeen(entityAlive) && !(entityAlive is EntitySupplyCrate)) { check = true; //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget OWNER CAN SEE TARGET: " + entityAlive.EntityClass.entityClassName); } } } } //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget check: " + check); if (check && (!entityAlive.IsSleeping || entityAlive is EntityAnimalSnake)) { //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget entityAlive.EntityClass.entityClassName: " + entityAlive.EntityClass.entityClassName); float distance = this.theEntity.GetDistance(entityAlive); //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget this.closeTargetDist: " + this.closeTargetDist); //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget distance: " + distance); bool bypassDistance = (entityAlive.Buffs.GetCustomVar("$FuriousRamsayAttacking") == 1f || entityAlive.Buffs.GetCustomVar("$FuriousRamsayAttacked") == 1f || this.theEntity.Buffs.HasBuff("buffNPCModThreatControlMode") ); if (bypassDistance && distance > 50) { bypassDistance = false; } if (this.theEntity.HasAnyTags(FastTags.Parse("allyanimal")) || this.theEntity.HasAnyTags(FastTags.Parse("melee"))) { //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget IS MELEE"); if ( entityAlive.EntityClass.Tags.Test_AnySet(FastTags.Parse("nomeleetracking"))) { //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget NO ANIMAL TRACKING"); if (this.theEntity.position.y < entityAlive.position.y - 4) { //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget TOO HIGH: " + entityAlive.EntityClass.entityClassName); j++; continue; } } } //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget bypassDistance: " + bypassDistance); //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget distance: " + distance); //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget seeDistance: " + seeDistance); if (bypassDistance || distance < seeDistance) { //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget A"); this.closeTargetDist = distance; this.closeTargetEntity = entityAlive; this.lastSeenPos = entityAlive.position; //Log.Out($"EAI SetNearestEntityAsTargetCompanion - FindTarget entityAlive: {entityAlive.EntityClass.entityClassName}"); break; } else { //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget B"); int OwnerID = (int)this.theEntity.Buffs.GetCustomVar("$Leader"); //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget OwnerID: " + OwnerID); EntityPlayer owner = null; if (OwnerID > 0) { //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget HAS OWNER"); EntityPlayer entityPlayer = (EntityPlayer)this.theEntity.world.GetEntity(OwnerID); if (entityPlayer != null) { //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget FOUND OWNER"); owner = entityPlayer; } } if (owner != null) { distance = owner.GetDistance(entityAlive); //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget DISTANCE TO OWNER: " + distance); if (distance < seeDistance + 5) { //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget OWNER distance: " + distance); //Log.Out("EAISetNearestEntityAsTargetCompanion-FindTarget entityAlive: " + entityAlive.EntityClass.entityClassName); this.closeTargetDist = distance; this.closeTargetEntity = entityAlive; this.lastSeenPos = entityAlive.position; break; } } } break; } else { j++; } } } EAISetNearestEntityAsTargetCompanion.list.Clear(); } } //Log.Out($"FindTarget END - closeTargetEntity: {closeTargetEntity}"); } public override void Start() { this.theEntity.SetAttackTarget(this.targetEntity, 200); this.theEntity.ConditionalTriggerSleeperWakeUp(); base.Start(); } public override bool Continue() { if (!NPCEAICanProceed()) { return false; } if (this.targetEntity.IsDead() || this.theEntity.distraction != null) { //Log.Out("EAISetNearestEntityAsTargetCompanion-Continue 5"); if (this.theEntity.GetAttackTarget() == this.targetEntity) { //Log.Out("SetNearestEntityAsTarget - Continue - GetAttackTarget() == this.targetEntity and isDead or distraction not null"); this.theEntity.SetAttackTarget(null, 0); } //Log.Out($"returning false here"); return false; } this.findTime += 0.05f; if (this.findTime > 2f) { //Log.Out("EAISetNearestEntityAsTargetCompanion-Continue 7"); this.findTime = 0f; this.FindTarget(); if (this.closeTargetEntity && this.closeTargetEntity != this.targetEntity) { //Log.Out("EAISetNearestEntityAsTargetCompanion-Continue we have a close target and its not equal to targetEntity return false"); return false; } } if (this.theEntity.GetAttackTarget() != this.targetEntity) { //Log.Out("EAISetNearestEntityAsTargetCompanion-Continue this.theEntity.GetAttackTarget() != this.targetEntity"); return false; } //Log.Out("EAISetNearestEntityAsTargetCompanion-Continue 19"); 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 const float cHearDistMax = 50f; 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; } }