using System; using System.Collections.Generic; using System.Globalization; using System.Text; using System.Xml; using System.Xml.Linq; using GamePath; using UnityEngine; using UnityEngine.Scripting; [Preserve] public class EAIApproachAndAttackTargetCompanion : EAIBase { public override void Init(EntityAlive _theEntity) { base.Init(_theEntity); this.MutexBits = 3; this.executeDelay = 0.1f; } 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(',', StringSplitOptions.None); for (int i = 0; i < array.Length; i += 2) { EAIApproachAndAttackTargetCompanion.TargetClass targetClass = default(EAIApproachAndAttackTargetCompanion.TargetClass); targetClass.type = EntityFactory.GetEntityType(array[i]); targetClass.chaseTimeMax = 0f; if (i + 1 < array.Length) { targetClass.chaseTimeMax = StringParsers.ParseFloat(array[i + 1], 0, -1, NumberStyles.Any); } this.targetClasses.Add(targetClass); if (targetClass.type == typeof(EntityEnemyAnimal)) { targetClass.type = typeof(EntityAnimalSnake); this.targetClasses.Add(targetClass); } } } } public bool NPCEAICanProceed(bool skipTargetVerification = false) { 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("EAIApproachAndAttackTargetCompanion-NPCEAICanProceed 1"); return false; } /*if (this.owner == null) { this.owner = (EntityAlive)EntityUtilities.GetOwner(this.theEntity.entityId); }*/ EntityUtilities.CheckDistanceToLeader(this.theEntity, this.targetPlayer); this.entityTarget = this.theEntity.GetAttackTarget(); /*if (!skipTargetVerification && this.entityTarget == null) { //Log.Out("EAIApproachAndAttackTargetCompanion-NPCEAICanProceed 2b"); return false; }*/ if (this.entityTarget != null) { if (this.entityTarget.IsDead()) { //Log.Out("EAIApproachAndAttackTargetCompanion-NPCEAICanProceed 2c"); this.theEntity.SetRevengeTarget(null); this.theEntity.SetAttackTarget(null, 0); return false; } if (!this.theEntity.CanEntityBeSeen(this.entityTarget)) { //Log.Out("EAIApproachAndAttackTargetCompanion-NPCEAICanProceed 2d"); return false; } bool shouldAttack = RebirthUtilities.VerifyFactionStanding(this.theEntity, this.entityTarget); if (!shouldAttack) { //Log.Out("EAIApproachAndAttackTargetCompanion-NPCEAICanProceed 2e"); //this.theEntity.SetAttackTarget(null, 0); //this.theEntity.SetRevengeTarget(null); return false; } //Log.Out("EAIApproachAndAttackTargetCompanion-NPCEAICanProceed 2f, this.entityTarget: " + this.entityTarget.EntityClass.entityClassName); } if (this.theEntity.emodel.IsRagdollActive) { //Log.Out("EAIApproachAndAttackTargetCompanion-NPCEAICanProceed 3"); return false; } if (this.theEntity.sleepingOrWakingUp || this.theEntity.bodyDamage.CurrentStun != EnumEntityStunType.None || (this.theEntity.Jumping && !this.theEntity.isSwimming)) { //Log.Out("EAIApproachAndAttackTargetCompanion-NPCEAICanProceed 4"); return false; } bool stopAttacking = this.theEntity.Buffs.HasBuff("FuriousRamsayBuffPauseAttack") || this.theEntity.Buffs.HasBuff("buffNPCModStopAttacking") || this.theEntity.Buffs.HasBuff("FuriousRamsayStandStill"); if (stopAttacking) { //Log.Out("EAIApproachAndAttackTargetCompanion-NPCEAICanProceed 5"); this.theEntity.SetRevengeTarget(null); this.theEntity.SetAttackTarget(null, 0); //return false; } if (this.theEntity.sleepingOrWakingUp || this.theEntity.bodyDamage.CurrentStun != EnumEntityStunType.None) { //Log.Out("EAIApproachAndAttackTargetCompanion-NPCEAICanProceed 6"); return false; } return result; } public override bool CanExecute() { CheckAnimator(); backingUp = false; this.theEntity.Buffs.SetCustomVar("$IsBackingUp", 0f); //Log.Out("EAIApproachAndAttackTargetCompanion-CanExecute START"); if (!NPCEAICanProceed(true)) { return false; } EntityAliveV2 npc = (EntityAliveV2)this.theEntity; if (this.entityTarget != null) { //Log.Out("EAIApproachAndAttackTargetCompanion-CanExecute this.entityTarget: " + this.entityTarget.EntityClass.entityClassName); Type type = this.entityTarget.GetType(); for (int i = 0; i < this.targetClasses.Count; i++) { EAIApproachAndAttackTargetCompanion.TargetClass targetClass = this.targetClasses[i]; if (targetClass.type != null && targetClass.type.IsAssignableFrom(type)) { this.chaseTimeMax = targetClass.chaseTimeMax; //Log.Out("EAIApproachAndAttackTargetCompanion-CanExecute 5"); return true; } } //Log.Out("EAIApproachAndAttackTargetCompanion-CanExecute 6"); return false; } else { //Log.Out("EAIApproachAndAttackTargetCompanion-CanExecute currentOrder: " + ((EntityNPCRebirth)this.theEntity).currentOrder); if (((EntityNPCRebirth)this.theEntity).currentOrder == (int)EntityUtilities.Orders.Stay) { //Log.Out("EAIApproachAndAttackTargetCompanion-CanExecute checkEntityPosition"); checkEntityPosition(); } if (this.targetPlayer == null) { //Log.Out("EAIApproachAndAttackTargetCompanion-CanExecute 2"); this.OwnerID = (int)this.theEntity.Buffs.GetCustomVar("$Leader"); if (this.OwnerID > 0) { //Log.Out("EAIApproachAndAttackTargetCompanion-CanExecute this.OwnerID: " + this.OwnerID); EntityPlayer entityPlayer = (EntityPlayer)this.theEntity.world.GetEntity(this.OwnerID); if (entityPlayer != null) { //Log.Out("EAIApproachAndAttackTargetCompanion-CanExecute FOUND OWNER"); this.targetPlayer = entityPlayer; } } } if (this.targetPlayer == null) { //Log.Out("EAIApproachAndAttackTargetCompanion-CanExecute NO OWNER"); return false; } } //Log.Out("EAIApproachAndAttackTargetCompanion-CanExecute END: GO AHEAD"); return true; } public void checkEntityPosition() { //Log.Out("EAIApproachAndAttackTargetCompanion-checkEntityPosition START"); if (!this.theEntity.onGround) return; if (this.entityTarget != null) { //Log.Out("EAIApproachAndAttackTargetCompanion-checkEntityPosition HAS ATTACK TARGET"); return; } if (!this.theEntity.navigator.noPathAndNotPlanningOne()) { //Log.Out("EAIApproachAndAttackTargetCompanion-checkEntityPosition HAVE PATH"); return; } if (this.theEntity.Buffs.HasBuff("buffTalkingTo")) { //Log.Out("EAIApproachAndAttackTargetCompanion-checkEntityPosition IS TALKING"); return; } EntityAliveV2 npc = this.theEntity as EntityAliveV2; if (npc == null) { //Log.Out("EAIApproachAndAttackTargetCompanion-checkEntityPosition EXIT"); return; } //Log.Out("EAIApproachAndAttackTargetCompanion-checkEntityPosition STAY 1, npc.position: (" + npc.position + ") / npc.guardPosition: (" + npc.guardPosition + ")"); if (npc.guardPosition == Vector3.zero) { //Log.Out("EAIApproachAndAttackTargetCompanion-checkEntityPosition NO GUARD POSITION"); return; } Vector3 entityPosition = EntityUtilities.CenterPosition(npc.position); Vector3 guardPosition = EntityUtilities.CenterPosition(npc.guardPosition); if (entityPosition != guardPosition) { //Log.Out("EAIApproachAndAttackTargetCompanion-checkEntityPosition STAY 2, npc.position: (" + npc.position + ") / npc.guardPosition: (" + npc.guardPosition + ")"); npc.moveHelper.SetMoveTo(guardPosition, true); npc.navigator?.clearPath(); npc.FindPath( npc.guardPosition, npc.GetMoveSpeedPanic(), false, (EAIBase)this); } else { this.theEntity.motion = Vector3.zero; this.theEntity.navigator?.clearPath(); this.theEntity.moveHelper?.Stop(); this.theEntity.speedForward = 0; this.theEntity.speedStrafe = 0; //this.theEntity.navigator?.clearPath(); //this.theEntity.moveHelper.Stop(); //this.theEntity.speedForward = 0; /*Vector3 entityRotation = EntityUtilities.CenterPosition(npc.rotation); Vector3 guardRotation = EntityUtilities.CenterPosition(npc.guardLookPosition); //Log.Out("EAIApproachAndAttackTargetCompanion-checkEntityPosition STAY 3, npc.position: (" + npc.position + ") / npc.guardPosition: (" + npc.guardPosition + ")"); //Log.Out("EAIApproachAndAttackTargetCompanion-checkEntityPosition entityRotation: " + entityRotation); //Log.Out("EAIApproachAndAttackTargetCompanion-checkEntityPosition guardRotation: " + guardRotation); //Log.Out("EAIApproachAndAttackTargetCompanion-checkEntityPosition npc.rotation: " + npc.rotation); //Log.Out("EAIApproachAndAttackTargetCompanion-checkEntityPosition npc.guardLookPosition: " + npc.guardLookPosition); if (entityRotation != guardRotation && npc.rotation != npc.guardLookPosition) { //Log.Out("EAIApproachAndAttackTargetCompanion-checkEntityPosition STAY ROTATE"); //npc.rotation = npc.guardLookPosition; npc.SetLookPosition(npc.guardLookPosition); npc.RotateTo( npc.guardLookPosition.x, npc.guardLookPosition.y, npc.guardLookPosition.z, 360f, 360f); } else { //Log.Out("EAIApproachAndAttackTargetCompanion-checkEntityPosition STAY IS IN RIGHT POSITION AND ROTATION"); }*/ //Log.Out("EAIApproachAndAttackTargetCompanion-checkEntityPosition SetLookPosition"); npc.SetLookPosition(npc.guardLookPosition); npc.RotateTo( npc.guardLookPosition.x, npc.guardLookPosition.y, npc.guardLookPosition.z, 360f, 360f); } } public override void Start() { if (this.entityTarget != null) { this.entityTargetPos = this.entityTarget.position; } else { this.entityTargetPos = Vector3.zero; } this.entityTargetVel = Vector3.zero; this.entityPlayerVel = Vector3.zero; this.isTargetToEat = false; this.isEating = false; this.theEntity.IsEating = false; this.homeTimeout = (this.theEntity.IsSleeper ? 90f : this.chaseTimeMax); this.hasHome = (this.homeTimeout > 0f); this.isGoingHome = false; if (this.theEntity.ChaseReturnLocation == Vector3.zero) { this.theEntity.ChaseReturnLocation = (this.theEntity.IsSleeper ? this.theEntity.SleeperSpawnPosition : this.theEntity.position); } this.pathCounter = 0; this.relocateTicks = 0; this.attackTimeout = 5; animator = this.theEntity.emodel.avatarController.GetAnimator(); } public override bool Continue() { //Log.Out("EAIApproachAndAttackTargetCompanion-Continue START"); CheckAnimator(); backingUp = false; this.theEntity.Buffs.SetCustomVar("$IsBackingUp", 0f); if (!NPCEAICanProceed()) { return false; } bool result = false; EntityAlive attackTarget = this.theEntity.GetAttackTarget(); if (attackTarget != null) { //Log.Out("EAIApproachAndAttackTargetCompanion-Continue 1, attackTarget: " + attackTarget.EntityClass.entityClassName); } else { //Log.Out("EAIApproachAndAttackTargetCompanion-Continue currentOrder: " + ((EntityNPCRebirth)this.theEntity).currentOrder); if (((EntityNPCRebirth)this.theEntity).currentOrder == (int)EntityUtilities.Orders.Stay) { //Log.Out("EAIApproachAndAttackTargetCompanion-Continue checkEntityPosition"); checkEntityPosition(); } //Log.Out("EAIApproachAndAttackTargetCompanion-Continue NO ATTACK TARGET"); } if (this.isGoingHome) { //Log.Out("EAIApproachAndAttackTargetCompanion-Continue 3, " + result); result = !attackTarget && this.theEntity.ChaseReturnLocation != Vector3.zero; return result; } result = attackTarget && !(attackTarget != this.entityTarget); if (!result && this.targetPlayer != null) { //Log.Out("EAIApproachAndAttackTargetCompanion-Continue WILL CONTINUE GIVEN HAS OWNER"); return true; } //Log.Out("EAIApproachAndAttackTargetCompanion-Continue 4, " + result); return result; } public override void Reset() { this.theEntity.IsEating = false; this.theEntity.motion = Vector3.zero; this.theEntity.navigator?.clearPath(); this.theEntity.moveHelper?.Stop(); this.theEntity.speedForward = 0; this.theEntity.speedStrafe = 0; //this.theEntity.navigator?.clearPath(); //this.theEntity.moveHelper.Stop(); if (this.blockTargetTask != null) { this.blockTargetTask.canExecute = false; } } public void CheckAnimator() { if (animator && !backingUp) { animator.SetBool("isBackingUp", false); } } public override void Update() { CheckAnimator(); backingUp = false; this.theEntity.Buffs.SetCustomVar("$IsBackingUp", 0f); if (!NPCEAICanProceed()) { return; } if (this.theEntity.Climbing) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 19"); return; } EntityAliveV2 npc = this.theEntity as EntityAliveV2; if (npc == null) { return; } if (this.relocateTicks > 0) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 2"); if (!this.theEntity.navigator.noPathAndNotPlanningOne()) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 3"); this.relocateTicks--; this.theEntity.moveHelper.SetFocusPos(this.entityTarget.position); return; } this.relocateTicks = 0; } EntityUtilities.CheckForClosedDoor(this.theEntity); float targetXZDistanceSq = 0; float distance = 0; if (this.entityTarget != null) { distance = this.entityTarget.GetDistance(this.theEntity); } bool isRanged = false; if (this.theEntity.HasAnyTags(FastTags.Parse("ranged"))) { _actionIndex = 1; isRanged = true; } bool skipFollow = false; /*if (this.entityTarget != null && isRanged && ((((EntityNPCRebirth)this.theEntity).currentOrder == (int)EntityUtilities.Orders.Follow) || this.theEntity.Buffs.GetCustomVar("$Leader") == 0)) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update distance: " + distance); float distanceFromTarget = 4f; if (this.entityTarget is EntityPlayer) { distanceFromTarget = 5f; } if (distance < distanceFromTarget) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 6"); //if (!this.entityTarget.emodel.IsRagdollActive) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 6a"); int maxDistanceFromLeader = UnityEngine.Random.Range(10, 25); backingUp = true; this.theEntity.Buffs.SetCustomVar("$IsBackingUp", 1f); Animator animator = this.theEntity.emodel.avatarController.GetAnimator(); if (animator) { animator.SetBool("isBackingUp", true); } EntityUtilities.BackupHelper(this.theEntity, this.entityTarget, distanceFromTarget * 3f, maxDistanceFromLeader); } skipFollow = true; } else { this.theEntity.Buffs.SetCustomVar("$IsBackingUp", 0f); skipFollow = false; Animator animator = this.theEntity.emodel.avatarController.GetAnimator(); if (animator) { animator.SetBool("isBackingUp", false); } } }*/ if (!skipFollow && this.entityTarget == null) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update currentOrder: " + ((EntityNPCRebirth)this.theEntity).currentOrder); if (((EntityNPCRebirth)this.theEntity).currentOrder != (int)EntityUtilities.Orders.Stay) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 1"); if (this.relocateTicks > 0) { //Log.Out("EAIFollowLeaderCompanion-Update 2"); if (!this.theEntity.navigator.noPathAndNotPlanningOne()) { //Log.Out("EAIFollowLeaderCompanion-Update 3"); this.relocateTicks--; this.theEntity.moveHelper.SetFocusPos(this.targetPlayer.position); return; } this.relocateTicks = 0; } Vector3 vector2 = this.targetPlayer.position; Vector3 a = theEntity.position - vector2; //Log.Out("EAIFollowLeaderCompanion-Update entityTargetPosn: " + vector2); //Log.Out("EAIFollowLeaderCompanion-Update a: " + a); //Log.Out("EAIFollowLeaderCompanion-Update a.sqrMagnitude: " + a.sqrMagnitude); //Log.Out("EAIFollowLeaderCompanion-Update this.OwnerID: " + this.theEntity.Buffs.GetCustomVar("$Leader")); this.OwnerID = (int)this.theEntity.Buffs.GetCustomVar("$Leader"); float magnitude = 3f; // 30f; bool isClient = SingletonMonoBehaviour.Instance.IsClient; if (isClient) { magnitude = 3f; } //Log.Out("EAIFollowLeaderCompanion-Update magnitude: " + magnitude); if (this.targetPlayer.entityId == this.OwnerID && a.sqrMagnitude < magnitude) { //Log.Out("EAIFollowLeaderCompanion-Update Entity is too close. Ending pathing."); this.theEntity.motion = Vector3.zero; this.theEntity.navigator?.clearPath(); this.theEntity.moveHelper?.Stop(); this.theEntity.speedForward = 0; this.theEntity.speedStrafe = 0; //this.theEntity.navigator?.clearPath(); //this.theEntity.moveHelper.Stop(); pathCounter = 0; return; } if (this.targetPlayer.entityId == this.OwnerID) { if (!this.theEntity.HasAnyTags(FastTags.Parse("allyanimal"))) { this.theEntity.Crouching = this.targetPlayer.Crouching; } //Log.Out("EAIFollowLeaderCompanion-Update theEntity.moveHelper.BlockedTime: " + theEntity.moveHelper.BlockedTime); if (theEntity.moveHelper.BlockedTime > 3f) { npc.TeleportToPlayer(this.targetPlayer, false); } } //Log.Out("EAIFollowLeaderCompanion-Update SetLookPosition"); theEntity.SetLookPosition(vector2); theEntity.RotateTo(vector2.x, vector2.y + 2, vector2.z, 8f, 8f); if (a.sqrMagnitude < 1f) { //Log.Out("EAIFollowLeaderCompanion-Update 6"); this.entityPlayerVel = this.entityPlayerVel * 0.7f + a * 0.3f; } //this.entityPlayerPos = vector2; this.theEntity.moveHelper.CalcIfUnreachablePos(); float num2; float num3; num2 = 1.095f; num3 = Utils.FastMax(0.7f, num2 - 0.35f); float num4 = num3 * num3; float num5 = 4f; if (this.theEntity.IsFeral) { num5 = 8f; } num5 = base.RandomFloat * num5; targetXZDistanceSq = this.GetTargetXZDistanceSqPlayer(num5); float num6 = vector2.y - this.theEntity.position.y; float num7 = Utils.FastAbs(num6); bool flag = targetXZDistanceSq <= num4 && num7 < 1f; if (!flag) { //Log.Out("EAIFollowLeaderCompanion-Update 9"); if (num7 < 3f && !PathFinderThread.Instance.IsCalculatingPath(this.theEntity.entityId)) { //Log.Out("EAIFollowLeaderCompanion-Update 10"); PathEntity path = this.theEntity.navigator.getPath(); if (path != null && path.NodeCountRemaining() <= 2) { //Log.Out("EAIFollowLeaderCompanion-Update 11"); this.pathCounter = 0; } } int num = this.pathCounter - 1; this.pathCounter = num; //Log.Out("EAIFollowLeaderCompanion-Update num: " + num); //Log.Out("EAIFollowLeaderCompanion-Update CanNavigatePath: " + this.theEntity.CanNavigatePath()); //Log.Out("EAIFollowLeaderCompanion-Update IsCalculatingPath: " + PathFinderThread.Instance.IsCalculatingPath(this.theEntity.entityId)); if (num <= 0 && this.theEntity.CanNavigatePath() && !PathFinderThread.Instance.IsCalculatingPath(this.theEntity.entityId)) { //Log.Out("EAIFollowLeaderCompanion-Update 12"); this.pathCounter = 6 + base.GetRandom(10); Vector3 moveToLocation = EntityUtilities.GetMoveToLocation(this.theEntity, this.targetPlayer.position, 5); if (moveToLocation.y - this.theEntity.position.y < -8f) { //Log.Out("EAIFollowLeaderCompanion-Update 13"); this.pathCounter += 40; if (base.RandomFloat < 0.2f) { //Log.Out("EAIFollowLeaderCompanion-Update 14"); this.seekPosOffset.x = this.seekPosOffset.x + (base.RandomFloat * 0.6f - 0.3f); this.seekPosOffset.y = this.seekPosOffset.y + (base.RandomFloat * 0.6f - 0.3f); } moveToLocation.x += this.seekPosOffset.x; moveToLocation.z += this.seekPosOffset.y; } else { //Log.Out("EAIFollowLeaderCompanion-Update 15"); float num8 = (moveToLocation - this.theEntity.position).magnitude - 5f; if (num8 > 0f) { //Log.Out("EAIFollowLeaderCompanion-Update 16"); if (num8 > 60f) { //Log.Out("EAIFollowLeaderCompanion-Update 17"); num8 = 60f; } this.pathCounter += (int)(num8 / 20f * 20f); } } //Log.Out("EAIFollowLeaderCompanion-Update $IsBackingUp: " + this.theEntity.Buffs.GetCustomVar("$IsBackingUp")); // THIS WORKS GREAT FOR FOLLOWING THE LEADER BUT MAKES THE ENTITY MOVE INTO THE TARGET this.theEntity.navigator?.clearPath(); this.theEntity.FindPath(moveToLocation, this.theEntity.GetMoveSpeedAggro(), false, (EAIBase)this); } } if (this.theEntity.Climbing) { //Log.Out("EAIFollowLeaderCompanion-Update 18"); return; } } else { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 19 checkEntityPosition"); checkEntityPosition(); } return; } /*else { EntityAlive attackTarget = this.theEntity.GetAttackTarget(); if ((attackTarget && !(attackTarget != this.entityTarget)) == false) { //Log.Out("EAIFollowLeaderCompanion-Update NO NEED TO UPDATE"); return; } }*/ ItemValue holdingItemItemValue = this.theEntity.inventory.holdingItemItemValue; int holdingItemIdx = this.theEntity.inventory.holdingItemIdx; ItemAction itemAction = this.theEntity.inventory.holdingItem.Actions[_actionIndex]; Vector3 curEntTargPos = this.entityTarget.position; //Log.Out("EAIApproachAndAttackTargetCompanion-Update B entityClassName: " + this.entityTarget.EntityClass.entityClassName); //Log.Out("EAIApproachAndAttackTargetCompanion-Update SetLookPosition"); theEntity.SetLookPosition(curEntTargPos); theEntity.RotateTo(curEntTargPos.x, curEntTargPos.y + 2, curEntTargPos.z, 8f, 8f); Vector3 targetDirection = theEntity.position - curEntTargPos; //Log.Out("EAIApproachAndAttackTargetCompanion-Update this.entityTarget.position: " + this.entityTarget.position); //Log.Out("EAIApproachAndAttackTargetCompanion-Update entityTargetPosn: " + curEntTargPos); //Log.Out("EAIApproachAndAttackTargetCompanion-Update targetDirection: " + targetDirection); //Log.Out("EAIApproachAndAttackTargetCompanion-Update targetDirection.sqrMagnitude: " + targetDirection.sqrMagnitude); /* if (this.theEntity.GetAttackTarget() != null) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update GetAttackTarget: " + this.theEntity.GetAttackTarget().EntityClass.entityClassName); } else { //Log.Out("EAIApproachAndAttackTargetCompanion-Update NO ATTACK TARGET"); } */ bool isTargetWithinItemActionRange = false; if (targetDirection.sqrMagnitude < 1f) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 7"); this.entityTargetVel = this.entityTargetVel * 0.7f + targetDirection * 0.3f; } this.entityTargetPos = curEntTargPos; this.attackTimeout--; this.theEntity.moveHelper.CalcIfUnreachablePos(); float itemActionRange; float maxItemActionRange; itemActionRange = 1.095f; if (itemAction != null) { itemActionRange = itemAction.Range; if (itemActionRange == 0f) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 8"); itemActionRange = EffectManager.GetItemValue(PassiveEffects.MaxRange, holdingItemItemValue, 0f); } } maxItemActionRange = Utils.FastMax(0.7f, itemActionRange - 0.35f); //Log.Out("EAIApproachAndAttackTargetCompanion-Update 9a, itemActionRange: " + itemActionRange); //Log.Out("EAIApproachAndAttackTargetCompanion-Update 9b, maxItemActionRange: " + maxItemActionRange); float maxRangeSquared = maxItemActionRange * maxItemActionRange; float estimatedTimeInTicks = 4f; if (this.theEntity.IsFeral) { estimatedTimeInTicks = 8f; } estimatedTimeInTicks = base.RandomFloat * estimatedTimeInTicks; targetXZDistanceSq = this.GetTargetXZDistanceSq(estimatedTimeInTicks); float yDiff = curEntTargPos.y - this.theEntity.position.y; float absoluteYDiff = Utils.FastAbs(yDiff); float entityDistance = Vector3.Distance(this.theEntity.position, curEntTargPos); isTargetWithinItemActionRange = entityDistance < maxItemActionRange; //Log.Out("EAIApproachAndAttackTargetCompanion-Update entityDistance: " + entityDistance); //Log.Out("EAIApproachAndAttackTargetCompanion-Update isTargetWithinItemActionRange: " + isTargetWithinItemActionRange); //Log.Out("EAIApproachAndAttackTargetCompanion-Update maxRangeSquared: " + maxRangeSquared); //Log.Out("EAIApproachAndAttackTargetCompanion-Update absoluteYDiff: " + absoluteYDiff); //Log.Out("EAIApproachAndAttackTargetCompanion-Update yDiff: " + yDiff); //Log.Out("EAIApproachAndAttackTargetCompanion-Update targetXZDistanceSq: " + targetXZDistanceSq); //Log.Out("EAIApproachAndAttackTargetCompanion-Update backingUp: " + backingUp); //Log.Out("EAIApproachAndAttackTargetCompanion-Update CurrentOrder: " + ((EntityNPCRebirth)this.theEntity).currentOrder); //Log.Out("EAIApproachAndAttackTargetCompanion-Update $Leader: " + this.theEntity.Buffs.GetCustomVar("$Leader")); if (!backingUp && ((((EntityNPCRebirth)this.theEntity).currentOrder == (int)EntityUtilities.Orders.Follow) || this.theEntity.Buffs.GetCustomVar("$Leader") == 0)) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 10a"); if (!isTargetWithinItemActionRange) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 10c"); if (absoluteYDiff < 3f && !PathFinderThread.Instance.IsCalculatingPath(this.theEntity.entityId)) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 11"); PathEntity path = this.theEntity.navigator.getPath(); if (path != null && path.NodeCountRemaining() <= 2) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 12"); this.pathCounter = 0; } } int pathCounterLessOne = this.pathCounter - 1; this.pathCounter = pathCounterLessOne; if (pathCounterLessOne <= 0 && this.theEntity.CanNavigatePath() && !PathFinderThread.Instance.IsCalculatingPath(this.theEntity.entityId)) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 13"); this.pathCounter = 6 + base.GetRandom(10); Vector3 moveToLocation = EntityUtilities.GetMoveToLocation(this.theEntity, this.entityTarget.position, 0); if (isRanged) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update BEFORE moveToLocation: " + moveToLocation); //moveToLocation = RandomPositionGenerator.CalcAway(this.theEntity, 2, 5, 5, this.entityTarget.position); //Log.Out("EAIApproachAndAttackTargetCompanion-Update AFTER moveToLocation: " + moveToLocation); } if (moveToLocation.y - this.theEntity.position.y < -8f) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 14"); this.pathCounter += 40; if (base.RandomFloat < 0.2f) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 15"); this.seekPosOffset.x = this.seekPosOffset.x + (base.RandomFloat * 0.6f - 0.3f); this.seekPosOffset.y = this.seekPosOffset.y + (base.RandomFloat * 0.6f - 0.3f); } moveToLocation.x += this.seekPosOffset.x; moveToLocation.z += this.seekPosOffset.y; } else { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 16"); float num8 = (moveToLocation - this.theEntity.position).magnitude - 5f; if (num8 > 0f) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 17"); if (num8 > 60f) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 18"); num8 = 60f; } this.pathCounter += (int)(num8 / 20f * 20f); } } // COMMENTED OUT TO REMOVE FORWARD MOVEMENT TOWARDS TARGET //this.theEntity.FindPath(moveToLocation, this.theEntity.GetMoveSpeedAggro(), true, (EAIBase)this); } } else { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 21"); this.theEntity.motion = Vector3.zero; this.theEntity.navigator?.clearPath(); this.theEntity.moveHelper?.Stop(); this.theEntity.speedForward = 0; this.theEntity.speedStrafe = 0; this.pathCounter = 0; } if (!isTargetWithinItemActionRange) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 19"); if (this.theEntity.navigator.noPathAndNotPlanningOne() && this.pathCounter > 0 && yDiff < 2.1f) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 20"); Vector3 moveToLocation2 = EntityUtilities.GetMoveToLocation(this.theEntity, this.entityTarget.position, 0); this.theEntity.moveHelper.SetMoveTo(moveToLocation2, true); } } float newItemActionRange = itemActionRange - 0.1f; float newRangeSquared = newItemActionRange * newItemActionRange; this.theEntity.IsBreakingBlocks = false; this.theEntity.IsBreakingDoors = false; if (this.theEntity.bodyDamage.HasLimbs && !this.theEntity.Electrocuted) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 23"); this.theEntity.RotateTo(curEntTargPos.x, curEntTargPos.y, curEntTargPos.z, 30f, 30f); } if (this.theEntity.GetDamagedTarget() == this.entityTarget || (this.entityTarget != null && this.entityTarget.GetDamagedTarget() == this.theEntity)) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 24"); this.homeTimeout = (this.theEntity.IsSleeper ? 90f : this.chaseTimeMax); if (this.blockTargetTask != null) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 25"); this.blockTargetTask.canExecute = false; } this.theEntity.ClearDamagedTarget(); if (this.entityTarget) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 26"); this.entityTarget.ClearDamagedTarget(); } } if (this.manager.groupCircle > 0f) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 27"); Entity targetIfAttackedNow = this.theEntity.GetTargetIfAttackedNow(); if (targetIfAttackedNow != this.entityTarget && (!this.entityTarget.AttachedToEntity || this.entityTarget.AttachedToEntity != targetIfAttackedNow)) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 28"); if (targetIfAttackedNow != null) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 29"); this.relocateTicks = 46; Vector3 vector3 = (this.theEntity.position - curEntTargPos).normalized * (newItemActionRange + 1.1f); float num11 = base.RandomFloat * 28f + 18f; if (base.RandomFloat < 0.5f) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 30"); num11 = -num11; } vector3 = Quaternion.Euler(0f, num11, 0f) * vector3; Vector3 targetPos = curEntTargPos + vector3; //Log.Out("EAIApproachAndAttackTargetCompanion-Update 30a FIND PATH"); // MAY BE REQUIRED - TESTING //this.theEntity.navigator?.clearPath(); //this.theEntity.FindPath(targetPos, this.theEntity.GetMoveSpeedAggro(), true, (EAIBase)this); } //Log.Out("EAIApproachAndAttackTargetCompanion-Update E entityClassName: " + this.entityTarget.EntityClass.entityClassName); //Log.Out("EAIApproachAndAttackTargetCompanion-Update 31"); return; } } } //Log.Out("EAIApproachAndAttackTargetCompanion-Update _actionIndex: " + _actionIndex); //Log.Out("EAIApproachAndAttackTargetCompanion-Update isRanged: " + isRanged); this.theEntity.SleeperSupressLivingSounds = false; if (this.theEntity.Buffs.HasBuff("buffReloadDelay") || this.theEntity.Buffs.HasBuff("buffReload2") || this.theEntity.Buffs.HasBuff("buffReload3") ) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 33"); return; } //Log.Out("EAIApproachAndAttackTargetCompanion-Update 34"); //Log.Out("EAIApproachAndAttackTargetCompanion-Update backingUp: " + backingUp); //Log.Out("EAIApproachAndAttackTargetCompanion-Update distance: " + distance); int rangeMax = 20; PrefabInstance poiatPosition = this.theEntity.world.GetPOIAtPosition(this.theEntity.position, false); if (poiatPosition != null) { //Give NPCs a better chance at a ragdoll when inside a POI rangeMax = 10; } if (this.entityTarget is EntityPlayer) { rangeMax = 100; } int chance = UnityEngine.Random.Range(1, rangeMax); if (chance < 10 && !this.entityTarget.emodel.IsRagdollActive && distance < this.theEntity.inventory.holdingItem.Actions[0].Range) { _actionIndex = 0; } if (_actionIndex == 1) { if (!isTargetWithinItemActionRange && this.theEntity.moveHelper.IsActive) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update Target isn't within range"); return; } } if (isTargetWithinItemActionRange) { if (this.theEntity.Buffs.HasBuff("buffRangedMeleeDelay")) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update HAS ATTACK DELAY BUFF"); return; } //Log.Out("EAIApproachAndAttackTargetCompanion-Update 35a"); if (npc.ExecuteAction(false, _actionIndex)) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 35b"); this.attackTimeout = this.theEntity.GetAttackTimeoutTicks(); if (isRanged && _actionIndex == 0) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update ADDED ATTACK DELAY BUFF"); this.theEntity.Buffs.AddBuff("buffRangedMeleeDelay"); } // Check the range on the item action ItemActionRanged.ItemActionDataRanged itemActionData = null; if (itemAction is ItemActionRanged itemActionRanged) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 36"); itemActionData = this.theEntity.inventory.holdingItemData.actionData[_actionIndex] as ItemActionRanged.ItemActionDataRanged; if (itemActionData != null) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 37"); // Check if we are already running. if (itemAction.IsActionRunning(itemActionData)) { //Log.Out("EAIApproachAndAttackTargetCompanion-Update 38"); return; } } } } } } private float GetTargetXZDistanceSq(float estimatedTicks) { Vector3 vector = this.entityTarget.position; vector += this.entityTargetVel * estimatedTicks; Vector3 vector2 = this.theEntity.position + this.theEntity.motion * estimatedTicks - vector; vector2.y = 0f; return vector2.sqrMagnitude; } private float GetTargetXZDistanceSqPlayer(float estimatedTicks) { Vector3 vector = this.targetPlayer.position; vector += this.entityPlayerVel * estimatedTicks; Vector3 vector2 = this.theEntity.position + this.theEntity.motion * estimatedTicks - vector; vector2.y = 0f; return vector2.sqrMagnitude; } public override string ToString() { ItemValue holdingItemItemValue = this.theEntity.inventory.holdingItemItemValue; int holdingItemIdx = this.theEntity.inventory.holdingItemIdx; ItemAction itemAction = holdingItemItemValue.ItemClass.Actions[holdingItemIdx]; float num = 1.095f; if (itemAction != null) { num = itemAction.Range; if (num == 0f) { num = EffectManager.GetItemValue(PassiveEffects.MaxRange, holdingItemItemValue, 0f); } } float value = num - 0.1f; float targetXZDistanceSq = this.GetTargetXZDistanceSq(0f); return string.Format("{0}, {1}{2}{3}{4}{5} dist {6} rng {7} timeout {8}", new object[] { base.ToString(), this.entityTarget ? this.entityTarget.EntityName : "", this.theEntity.CanSee(this.entityTarget) ? "(see)" : "", this.theEntity.navigator.noPathAndNotPlanningOne() ? "(-path)" : (this.theEntity.navigator.noPath() ? "(!path)" : ""), this.isTargetToEat ? "(eat)" : "", this.isGoingHome ? "(home)" : "", Mathf.Sqrt(targetXZDistanceSq).ToCultureInvariantString("0.000"), value.ToCultureInvariantString("0.000"), this.homeTimeout.ToCultureInvariantString("0.00") }); } private int _actionIndex = 0; private const float cSleeperChaseTime = 90f; private List targetClasses; private float chaseTimeMax; private bool hasHome; private bool isGoingHome; private float homeTimeout; private EntityAlive targetPlayer; private EntityAlive entityTarget; private Vector3 entityTargetPos; private Vector3 entityTargetVel; private Vector3 entityPlayerVel; private int attackTimeout; private int pathCounter; private Vector2 seekPosOffset; private bool isTargetToEat; private bool isEating; private int eatCount; private EAIBlockingTargetTask blockTargetTask; private int relocateTicks; private int OwnerID = 0; private bool backingUp = false; private Animator animator = null; private struct TargetClass { public Type type; public float chaseTimeMax; } }