Files
zzz_REBIRTH__Utils/Scripts/EAI/EAIApproachAndAttackTargetSDX.cs
2025-06-04 16:44:53 +09:30

531 lines
20 KiB
C#

using GamePath;
using System.Collections.Generic;
using System.Globalization;
public class EAIApproachAndAttackTargetSDX : EAIApproachAndAttackTarget
{
public override void Init(EntityAlive _theEntity)
{
//Log.Out("EAIApproachAndAttackTargetSDX-Init START");
base.Init(_theEntity);
this.MutexBits = 3;
this.executeDelay = 0.1f;
}
public override void SetData(DictionarySave<string, string> data)
{
//Log.Out("EAIApproachAndAttackTargetSDX-SetData START");
base.SetData(data);
this.targetClasses = new List<EAIApproachAndAttackTargetSDX.TargetClass>();
string text;
if (data.TryGetValue("class", out text))
{
string[] array = text.Split(new char[]
{
','
});
for (int i = 0; i < array.Length; i += 2)
{
EAIApproachAndAttackTargetSDX.TargetClass item = default(EAIApproachAndAttackTargetSDX.TargetClass);
item.type = EntityFactory.GetEntityType(array[i]);
item.maxChaseTime = 0f;
if (i + 1 < array.Length)
{
item.maxChaseTime = StringParsers.ParseFloat(array[i + 1], 0, -1, NumberStyles.Any);
}
this.targetClasses.Add(item);
}
}
}
public override bool CanExecute()
{
//Log.Out("EAIApproachAndAttackTargetSDX-CanExecute START");
if (RebirthUtilities.canAttack(theEntity))
{
return false;
}
if (!this.theEntity.GetRevengeTarget())
{
EntityPlayer closestPlayer = null;
float num = 200 * 200;
float num2 = float.MaxValue;
for (int i = this.theEntity.world.Players.list.Count - 1; i >= 0; i--)
{
EntityPlayer entityPlayer = this.theEntity.world.Players.list[i];
if (!entityPlayer.IsDead() && entityPlayer.Spawned && !entityPlayer.IsSpectator)
{
//Log.Out("FOUND PLAYER: " + entityPlayer.EntityName);
float distanceSq = entityPlayer.GetDistanceSq(this.theEntity.position);
if (distanceSq < num2 && distanceSq <= num)
{
num2 = distanceSq;
closestPlayer = entityPlayer;
}
}
}
if (closestPlayer != null)
{
this.theEntity.SetAttackTarget(closestPlayer, 200);
this.entityTarget = closestPlayer;
//Log.Out("CanExecute GOT CLOSEST PLAYER");
}
else
{
this.entityTarget = this.theEntity.GetAttackTarget();
//Log.Out("CanExecute NO CLOSEST PLAYER");
}
}
else
{
this.entityTarget = this.theEntity.GetRevengeTarget();
}
if (this.entityTarget == null)
{
//Log.Out("CanExecute NO TARGET");
return false;
}
Type type = this.entityTarget.GetType();
for (int i = 0; i < this.targetClasses.Count; i++)
{
EAIApproachAndAttackTargetSDX.TargetClass targetClass = this.targetClasses[i];
if (targetClass.type != null && targetClass.type.IsAssignableFrom(type))
{
this.maxChaseTime = targetClass.maxChaseTime;
return true;
}
}
return false;
}
public override void Start()
{
//Log.Out("EAIApproachAndAttackTargetSDX-Start START");
this.entityTargetPos = this.entityTarget.position;
this.entityTargetVel = Vector3.zero;
this.isTargetToEat = this.entityTarget.IsDead() && !(this.entityTarget is EntityZombie);
this.isEating = false;
this.theEntity.IsEating = false;
this.homeTimeout = (this.theEntity.IsSleeper ? 90f : this.maxChaseTime);
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;
if (this.isTargetToEat)
{
Vector3 moveToLocation = this.GetMoveToLocation(0f);
this.theEntity.FindPath(moveToLocation, this.theEntity.GetMoveSpeedAggro(), true, this);
}
this.attackTimeout = 5;
}
public override bool Continue()
{
//Log.Out($"EAIApproachAndAttackTargetSDX-Continue START this {theEntity}, attackTarget: {theEntity.attackTarget}");
if (RebirthUtilities.canAttack(theEntity))
{
return false;
}
EntityAlive attackTarget = this.theEntity.GetAttackTarget();
if (this.isGoingHome)
{
return !attackTarget && this.theEntity.ChaseReturnLocation != Vector3.zero;
}
return attackTarget && !(attackTarget != this.entityTarget) && attackTarget.IsDead() == this.isTargetToEat;
}
public override void Reset()
{
//Log.Out("EAIApproachAndAttackTargetSDX-Reset START");
this.theEntity.IsEating = false;
this.theEntity.navigator.clearPath();
if (this.blockTargetTask != null)
{
this.blockTargetTask.canExecute = false;
}
}
public override void Update()
{
//Log.Out("EAIApproachAndAttackTargetSDX-Update START");
if (this.hasHome && !this.isTargetToEat)
{
if (this.isGoingHome)
{
Vector3 vector = this.theEntity.ChaseReturnLocation - this.theEntity.position;
float y = vector.y;
vector.y = 0f;
if (vector.sqrMagnitude <= 0.16000001f && Utils.FastAbs(y) < 2f)
{
Vector3 chaseReturnLocation = this.theEntity.ChaseReturnLocation;
chaseReturnLocation.y = this.theEntity.position.y;
this.theEntity.SetPosition(chaseReturnLocation, true);
this.theEntity.ChaseReturnLocation = Vector3.zero;
if (this.theEntity.IsSleeper)
{
this.theEntity.ResumeSleeperPose();
}
return;
}
int num = this.pathCounter - 1;
this.pathCounter = num;
if (num <= 0 && !PathFinderThread.Instance.IsCalculatingPath(this.theEntity.entityId))
{
this.pathCounter = 60;
float moveSpeed = this.theEntity.GetMoveSpeedAggro() * 0.8f;
this.theEntity.FindPath(this.theEntity.ChaseReturnLocation, moveSpeed, true, this);
}
return;
}
else
{
this.homeTimeout -= 0.05f;
if (this.homeTimeout <= 0f)
{
if (this.blockTargetTask == null)
{
List<EAIBlockingTargetTask> targetTasks = this.manager.GetTargetTasks<EAIBlockingTargetTask>();
if (targetTasks != null)
{
this.blockTargetTask = targetTasks[0];
}
}
if (this.blockTargetTask != null)
{
this.blockTargetTask.canExecute = true;
}
this.theEntity.attackTarget = (EntityAlive) null;
this.theEntity.SetLookPosition(Vector3.zero);
this.theEntity.PlayGiveUpSound();
this.pathCounter = 0;
this.isGoingHome = true;
return;
}
}
}
if (this.entityTarget == null)
{
//Log.Out("EAIApproachAndAttackTargetSDX-Update 1");
//Log.Out("Update NO TARGET");
EntityPlayer closestPlayer = null;
float numTarget = 200 * 200;
float numTarget2 = float.MaxValue;
//Log.Out("EAIApproachAndAttackTargetSDX-Update 1ba");
for (int i = this.theEntity.world.Players.list.Count - 1; i >= 0; i--)
{
EntityPlayer entityPlayer = this.theEntity.world.Players.list[i];
if (!entityPlayer.IsDead() && entityPlayer.Spawned)
{
//Log.Out("FOUND PLAYER: " + entityPlayer.EntityName);
float distanceSq = entityPlayer.GetDistanceSq(this.theEntity.position);
if (distanceSq < numTarget2 && distanceSq <= numTarget)
{
numTarget2 = distanceSq;
closestPlayer = entityPlayer;
}
}
}
if (closestPlayer != null)
{
this.theEntity.SetAttackTarget(closestPlayer, 120);
this.entityTarget = closestPlayer;
//Log.Out("Update GOT PLAYER TARGET: " + closestPlayer.EntityName);
}
if (this.entityTarget == null)
{
return;
}
}
else
{
//Log.Out("UPDATE-EntityTarget Name: " + this.entityTarget.EntityName);
}
if (this.relocateTicks > 0)
{
//Log.Out("EAIApproachAndAttackTargetSDX-Update 2");
if (!this.theEntity.navigator.noPathAndNotPlanningOne())
{
//Log.Out("EAIApproachAndAttackTargetSDX-Update 3");
this.relocateTicks--;
this.theEntity.moveHelper.SetFocusPos(this.entityTarget.position);
return;
}
this.relocateTicks = 0;
}
Vector3 position = this.entityTarget.position;
Vector3 vector2 = position - this.entityTargetPos;
if (vector2.sqrMagnitude < 1f)
{
this.entityTargetVel = this.entityTargetVel * 0.7f + vector2 * 0.3f;
}
this.entityTargetPos = position;
this.attackTimeout--;
if (this.isEating)
{
//Log.Out("EAIApproachAndAttackTargetSDX-Update 4");
if (this.theEntity.bodyDamage.HasLimbs)
{
this.theEntity.RotateTo(position.x, position.y, position.z, 30f, 30f);
}
if (this.attackTimeout <= 0)
{
this.theEntity.PlayOneShot("eat_player", false);
this.attackTimeout = 60 + base.GetRandom(20);
}
return;
}
this.theEntity.moveHelper.CalcIfUnreachablePos();
ItemAction itemAction = this.theEntity.inventory.holdingItem.Actions[0];
float num2 = 1.095f;
if (!this.isTargetToEat)
{
num2 = ((itemAction != null) ? Utils.FastMax(0.5f, itemAction.Range - 0.35f) : 0.5f);
}
float num3 = num2 * num2;
float estimatedTicks = 1f + base.RandomFloat * 10f;
float targetXZDistanceSq = this.GetTargetXZDistanceSq(estimatedTicks);
float num4 = position.y - this.theEntity.position.y;
float num5 = Utils.FastAbs(num4);
bool flag = targetXZDistanceSq <= num3 && num5 < 1f;
if (!flag && !this.isTargetToEat)
{
if (!PathFinderThread.Instance.IsCalculatingPath(this.theEntity.entityId))
{
PathEntity path = this.theEntity.navigator.getPath();
if (path != null && path.NodeCountRemaining() <= 2)
{
this.pathCounter = 0;
}
}
int num = this.pathCounter - 1;
this.pathCounter = num;
if (num <= 0 && !PathFinderThread.Instance.IsCalculatingPath(this.theEntity.entityId))
{
this.pathCounter = 6 + base.GetRandom(10);
Vector3 moveToLocation = this.GetMoveToLocation(num2);
this.theEntity.FindPath(moveToLocation, this.theEntity.GetMoveSpeedAggro(), true, this);
}
}
if (this.theEntity.Climbing)
{
//Log.Out("EAIApproachAndAttackTargetSDX-Update 5");
return;
}
bool flag2 = this.theEntity.CanSee(this.entityTarget);
if (!flag2)
{
//Log.Out("Update - CANNOT SEE TARGET");
}
this.theEntity.SetLookPosition((!this.theEntity.IsBreakingBlocks) ? this.entityTarget.getHeadPosition() : Vector3.zero);
if (!flag)
{
if (this.theEntity.navigator.noPathAndNotPlanningOne() && num4 < 2.1f)
{
Vector3 moveToLocation2 = this.GetMoveToLocation(num2);
this.theEntity.moveHelper.SetMoveTo(moveToLocation2, true);
}
}
else
{
this.theEntity.navigator.clearPath();
this.theEntity.moveHelper.Stop();
this.pathCounter = 0;
}
float num6 = this.isTargetToEat ? 1.095f : ((itemAction != null) ? (itemAction.Range - 0.1f) : 0f);
float num7 = num6 * num6;
if (targetXZDistanceSq > num7 || num5 >= 1.25f)
{
//Log.Out("EAIApproachAndAttackTargetSDX-Update 6");
return;
}
this.theEntity.IsBreakingBlocks = false;
this.theEntity.IsBreakingDoors = false;
if (this.theEntity.bodyDamage.HasLimbs)
{
this.theEntity.RotateTo(position.x, position.y, position.z, 30f, 30f);
}
if (this.isTargetToEat)
{
this.isEating = true;
this.theEntity.IsEating = true;
this.attackTimeout = 0;
//Log.Out("EAIApproachAndAttackTargetSDX-Update 6a");
return;
}
if (this.theEntity.GetDamagedTarget() == this.entityTarget || (this.entityTarget != null && this.entityTarget.GetDamagedTarget() == this.theEntity))
{
this.homeTimeout = (this.theEntity.IsSleeper ? 90f : this.maxChaseTime);
if (this.blockTargetTask != null)
{
this.blockTargetTask.canExecute = false;
}
this.theEntity.ClearDamagedTarget();
if (this.entityTarget)
{
this.entityTarget.ClearDamagedTarget();
}
}
if (this.attackTimeout > 0)
{
//Log.Out("EAIApproachAndAttackTargetSDX-Update 7");
return;
}
if (this.manager.groupCircle > 0f)
{
Entity targetIfAttackedNow = this.theEntity.GetTargetIfAttackedNow();
if (targetIfAttackedNow != this.entityTarget && (!this.entityTarget.AttachedToEntity || this.entityTarget.AttachedToEntity != targetIfAttackedNow))
{
if (targetIfAttackedNow != null)
{
this.relocateTicks = 46;
Vector3 vector3 = (this.theEntity.position - position).normalized * (num6 + 1.1f);
float num8 = base.RandomFloat * 28f + 18f;
if (base.RandomFloat < 0.5f)
{
num8 = -num8;
}
vector3 = Quaternion.Euler(0f, num8, 0f) * vector3;
Vector3 targetPos = position + vector3;
this.theEntity.FindPath(targetPos, this.theEntity.GetMoveSpeedAggro(), true, this);
}
//Log.Out("EAIApproachAndAttackTargetSDX-Update 8");
return;
}
}
//Log.Out("EAIApproachAndAttackTargetSDX-Update 9");
this.theEntity.SleeperSupressLivingSounds = false;
if (this.theEntity.Attack(false))
{
this.attackTimeout = this.theEntity.GetAttackTimeoutTicks();
this.theEntity.Attack(true);
}
}
private float GetTargetXZDistanceSq(float estimatedTicks)
{
Vector3 vector = this.entityTarget.position;
vector += this.entityTargetVel * estimatedTicks;
if (this.isTargetToEat)
{
EModelBase emodel = this.entityTarget.emodel;
if (emodel && emodel.bipedPelvisTransform)
{
vector = emodel.bipedPelvisTransform.position + Origin.position;
}
}
Vector3 vector2 = this.theEntity.position + this.theEntity.motion * estimatedTicks - vector;
vector2.y = 0f;
return vector2.sqrMagnitude;
}
private Vector3 GetMoveToLocation(float maxDist)
{
//Log.Out("EAIApproachAndAttackTargetSDX-GetMoveToLocation START");
Vector3 vector = this.entityTarget.position;
vector += this.entityTargetVel * 6f;
if (this.isTargetToEat)
{
EModelBase emodel = this.entityTarget.emodel;
if (emodel && emodel.bipedPelvisTransform)
{
vector = emodel.bipedPelvisTransform.position + Origin.position;
}
}
vector = this.entityTarget.world.FindSupportingBlockPos(vector);
if (maxDist > 0f)
{
Vector3 vector2 = new Vector3(this.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 - this.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 = this.entityTarget.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 string ToString()
{
ItemAction itemAction = this.theEntity.inventory.holdingItem.Actions[0];
float value = (itemAction != null) ? (itemAction.Range - 0.1f) : 0f;
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 const float cSleeperChaseTime = 90f;
private List<EAIApproachAndAttackTargetSDX.TargetClass> targetClasses;
private float maxChaseTime;
private bool hasHome;
private bool isGoingHome;
private float homeTimeout;
private EntityAlive entityTarget;
private Vector3 entityTargetPos;
private Vector3 entityTargetVel;
private int attackTimeout;
private int pathCounter;
private bool isTargetToEat;
private bool isEating;
private EAIBlockingTargetTask blockTargetTask;
private int relocateTicks;
private struct TargetClass
{
public Type type;
public float maxChaseTime;
}
}