828 lines
30 KiB
C#
828 lines
30 KiB
C#
using System.Collections.Generic;
|
|
|
|
public class EntityWraith : EntityFlying
|
|
{
|
|
public override void FireEvent(MinEventTypes _eventType, bool useInventory = true)
|
|
{
|
|
bool applyBlockDamageBuffs = false;
|
|
|
|
if (_eventType == MinEventTypes.onSelfDamagedOther)
|
|
{
|
|
//Log.Out("EntityAlivePatches-FireEvent WRAITH DAMAGED OTHER");
|
|
this.Buffs.AddBuff("FuriousRamsayWraithProtection");
|
|
this.Buffs.SetCustomVar("$FuriousRamsayAttacked", 0f);
|
|
}
|
|
else if (_eventType == MinEventTypes.onSelfRangedBurstShotStart)
|
|
{
|
|
//Log.Out("EntityAlivePatches-FireEvent WRAITH BURST SHOT OTHER");
|
|
this.Buffs.AddBuff("FuriousRamsayWraithProtection");
|
|
this.Buffs.SetCustomVar("$FuriousRamsayAttacked", 1f);
|
|
}
|
|
else if (_eventType == MinEventTypes.onSelfAttackedOther)
|
|
{
|
|
//Log.Out("EntityAlivePatches-FireEvent WRAITH ATTACKED OTHER");
|
|
this.Buffs.AddBuff("FuriousRamsayWraithProtection");
|
|
|
|
float attacks = this.Buffs.GetCustomVar("$FuriousRamsayAttacked") - 2f;
|
|
|
|
if (attacks < 0f)
|
|
{
|
|
attacks = 0f;
|
|
}
|
|
|
|
this.Buffs.SetCustomVar("$FuriousRamsayAttacked", attacks);
|
|
}
|
|
else if (_eventType == MinEventTypes.onSelfDamagedBlock)
|
|
{
|
|
//Log.Out("EntityAlivePatches-FireEvent WRAITH DAMAGED BLOCK");
|
|
applyBlockDamageBuffs = true;
|
|
}
|
|
else if (_eventType == MinEventTypes.onSelfDestroyedBlock)
|
|
{
|
|
//Log.Out("EntityAlivePatches-FireEvent WRAITH DESTROYED BLOCK");
|
|
applyBlockDamageBuffs = true;
|
|
}
|
|
else if (_eventType == MinEventTypes.onSelfPrimaryActionUpdate ||
|
|
_eventType == MinEventTypes.onSelfSecondaryActionUpdate
|
|
)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
//Log.Out("EntityAlivePatches-FireEvent _eventType: " + _eventType);
|
|
}
|
|
|
|
if (applyBlockDamageBuffs)
|
|
{
|
|
//Log.Out("EntityAlivePatches-FireEvent ADD BLOCK BUFF");
|
|
this.Buffs.AddBuff("FuriousRamsayWraithProtectionBlocks");
|
|
}
|
|
|
|
if (_eventType == MinEventTypes.onOtherDamagedSelf)
|
|
{
|
|
float attacks = this.Buffs.GetCustomVar("$FuriousRamsayAttacked") + 1f;
|
|
|
|
this.Buffs.SetCustomVar("$FuriousRamsayAttacked", attacks);
|
|
|
|
if (attacks >= 4f)
|
|
{
|
|
this.Buffs.RemoveBuff("FuriousRamsayWraithProtection");
|
|
this.Buffs.RemoveBuff("FuriousRamsayWraithProtectionBlocks");
|
|
}
|
|
}
|
|
|
|
base.FireEvent(_eventType, useInventory);
|
|
}
|
|
|
|
public override string EntityName
|
|
{
|
|
get
|
|
{
|
|
return this.entityName;
|
|
}
|
|
}
|
|
|
|
public override void OnUpdateLive()
|
|
{
|
|
if (this.bDead)
|
|
{
|
|
if (this.lootContainer != null)
|
|
{
|
|
if (this.lootContainer.bTouched && this.lootContainer.IsEmpty())
|
|
{
|
|
this.MarkToUnload();
|
|
this.KillLootContainer();
|
|
}
|
|
}
|
|
}
|
|
|
|
base.OnUpdateLive();
|
|
}
|
|
|
|
public override void Awake()
|
|
{
|
|
base.Awake();
|
|
this.state = EntityWraith.State.WanderStart;
|
|
}
|
|
|
|
public override void Init(int _entityClass)
|
|
{
|
|
base.Init(_entityClass);
|
|
this.Init();
|
|
}
|
|
|
|
public override void InitFromPrefab(int _entityClass)
|
|
{
|
|
base.InitFromPrefab(_entityClass);
|
|
this.Init();
|
|
}
|
|
|
|
private void Init()
|
|
{
|
|
this.isRadiated = EntityClass.list[this.entityClass].Properties.Values.ContainsKey("Radiated");
|
|
this.battleFatigueSeconds = 30f + this.rand.RandomFloat * 60f;
|
|
}
|
|
|
|
public override void SetSleeper()
|
|
{
|
|
base.SetSleeper();
|
|
this.sorter = new EAISetNearestEntityAsTargetSorter(this);
|
|
base.setHomeArea(new Vector3i(this.position), (int)this.sleeperSightRange + 1);
|
|
this.battleFatigueSeconds = float.MaxValue;
|
|
}
|
|
|
|
public override void updateTasks()
|
|
{
|
|
if (GamePrefs.GetBool(EnumGamePrefs.DebugStopEnemiesMoving))
|
|
{
|
|
this.aiManager.UpdateDebugName();
|
|
return;
|
|
}
|
|
if (GameStats.GetInt(EnumGameStats.GameState) == 2)
|
|
{
|
|
return;
|
|
}
|
|
base.CheckDespawn();
|
|
base.GetEntitySenses().ClearIfExpired();
|
|
|
|
bool flag = this.Buffs.HasBuff("buffShocked");
|
|
if (flag)
|
|
{
|
|
this.SetState(EntityWraith.State.Stun);
|
|
}
|
|
else
|
|
{
|
|
EntityAlive revengeTarget = base.GetRevengeTarget();
|
|
if (revengeTarget)
|
|
{
|
|
this.battleDuration = 0f;
|
|
this.isBattleFatigued = false;
|
|
base.SetRevengeTarget((EntityAlive) null);
|
|
if (revengeTarget != this.attackTarget && (!this.attackTarget || this.rand.RandomFloat < 0.5f))
|
|
{
|
|
base.SetAttackTarget(revengeTarget, 1200);
|
|
}
|
|
}
|
|
if (this.attackTarget != this.currentTarget)
|
|
{
|
|
this.currentTarget = this.attackTarget;
|
|
if (this.currentTarget)
|
|
{
|
|
this.SetState(EntityWraith.State.Attack);
|
|
this.waypoint = this.position;
|
|
this.moveUpdateDelay = 0;
|
|
this.homeCheckDelay = 400;
|
|
}
|
|
else
|
|
{
|
|
this.SetState(EntityWraith.State.AttackStop);
|
|
}
|
|
}
|
|
}
|
|
float sqrMagnitude = (this.waypoint - this.position).sqrMagnitude;
|
|
this.stateTime += 0.05f;
|
|
int num2;
|
|
switch (this.state)
|
|
{
|
|
case EntityWraith.State.Attack:
|
|
this.battleDuration += 0.05f;
|
|
break;
|
|
case EntityWraith.State.AttackReposition:
|
|
if (sqrMagnitude < 2.25f || this.stateTime >= this.stateMaxTime)
|
|
{
|
|
this.SetState(EntityWraith.State.Attack);
|
|
this.motion *= -0.2f;
|
|
this.motion.y = 0f;
|
|
}
|
|
break;
|
|
case EntityWraith.State.AttackStop:
|
|
this.ClearTarget();
|
|
this.SetState(EntityWraith.State.WanderStart);
|
|
break;
|
|
case EntityWraith.State.Home:
|
|
if (sqrMagnitude < 4f || this.stateTime > 30f)
|
|
{
|
|
this.SetState(EntityWraith.State.WanderStart);
|
|
}
|
|
else
|
|
{
|
|
num2 = this.homeSeekDelay - 1;
|
|
this.homeSeekDelay = num2;
|
|
if (num2 <= 0)
|
|
{
|
|
this.homeSeekDelay = 40;
|
|
int minXZ = 10;
|
|
if (this.stateTime > 20f)
|
|
{
|
|
minXZ = -20;
|
|
}
|
|
int maximumHomeDistance = base.getMaximumHomeDistance();
|
|
Vector3 vector = RandomPositionGenerator.CalcTowards(this, minXZ, 30, maximumHomeDistance / 2, base.getHomePosition().position.ToVector3());
|
|
if (!vector.Equals(Vector3.zero))
|
|
{
|
|
this.waypoint = vector;
|
|
this.AdjustWaypoint();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case EntityWraith.State.Stun:
|
|
if (flag)
|
|
{
|
|
this.motion = this.rand.RandomOnUnitSphere * -0.075f;
|
|
this.motion.y = this.motion.y + -0.060000002f;
|
|
this.ModelTransform.GetComponentInChildren<Animator>().enabled = false;
|
|
return;
|
|
}
|
|
this.ModelTransform.GetComponentInChildren<Animator>().enabled = true;
|
|
this.SetState(EntityWraith.State.WanderStart);
|
|
break;
|
|
case EntityWraith.State.WanderStart:
|
|
this.homeCheckDelay = 60;
|
|
|
|
this.SetState(EntityWraith.State.Wander);
|
|
this.isCircling = (!this.IsSleeper && this.rand.RandomFloat < 0.4f);
|
|
float num3 = this.position.y;
|
|
RaycastHit raycastHit;
|
|
if (Physics.Raycast(this.position - Origin.position, Vector3.down, out raycastHit, 999f, 65536))
|
|
{
|
|
float num4 = 10f + this.rand.RandomFloat * 20f;
|
|
if (this.IsSleeper)
|
|
{
|
|
num4 *= 0.4f;
|
|
}
|
|
num3 += -raycastHit.distance + num4;
|
|
}
|
|
else
|
|
{
|
|
this.isCircling = false;
|
|
}
|
|
bool flag2 = false;
|
|
EntityPlayer entityPlayer3 = null;
|
|
|
|
EntityPlayer closestPlayer = null;
|
|
float numTarget = 200 * 200;
|
|
float numTarget2 = float.MaxValue;
|
|
for (int i = this.world.Players.list.Count - 1; i >= 0; i--)
|
|
{
|
|
EntityPlayer entityPlayer = this.world.Players.list[i];
|
|
if (!entityPlayer.IsDead() && entityPlayer.Spawned)
|
|
{
|
|
////Log.Out("FOUND PLAYER: " + entityPlayer.EntityName);
|
|
float distanceSq = entityPlayer.GetDistanceSq(this.position);
|
|
if (distanceSq < numTarget2 && distanceSq <= numTarget)
|
|
{
|
|
numTarget2 = distanceSq;
|
|
closestPlayer = entityPlayer;
|
|
}
|
|
}
|
|
}
|
|
|
|
entityPlayer3 = closestPlayer;
|
|
|
|
if (this.isCircling)
|
|
{
|
|
this.wanderChangeDelay = 120;
|
|
Vector3 right = base.transform.right;
|
|
right.y = 0f;
|
|
this.circleReverseScale = 1f;
|
|
if (this.rand.RandomFloat < 0.5f)
|
|
{
|
|
this.circleReverseScale = -1f;
|
|
right.x = -right.x;
|
|
right.z = -right.z;
|
|
}
|
|
this.circleCenter = this.position + right * (3f + this.rand.RandomFloat * 7f);
|
|
this.circleCenter.y = num3;
|
|
if (flag2)
|
|
{
|
|
this.circleCenter.x = this.circleCenter.x * 0.6f + entityPlayer3.position.x * 0.4f;
|
|
this.circleCenter.z = this.circleCenter.z * 0.6f + entityPlayer3.position.z * 0.4f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.wanderChangeDelay = 400;
|
|
this.waypoint = this.position;
|
|
this.waypoint.x = this.waypoint.x + (this.rand.RandomFloat * 16f - 8f);
|
|
this.waypoint.y = num3;
|
|
this.waypoint.z = this.waypoint.z + (this.rand.RandomFloat * 16f - 8f);
|
|
if (flag2)
|
|
{
|
|
this.waypoint.x = this.waypoint.x * 0.6f + entityPlayer3.position.x * 0.4f;
|
|
this.waypoint.z = this.waypoint.z * 0.6f + entityPlayer3.position.z * 0.4f;
|
|
}
|
|
this.AdjustWaypoint();
|
|
}
|
|
|
|
break;
|
|
case EntityWraith.State.Wander:
|
|
if (this.isBattleFatigued)
|
|
{
|
|
this.battleDuration -= 0.05f;
|
|
if (this.battleDuration <= 0f)
|
|
{
|
|
this.isBattleFatigued = false;
|
|
}
|
|
}
|
|
num2 = this.wanderChangeDelay - 1;
|
|
this.wanderChangeDelay = num2;
|
|
if (num2 <= 0)
|
|
{
|
|
this.SetState(EntityWraith.State.WanderStart);
|
|
}
|
|
if (this.isCircling)
|
|
{
|
|
Vector3 vector2 = this.circleCenter - this.position;
|
|
float x = vector2.x;
|
|
vector2.x = -vector2.z * this.circleReverseScale;
|
|
vector2.z = x * this.circleReverseScale;
|
|
vector2.y = 0f;
|
|
this.waypoint = this.position + vector2;
|
|
}
|
|
else if (sqrMagnitude < 1f)
|
|
{
|
|
this.SetState(EntityWraith.State.WanderStart);
|
|
}
|
|
num2 = this.targetSwitchDelay - 1;
|
|
this.targetSwitchDelay = num2;
|
|
if (num2 <= 0)
|
|
{
|
|
this.targetSwitchDelay = 40;
|
|
if (this.IsSleeper || this.rand.RandomFloat >= 0.5f)
|
|
{
|
|
EntityPlayer entityPlayer4 = this.FindTarget();
|
|
if (entityPlayer4)
|
|
{
|
|
base.SetAttackTarget(entityPlayer4, 1200);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
if (this.state != EntityWraith.State.Home)
|
|
{
|
|
num2 = this.homeCheckDelay - 1;
|
|
this.homeCheckDelay = num2;
|
|
if (num2 <= 0)
|
|
{
|
|
this.homeCheckDelay = 60;
|
|
if (!base.isWithinHomeDistanceCurrentPosition())
|
|
{
|
|
this.SetState(EntityWraith.State.AttackStop);
|
|
}
|
|
}
|
|
}
|
|
num2 = this.moveUpdateDelay - 1;
|
|
this.moveUpdateDelay = num2;
|
|
if (num2 <= 0)
|
|
{
|
|
this.moveUpdateDelay = 5 + this.rand.RandomRange(5);
|
|
if (this.currentTarget && this.state == EntityWraith.State.Attack)
|
|
{
|
|
this.waypoint = this.currentTarget.getHeadPosition();
|
|
this.waypoint.y = this.waypoint.y + -0.1f;
|
|
if (this.currentTarget.AttachedToEntity)
|
|
{
|
|
this.waypoint += this.currentTarget.GetVelocityPerSecond() * 0.3f;
|
|
}
|
|
Vector3 a = this.waypoint - this.position;
|
|
a.y = 0f;
|
|
a.Normalize();
|
|
this.waypoint += a * -0.6f;
|
|
}
|
|
float num5;
|
|
if (!isCourseTraversable(this.waypoint, out num5))
|
|
{
|
|
this.waypoint.y = this.waypoint.y + 2f;
|
|
if (this.state == EntityWraith.State.Attack)
|
|
{
|
|
if (this.rand.RandomFloat < 0.1f)
|
|
{
|
|
this.StartAttackReposition();
|
|
}
|
|
}
|
|
else if (this.state != EntityWraith.State.Home && this.state != EntityWraith.State.AttackReposition)
|
|
{
|
|
this.SetState(EntityWraith.State.WanderStart);
|
|
}
|
|
}
|
|
}
|
|
Vector3 a2 = this.waypoint - this.position;
|
|
float magnitude = a2.magnitude;
|
|
Vector3 vector3 = a2 * (1f / magnitude);
|
|
this.glidingPercent = 0f;
|
|
if (vector3.y > 0.57f)
|
|
{
|
|
this.accel = 0.35f;
|
|
}
|
|
else if (vector3.y < -0.34f)
|
|
{
|
|
this.accel = 0.95f;
|
|
this.glidingPercent = 1f;
|
|
}
|
|
else
|
|
{
|
|
this.accel = 0.55f;
|
|
if (this.state == EntityWraith.State.Home || this.state == EntityWraith.State.Wander)
|
|
{
|
|
this.accel = 0.8f;
|
|
if (this.isCircling)
|
|
{
|
|
this.glidingPercent = 1f;
|
|
}
|
|
}
|
|
}
|
|
if (this.attackDelay > 0)
|
|
{
|
|
this.glidingPercent = 0f;
|
|
}
|
|
if (this.currentTarget && this.currentTarget.AttachedToEntity)
|
|
{
|
|
if (this.IsBloodMoon && this.accel > 0.5f)
|
|
{
|
|
this.accel = 2.5f;
|
|
}
|
|
this.accel *= this.moveSpeedAggro;
|
|
}
|
|
else
|
|
{
|
|
this.accel *= this.moveSpeed;
|
|
}
|
|
this.motion = this.motion * 0.9f + vector3 * (this.accel * 0.1f);
|
|
this.glidingCurrentPercent = Mathf.MoveTowards(this.glidingCurrentPercent, this.glidingPercent, 0.060000002f);
|
|
this.emodel.avatarController.UpdateFloat("Gliding", this.glidingCurrentPercent);
|
|
if (this.attackDelay > 0)
|
|
{
|
|
this.attackDelay--;
|
|
}
|
|
if (this.attack2Delay > 0)
|
|
{
|
|
this.attack2Delay--;
|
|
}
|
|
float num6 = Mathf.Atan2(this.motion.x * this.motionReverseScale, this.motion.z * this.motionReverseScale) * 57.29578f;
|
|
if (this.currentTarget)
|
|
{
|
|
num2 = this.targetSwitchDelay - 1;
|
|
this.targetSwitchDelay = num2;
|
|
if (num2 <= 0)
|
|
{
|
|
this.targetSwitchDelay = 60;
|
|
if (this.state != EntityWraith.State.AttackStop)
|
|
{
|
|
EntityPlayer entityPlayer5 = this.FindTarget();
|
|
|
|
EntityPlayer closestPlayer = null;
|
|
float numTarget = 200 * 200;
|
|
float numTarget2 = float.MaxValue;
|
|
for (int i = this.world.Players.list.Count - 1; i >= 0; i--)
|
|
{
|
|
EntityPlayer entityPlayer = this.world.Players.list[i];
|
|
if (!entityPlayer.IsDead() && entityPlayer.Spawned)
|
|
{
|
|
////Log.Out("FOUND PLAYER: " + entityPlayer.EntityName);
|
|
float distanceSq = entityPlayer.GetDistanceSq(this.position);
|
|
if (distanceSq < numTarget2 && distanceSq <= numTarget)
|
|
{
|
|
numTarget2 = distanceSq;
|
|
closestPlayer = entityPlayer;
|
|
}
|
|
}
|
|
}
|
|
|
|
entityPlayer5 = closestPlayer;
|
|
|
|
if (entityPlayer5 && entityPlayer5 != this.attackTarget)
|
|
{
|
|
base.SetAttackTarget(entityPlayer5, 400);
|
|
}
|
|
}
|
|
float num7 = this.currentTarget.AttachedToEntity ? 0.1f : 0.25f;
|
|
if (this.state != EntityWraith.State.AttackReposition && this.rand.RandomFloat < num7)
|
|
{
|
|
this.StartAttackReposition();
|
|
}
|
|
}
|
|
}
|
|
if (this.currentTarget)
|
|
{
|
|
Vector3 vector4 = this.currentTarget.getHeadPosition();
|
|
vector4 += this.currentTarget.GetVelocityPerSecond() * 0.2f;
|
|
Vector3 vector5 = vector4 - this.position;
|
|
float sqrMagnitude2 = vector5.sqrMagnitude;
|
|
if ((sqrMagnitude2 > 6400f && !this.IsBloodMoon) || this.currentTarget.IsDead())
|
|
{
|
|
this.SetState(EntityWraith.State.AttackStop);
|
|
}
|
|
else if (this.state != EntityWraith.State.AttackReposition)
|
|
{
|
|
if (sqrMagnitude2 < 4f)
|
|
{
|
|
num6 = Mathf.Atan2(vector5.x, vector5.z) * 57.29578f;
|
|
}
|
|
if (this.attackDelay <= 0 && !this.isAttack2On)
|
|
{
|
|
if (sqrMagnitude2 < 0.64000005f && this.position.y >= this.currentTarget.position.y && this.position.y < vector4.y + 0.1f)
|
|
{
|
|
this.AttackAndAdjust(false);
|
|
}
|
|
else if (this.checkBlockedDelay > 0)
|
|
{
|
|
this.checkBlockedDelay--;
|
|
}
|
|
else
|
|
{
|
|
this.checkBlockedDelay = 6;
|
|
Vector3 normalized = vector5.normalized;
|
|
Ray ray = new Ray(this.position + new Vector3(0f, 0.22f, 0f) - normalized * 0.13f, normalized);
|
|
if (Voxel.Raycast(this.world, ray, 0.83f, 1082195968, 128, 0.13f))
|
|
{
|
|
this.AttackAndAdjust(true);
|
|
}
|
|
}
|
|
}
|
|
bool flag3 = false;
|
|
ItemActionVomit.ItemActionDataVomit itemActionDataVomit = this.inventory.holdingItemData.actionData[1] as ItemActionVomit.ItemActionDataVomit;
|
|
if (itemActionDataVomit != null && this.attack2Delay <= 0 && sqrMagnitude2 >= 9f)
|
|
{
|
|
float range = ((ItemActionRanged)this.inventory.holdingItem.Actions[1]).GetRange(itemActionDataVomit);
|
|
if (sqrMagnitude2 < range * range && Utils.FastAbs(Mathf.DeltaAngle(num6, this.rotation.y)) < 20f && Utils.FastAbs(Vector3.SignedAngle(vector5, base.transform.forward, Vector3.right)) < 25f)
|
|
{
|
|
flag3 = true;
|
|
}
|
|
}
|
|
if (!this.isAttack2On && flag3)
|
|
{
|
|
this.isAttack2On = true;
|
|
itemActionDataVomit.muzzle = this.emodel.GetHeadTransform();
|
|
itemActionDataVomit.numWarningsPlayed = 999;
|
|
}
|
|
if (this.isAttack2On)
|
|
{
|
|
if (!flag3)
|
|
{
|
|
this.isAttack2On = false;
|
|
}
|
|
else
|
|
{
|
|
this.motion *= 0.7f;
|
|
this.SetLookPosition(vector4);
|
|
base.Use(false);
|
|
if (itemActionDataVomit.isDone)
|
|
{
|
|
this.isAttack2On = false;
|
|
}
|
|
}
|
|
if (!this.isAttack2On)
|
|
{
|
|
if (itemActionDataVomit.numVomits > 0)
|
|
{
|
|
this.StartAttackReposition();
|
|
}
|
|
base.Use(true);
|
|
this.attack2Delay = 60;
|
|
this.SetLookPosition(Vector3.zero);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
float magnitude2 = this.motion.magnitude;
|
|
if (magnitude2 < 0.02f)
|
|
{
|
|
this.motion *= 1f / magnitude2 * 0.02f;
|
|
}
|
|
base.SeekYaw(num6, 0f, 20f);
|
|
this.aiManager.UpdateDebugName();
|
|
}
|
|
|
|
public override string MakeDebugNameInfo()
|
|
{
|
|
return string.Format("\n{0} {1}\nWaypoint {2}\nTarget {3}, AtkDelay {4}, BtlTime {5}\nSpeed {6}, Motion {7}, Accel {8}", new object[]
|
|
{
|
|
this.state.ToStringCached<EntityWraith.State>(),
|
|
this.stateTime.ToCultureInvariantString("0.00"),
|
|
this.waypoint.ToCultureInvariantString(),
|
|
this.currentTarget ? this.currentTarget.name : "",
|
|
this.attackDelay,
|
|
this.battleDuration.ToCultureInvariantString("0.00"),
|
|
this.motion.magnitude.ToCultureInvariantString("0.000"),
|
|
this.motion.ToCultureInvariantString("0.000"),
|
|
this.accel.ToCultureInvariantString("0.000")
|
|
});
|
|
}
|
|
|
|
private void SetState(EntityWraith.State newState)
|
|
{
|
|
this.state = newState;
|
|
this.stateTime = 0f;
|
|
this.motionReverseScale = 1f;
|
|
}
|
|
|
|
private void AdjustWaypoint()
|
|
{
|
|
int num = 255;
|
|
Vector3i pos = new Vector3i(this.waypoint);
|
|
while (!this.world.GetBlock(pos).isair && --num >= 0)
|
|
{
|
|
this.waypoint.y = this.waypoint.y + 1f;
|
|
pos.y++;
|
|
}
|
|
this.waypoint.y = Mathf.Min(this.waypoint.y, 250f);
|
|
}
|
|
|
|
private void StartAttackReposition()
|
|
{
|
|
this.SetState(EntityWraith.State.AttackReposition);
|
|
this.stateMaxTime = this.rand.RandomRange(0.8f, 5f);
|
|
this.attackCount = 0;
|
|
this.waypoint = this.position;
|
|
this.waypoint.x = this.waypoint.x + (this.rand.RandomFloat * 8f - 4f);
|
|
this.waypoint.y = this.waypoint.y + (this.rand.RandomFloat * 4f + 3f);
|
|
this.waypoint.z = this.waypoint.z + (this.rand.RandomFloat * 8f - 4f);
|
|
this.moveUpdateDelay = 0;
|
|
this.motion = -this.motion;
|
|
if (this.rand.RandomFloat < 0.5f)
|
|
{
|
|
this.motionReverseScale = -1f;
|
|
this.motion.y = 0.2f;
|
|
}
|
|
}
|
|
|
|
private void ClearTarget()
|
|
{
|
|
base.attackTarget = (EntityAlive) null;
|
|
base.SetRevengeTarget((EntityAlive) null);
|
|
this.currentTarget = null;
|
|
}
|
|
|
|
private EntityPlayer FindTarget()
|
|
{
|
|
EntityPlayer closestPlayer = null;
|
|
float numTarget = 200 * 200;
|
|
float numTarget2 = float.MaxValue;
|
|
for (int i = this.world.Players.list.Count - 1; i >= 0; i--)
|
|
{
|
|
EntityPlayer entityPlayer = this.world.Players.list[i];
|
|
if (!entityPlayer.IsDead() && entityPlayer.Spawned)
|
|
{
|
|
////Log.Out("FOUND PLAYER: " + entityPlayer.EntityName);
|
|
float distanceSq = entityPlayer.GetDistanceSq(this.position);
|
|
if (distanceSq < numTarget2 && distanceSq <= numTarget)
|
|
{
|
|
numTarget2 = distanceSq;
|
|
closestPlayer = entityPlayer;
|
|
}
|
|
}
|
|
}
|
|
return closestPlayer;
|
|
}
|
|
|
|
public override float GetEyeHeight()
|
|
{
|
|
return 0.3f;
|
|
}
|
|
|
|
public override Vector3 GetLookVector()
|
|
{
|
|
if (this.lookAtPosition.Equals(Vector3.zero))
|
|
{
|
|
return base.GetLookVector();
|
|
}
|
|
return this.lookAtPosition - this.getHeadPosition();
|
|
}
|
|
|
|
public override int DamageEntity(
|
|
DamageSource _damageSource,
|
|
int _strength,
|
|
bool _criticalHit,
|
|
float _impulseScale)
|
|
{
|
|
//Log.Out("EntityWraith-DamageEntity START, _strength: " + _strength);
|
|
|
|
if (!this.Buffs.HasBuff("FuriousRamsayWraithProtection"))
|
|
{
|
|
//Log.Out("EntityWraith-CanDamageEntity SHIELD IS UP");
|
|
return 0;
|
|
}
|
|
|
|
return base.DamageEntity(_damageSource, _strength, _criticalHit, _impulseScale);
|
|
}
|
|
|
|
/*public override bool CanDamageEntity(int _sourceEntityId)
|
|
{
|
|
//Log.Out("EntityWraith-CanDamageEntity START");
|
|
if (!this.Buffs.HasBuff("FuriousRamsayWraithProtection"))
|
|
{
|
|
//Log.Out("EntityWraith-CanDamageEntity SHIELD IS UP");
|
|
return false;
|
|
}
|
|
|
|
Entity entity = this.world.GetEntity(_sourceEntityId);
|
|
return !entity || entity.entityClass != this.entityClass;
|
|
}*/
|
|
|
|
private void AttackAndAdjust(bool isBlock)
|
|
{
|
|
if (base.Attack(false))
|
|
{
|
|
base.Attack(true);
|
|
this.attackDelay = 18;
|
|
this.isCircling = false;
|
|
if (this.currentTarget.AttachedToEntity)
|
|
{
|
|
this.motion *= 0.7f;
|
|
}
|
|
else
|
|
{
|
|
this.motion *= 0.6f;
|
|
}
|
|
int num = this.attackCount + 1;
|
|
this.attackCount = num;
|
|
if (num >= 5 || this.rand.RandomFloat < 0.25f)
|
|
{
|
|
this.StartAttackReposition();
|
|
}
|
|
}
|
|
}
|
|
|
|
private const float cFlyingMinimumSpeed = 0.02f;
|
|
private const float cTargetDistanceClose = 0.8f;
|
|
private const float cTargetDistanceMax = 80f;
|
|
private const float cTargetAttackOffsetY = -0.1f;
|
|
private const float cVomitMinRange = 3f;
|
|
private const int cAttackDelay = 18;
|
|
private const int cCollisionMask = 1082195968;
|
|
private const float cBattleFatigueMin = 30f;
|
|
private const float cBattleFatigueMax = 90f;
|
|
private const float cBattleFatigueCooldownMin = 60f;
|
|
private const float cBattleFatigueCooldownMax = 180f;
|
|
private bool isRadiated;
|
|
private int moveUpdateDelay;
|
|
private float motionReverseScale = 1f;
|
|
private Vector3 waypoint;
|
|
private bool isCircling;
|
|
private Vector3 circleCenter;
|
|
private float circleReverseScale;
|
|
private float glidingCurrentPercent;
|
|
private float glidingPercent;
|
|
private float accel;
|
|
private EntityAlive currentTarget;
|
|
private int targetSwitchDelay;
|
|
private int homeCheckDelay;
|
|
private int homeSeekDelay;
|
|
private int wanderChangeDelay;
|
|
private int checkBlockedDelay;
|
|
private float battleDuration;
|
|
private float battleFatigueSeconds;
|
|
private bool isBattleFatigued;
|
|
private int attackDelay;
|
|
private int attackCount;
|
|
private int attack2Delay;
|
|
private bool isAttack2On;
|
|
private EAISetNearestEntityAsTargetSorter sorter;
|
|
private static List<Entity> list = new List<Entity>();
|
|
private EntityWraith.State state;
|
|
private float stateTime;
|
|
private float stateMaxTime;
|
|
protected bool isCourseTraversable(Vector3 _pos, out float _distance)
|
|
{
|
|
float num = _pos.x - this.position.x;
|
|
float num2 = _pos.y - this.position.y;
|
|
float num3 = _pos.z - this.position.z;
|
|
_distance = Mathf.Sqrt(num * num + num2 * num2 + num3 * num3);
|
|
if (_distance < 1.5f)
|
|
{
|
|
return true;
|
|
}
|
|
num /= _distance;
|
|
num2 /= _distance;
|
|
num3 /= _distance;
|
|
Bounds boundingBox = this.boundingBox;
|
|
this.collBB.Clear();
|
|
int num4 = 1;
|
|
while ((float)num4 < _distance - 1f)
|
|
{
|
|
boundingBox.center += new Vector3(num, num2, num3);
|
|
this.world.GetCollidingBounds(this, boundingBox, this.collBB);
|
|
if (this.collBB.Count > 0)
|
|
{
|
|
return false;
|
|
}
|
|
num4++;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private List<Bounds> collBB = new List<Bounds>();
|
|
private enum State
|
|
{
|
|
Attack,
|
|
AttackReposition,
|
|
AttackStop,
|
|
Home,
|
|
Stun,
|
|
WanderStart,
|
|
Wander
|
|
}
|
|
}
|