416 lines
15 KiB
C#
416 lines
15 KiB
C#
using GamePath;
|
|
using UnityEngine.Scripting;
|
|
|
|
[Preserve]
|
|
public class EAIFollowLeaderCompanion : EAITarget
|
|
{
|
|
public override void Init(EntityAlive _theEntity)
|
|
{
|
|
base.Init(_theEntity, 25f, true);
|
|
MutexBits = 1;
|
|
}
|
|
|
|
public override void Start()
|
|
{
|
|
entityPlayerVel = Vector3.zero;
|
|
relocateTicks = 0;
|
|
pathCounter = 0;
|
|
theEntity.ConditionalTriggerSleeperWakeUp();
|
|
base.Start();
|
|
}
|
|
|
|
public bool NPCEAICanProceed()
|
|
{
|
|
bool result = true;
|
|
|
|
OwnerID = (int)theEntity.Buffs.GetCustomVar("$Leader");
|
|
|
|
if (OwnerID == 0)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-NPCEAICanProceed 0");
|
|
return false;
|
|
}
|
|
|
|
if (theEntity.Buffs.GetCustomVar("onMission") == 1f ||
|
|
theEntity.Buffs.GetCustomVar("$FR_NPC_Respawn") == 1f ||
|
|
theEntity.Buffs.GetCustomVar("$FR_NPC_Hidden") == 1f
|
|
)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-NPCEAICanProceed 1");
|
|
return false;
|
|
}
|
|
|
|
EntityUtilities.CheckDistanceToLeader(theEntity, targetPlayer);
|
|
|
|
if (theEntity.emodel.IsRagdollActive)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-NPCEAICanProceed 3");
|
|
return false;
|
|
}
|
|
|
|
if (theEntity.sleepingOrWakingUp || theEntity.bodyDamage.CurrentStun != EnumEntityStunType.None || (theEntity.Jumping && !theEntity.isSwimming))
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-NPCEAICanProceed theEntity.sleepingOrWakingUp: " + theEntity.sleepingOrWakingUp);
|
|
//Log.Out("EAIFollowLeaderCompanion-NPCEAICanProceed theEntity.bodyDamage.CurrentStun: " + theEntity.bodyDamage.CurrentStun);
|
|
//Log.Out("EAIFollowLeaderCompanion-NPCEAICanProceed theEntity.Jumping: " + theEntity.Jumping);
|
|
//Log.Out("EAIFollowLeaderCompanion-NPCEAICanProceed theEntity.isSwimming: " + theEntity.isSwimming);
|
|
//Log.Out("EAIFollowLeaderCompanion-NPCEAICanProceed 4");
|
|
return false;
|
|
}
|
|
|
|
if (theEntity.Buffs.GetCustomVar("CurrentOrder") != (int)EntityUtilities.Orders.Follow)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-CanExecute IS NOT FOLLOWING");
|
|
return false;
|
|
}
|
|
|
|
/*bool stopAttacking = this.theEntity.Buffs.HasBuff("FuriousRamsayBuffPauseAttack") ||
|
|
this.theEntity.Buffs.HasBuff("buffNPCModStopAttacking") ||
|
|
this.theEntity.Buffs.HasBuff("FuriousRamsayStandStill");*/
|
|
|
|
bool stopAttacking = theEntity.Buffs.HasBuff("FuriousRamsayStandStill");
|
|
|
|
if (stopAttacking)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-NPCEAICanProceed 5");
|
|
theEntity.SetRevengeTarget((EntityAlive) null);
|
|
theEntity.attackTarget = (EntityAlive) null;
|
|
|
|
return false;
|
|
}
|
|
|
|
if (theEntity.sleepingOrWakingUp || theEntity.bodyDamage.CurrentStun != EnumEntityStunType.None)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-NPCEAICanProceed 6");
|
|
return false;
|
|
}
|
|
|
|
//Log.Out($"EAIFollowLeaderCompanion::NPCEAICanProceed END {theEntity}, return: {result}, attackTarget: {theEntity.attackTarget}");
|
|
return result;
|
|
}
|
|
|
|
public override bool CanExecute()
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-CanExecute START");
|
|
|
|
if (!NPCEAICanProceed())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (targetPlayer == null)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-CanExecute 2");
|
|
OwnerID = (int)theEntity.Buffs.GetCustomVar("$Leader");
|
|
|
|
if (OwnerID > 0)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-CanExecute this.OwnerID: " + this.OwnerID);
|
|
|
|
EntityPlayer entityPlayer = (EntityPlayer)theEntity.world.GetEntity(OwnerID);
|
|
if (entityPlayer != null)
|
|
{
|
|
targetPlayer = entityPlayer;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//Log.Out($"EAIFollowLeaderCompanion::CanExecute END {theEntity}, return false, attackTarget: {theEntity.attackTarget}");
|
|
//Log.Out("EAIFollowLeaderCompanion-CanExecute this.theEntity.GetAttackTarget: " + this.theEntity.GetAttackTarget().EntityClass.entityClassName);
|
|
return false;
|
|
}
|
|
|
|
public override bool Continue()
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Continue START");
|
|
|
|
if (!NPCEAICanProceed())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (pathCounter == 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//Log.Out($"EAIFollowLeaderCompanion::Continue END {theEntity}, return true, attackTarget: {theEntity.attackTarget}");
|
|
return true;
|
|
}
|
|
|
|
public override void Update()
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Update START");
|
|
|
|
if (!NPCEAICanProceed())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (targetPlayer == null)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Update 2");
|
|
OwnerID = (int)theEntity.Buffs.GetCustomVar("$Leader");
|
|
|
|
if (OwnerID > 0)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Update this.OwnerID: " + this.OwnerID);
|
|
|
|
EntityPlayer entityPlayer = (EntityPlayer)theEntity.world.GetEntity(OwnerID);
|
|
if (entityPlayer != null)
|
|
{
|
|
targetPlayer = entityPlayer;
|
|
//Log.Out("EAIFollowLeaderCompanion-Update FOUND OWNER");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (relocateTicks > 0)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Update 2");
|
|
if (!theEntity.navigator.noPathAndNotPlanningOne())
|
|
{
|
|
//Log.Out($"EAIFollowLeaderCompanion-Update 3 {theEntity}, SetFocusPos: {targetPlayer.position}");
|
|
relocateTicks--;
|
|
theEntity.moveHelper.SetFocusPos(targetPlayer.position);
|
|
return;
|
|
}
|
|
relocateTicks = 0;
|
|
}
|
|
|
|
Vector3 vector2 = 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"));
|
|
|
|
OwnerID = (int)theEntity.Buffs.GetCustomVar("$Leader");
|
|
|
|
float magnitude = 30f;
|
|
|
|
bool isClient = SingletonMonoBehaviour<ConnectionManager>.Instance.IsClient;
|
|
|
|
if (isClient)
|
|
{
|
|
magnitude = 3f;
|
|
}
|
|
|
|
//Log.Out("EAIFollowLeaderCompanion-Update magnitude: " + magnitude);
|
|
|
|
if (targetPlayer.entityId == OwnerID && a.sqrMagnitude < magnitude)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Update Entity is too close. Ending pathing.");
|
|
theEntity.moveHelper.Stop();
|
|
pathCounter = 0;
|
|
|
|
return;
|
|
}
|
|
|
|
if (targetPlayer.entityId == OwnerID)
|
|
{
|
|
/*if (!theEntity.HasAnyTags(FastTags<TagGroup.Global>.Parse("allyanimal")))
|
|
{
|
|
theEntity.Crouching = targetPlayer.Crouching;
|
|
}*/
|
|
|
|
//Log.Out("EAIFollowLeaderCompanion-Update theEntity.moveHelper.BlockedTime: " + theEntity.moveHelper.BlockedTime);
|
|
|
|
if (theEntity.moveHelper.BlockedTime > 3f)
|
|
{
|
|
EntityAliveV2 npc = theEntity as EntityAliveV2;
|
|
|
|
if (npc != null)
|
|
{
|
|
npc.TeleportToPlayer(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 = entityPlayerVel * 0.7f + a * 0.3f;
|
|
}
|
|
entityPlayerPos = vector2;
|
|
|
|
theEntity.moveHelper.CalcIfUnreachablePos();
|
|
|
|
//Log.Out($"Is unreachable: {theEntity.moveHelper.IsUnreachableSide}");
|
|
|
|
if (!theEntity.moveHelper.IsUnreachableSide)
|
|
EntityUtilities.CheckForClosedDoor(theEntity);
|
|
|
|
float num2;
|
|
float num3;
|
|
|
|
num2 = 1.095f;
|
|
num3 = Utils.FastMax(0.7f, num2 - 0.35f);
|
|
|
|
float num4 = num3 * num3;
|
|
float num5 = 4f;
|
|
if (theEntity.IsFeral)
|
|
{
|
|
num5 = 8f;
|
|
}
|
|
num5 = base.RandomFloat * num5;
|
|
float targetXZDistanceSq = GetTargetXZDistanceSq(num5);
|
|
float num6 = vector2.y - 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(theEntity.entityId))
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Update 10");
|
|
PathEntity path = theEntity.navigator.getPath();
|
|
if (path != null && path.NodeCountRemaining() <= 2)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Update 11");
|
|
pathCounter = 0;
|
|
}
|
|
}
|
|
int num = pathCounter - 1;
|
|
pathCounter = num;
|
|
if (num <= 0 && this.theEntity.CanNavigatePath() && !PathFinderThread.Instance.IsCalculatingPath(theEntity.entityId))
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Update 12");
|
|
pathCounter = 6 + base.GetRandom(10);
|
|
Vector3 moveToLocation = EntityUtilities.GetMoveToLocation(this.theEntity, targetPlayer.position, 5);
|
|
if (moveToLocation.y - theEntity.position.y < -8f)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Update 13");
|
|
pathCounter += 40;
|
|
if (base.RandomFloat < 0.2f)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Update 14");
|
|
seekPosOffset.x = this.seekPosOffset.x + (base.RandomFloat * 0.6f - 0.3f);
|
|
seekPosOffset.y = this.seekPosOffset.y + (base.RandomFloat * 0.6f - 0.3f);
|
|
}
|
|
moveToLocation.x += seekPosOffset.x;
|
|
moveToLocation.z += seekPosOffset.y;
|
|
}
|
|
else
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Update 15");
|
|
float num8 = (moveToLocation - theEntity.position).magnitude - 5f;
|
|
if (num8 > 0f)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Update 16");
|
|
if (num8 > 60f)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Update 17");
|
|
num8 = 60f;
|
|
}
|
|
pathCounter += (int)(num8 / 20f * 20f);
|
|
}
|
|
}
|
|
//Log.Out($"EAIFollowLeaderCompanion-Update FindPath moveToLocation: {moveToLocation}");
|
|
theEntity.FindPath(moveToLocation, this.theEntity.GetMoveSpeedAggro(), true, this);
|
|
}
|
|
}
|
|
if (theEntity.Climbing)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Update 18");
|
|
return;
|
|
}
|
|
if (!flag)
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Update 20");
|
|
if (this.theEntity.navigator.noPathAndNotPlanningOne() && pathCounter > 0 && num6 < 2.1f)
|
|
{
|
|
Vector3 moveToLocation2 = EntityUtilities.GetMoveToLocation(theEntity, this.targetPlayer.position);
|
|
//Log.Out($"EAIFollowLeaderCompanion-Update SetMoveTo moveToLocation2: {moveToLocation2}");
|
|
theEntity.moveHelper.SetMoveTo(moveToLocation2, true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Log.Out("EAIFollowLeaderCompanion-Update 22 moveHelper.Stop");
|
|
theEntity.moveHelper.Stop();
|
|
pathCounter = 0;
|
|
}
|
|
}
|
|
|
|
private float GetTargetXZDistanceSq(float estimatedTicks)
|
|
{
|
|
Vector3 vector = targetPlayer.position;
|
|
vector += entityPlayerVel * estimatedTicks;
|
|
Vector3 vector2 = this.theEntity.position + theEntity.motion * estimatedTicks - vector;
|
|
vector2.y = 0f;
|
|
return vector2.sqrMagnitude;
|
|
}
|
|
|
|
private Vector3 GetMoveToLocation(float maxDist)
|
|
{
|
|
Vector3 vector = targetPlayer.position;
|
|
vector += entityPlayerVel * 6f;
|
|
vector = targetPlayer.world.FindSupportingBlockPos(vector);
|
|
if (maxDist > 0f)
|
|
{
|
|
Vector3 vector2 = new Vector3(theEntity.position.x, vector.y, this.theEntity.position.z);
|
|
Vector3 vector3 = vector - vector2;
|
|
float magnitude = vector3.magnitude;
|
|
if (magnitude < 3f)
|
|
{
|
|
if (magnitude <= maxDist)
|
|
{
|
|
float num = vector.y - theEntity.position.y;
|
|
if (num < -3f || num > 1.5f)
|
|
{
|
|
return vector;
|
|
}
|
|
return vector2;
|
|
}
|
|
else
|
|
{
|
|
vector3 *= maxDist / magnitude;
|
|
Vector3 vector4 = vector - vector3;
|
|
vector4.y += 0.51f;
|
|
Vector3i pos = World.worldToBlockPos(vector4);
|
|
BlockValue block = targetPlayer.world.GetBlock(pos);
|
|
Block block2 = block.Block;
|
|
if (block2.PathType <= 0)
|
|
{
|
|
RaycastHit raycastHit;
|
|
if (Physics.Raycast(vector4 - Origin.position, Vector3.down, out raycastHit, 1.02f, 1082195968))
|
|
{
|
|
vector4.y = raycastHit.point.y + Origin.position.y;
|
|
return vector4;
|
|
}
|
|
if (block2.IsElevator((int)block.rotation))
|
|
{
|
|
vector4.y = vector.y;
|
|
return vector4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return vector;
|
|
}
|
|
|
|
public override void Reset()
|
|
{
|
|
targetPlayer = null;
|
|
}
|
|
|
|
private EntityPlayer targetPlayer;
|
|
private Vector3 entityPlayerVel;
|
|
private Vector3 entityPlayerPos;
|
|
private int relocateTicks;
|
|
private int OwnerID = 0;
|
|
private int pathCounter;
|
|
private Vector2 seekPosOffset;
|
|
}
|