protected void LegacyTask() { if (!GamePrefs.GetBool(EnumGamePrefs.DebugStopEnemiesMoving)) { if (GameStats.GetInt(EnumGameStats.GameState) != 2) { base.GetEntitySenses().ClearIfExpired(); if (this.MV > 0) { this.MV--; } if (this.MV <= 0) { Vector3 vector = this.HV - this.position; float sqrMagnitude = vector.sqrMagnitude; if (sqrMagnitude < 1f || sqrMagnitude > 2304f) { if (!base.isWithinHomeDistanceCurrentPosition()) { Vector3 hv = RandomPositionGenerator.CalcTowards(this, 2 * base.getMaximumHomeDistance(), 2 * base.getMaximumHomeDistance(), 2 * base.getMaximumHomeDistance(), base.getHomePosition().position.ToVector3()); if (!hv.Equals(Vector3.zero)) { this.HV = hv; this.AV = true; } } else { this.AV = false; if (base.GetRevengeTarget() != null && base.GetRevengeTarget().GetDistanceSq(this) < 2304f && Random.value <= 0.5f) { this.HV = base.GetRevengeTarget().GetPosition() + Vector3.up; } else { this.HV = base.GetPosition() + new Vector3((float)((this.rand.NextDouble() * 2.0 - 1.0) * 16.0), (float)((this.rand.NextDouble() * 2.0 - 1.0) * 16.0), (float)((this.rand.NextDouble() * 2.0 - 1.0) * 16.0)); } } this.HV.y = Mathf.Min(this.HV.y, 250f); } if (this.LV-- <= 0) { this.LV += this.rand.Next(5) + 2; if (this.isCourseTraversable(this.HV, out sqrMagnitude)) { this.motion += vector / sqrMagnitude * 0.1f; } else { this.HV = base.GetPosition(); } } } if (base.GetRevengeTarget() != null && base.GetRevengeTarget().IsDead()) { base.SetRevengeTarget(null); } if (base.GetRevengeTarget() == null || this.EV-- <= 0) { EntityPlayer closestPlayer = this.world.GetClosestPlayer(this, 48f, false); if (base.CanSee(closestPlayer)) { base.SetRevengeTarget(closestPlayer); } if (base.GetRevengeTarget() != null) { this.EV = 20; } } float distanceSq; if (!this.AV && base.GetRevengeTarget() != null && (distanceSq = base.GetRevengeTarget().GetDistanceSq(this)) < 2304f) { float num = base.GetRevengeTarget().position.x - this.position.x; float num2 = base.GetRevengeTarget().position.z - this.position.z; this.rotation.y = Mathf.Atan2(num, num2) * 180f / 3.14159274f; if (this.MV <= 0 && distanceSq < 2.8f && this.position.y >= base.GetRevengeTarget().position.y&& this.position.y <= base.GetRevengeTarget().getHeadPosition().y&& base.Attack(false)) { this.MV = base.GetAttackTimeoutTicks(); base.Attack(true); } } else { this.rotation.y = (float)Math.Atan2((double)this.motion.x, (double)this.motion.z) * 180f / 3.14159274f; } return; } } }
// flocking logic private void flockTasks() { if (GamePrefs.GetBool(EnumGamePrefs.DebugStopEnemiesMoving) || GameStats.GetInt(EnumGameStats.GameState) == 2) { return; } if (world.IsRemote()) { return; } if (IsDead()) { return; } if (masterEntity == null && !hasFlock && maxToSpawn > 0) { SpawnFlock(); } else if (masterEntity == null && hasFlock && oldmasterID > 0) { FindOldMaster(); } GetEntitySenses().ClearIfExpired(); if (AttackTimeout > 0) { AttackTimeout--; } if (AttackTimeout <= 0) { var a = Waypoint - position; var sqrMagnitude = a.sqrMagnitude; if (sqrMagnitude < 1f || sqrMagnitude > 6400f) { if (!isWithinHomeDistanceCurrentPosition() && GetMasterEntity() == null && !isHunting) { // uses vanilla code to stay near "home position" if its a "master" Vector3 ye = RandomPositionGenerator.CalcTowards(this, 2 * base.getMaximumHomeDistance(), 2 * base.getMaximumHomeDistance(), 2 * base.getMaximumHomeDistance(), base.getHomePosition().position.ToVector3()); if (!ye.Equals(Vector3.zero)) { // going home Waypoint = ye; HasWaypoint = true; } } else { HasWaypoint = false; if (!HasWaypoint) { if (base.GetRevengeTarget() != null && (base.GetRevengeTarget().GetDistanceSq(this) < 6400f && Random.value <= 0.5f || isHunting)) { // if it's targeting an enemy. Notice that if it's hunting I just want it to get it done. Waypoint = base.GetRevengeTarget().GetPosition() + Vector3.up; } else { if (GetMasterEntity() == null) { // if it finds a target block nearby, it will go for it. Not attack it, just go near it // this will make them "destroy" crops for example, if we make them target crop blocks. if (FindLandSpot()) { // going for landing spot Waypoint = landPosition + new Vector3((float)((rand.NextDouble() * 2.0 - 1.0) * 3.0), (float)((rand.NextDouble() * 2.0 - 1.0) * 3.0), (float)((rand.NextDouble() * 2.0 - 1.0) * 3.0)); } else { // chooses a random waypoint - vanilla code Waypoint = GetPosition() + new Vector3((float)((rand.NextDouble() * 2.0 - 1.0) * 16.0), (float)((rand.NextDouble() * 2.0 - 1.0) * 16.0), (float)((rand.NextDouble() * 2.0 - 1.0) * 16.0)); // maximum Y. Just to avoid them going too high (out of sight, out of heart) var maxY = world.GetHeight((int)Waypoint.x, (int)Waypoint.z) + maxHeight; if (Waypoint.y > maxY) { Waypoint.y = maxY; } } } else { // if the master has a landing spot, it goes to random position near the landing spot, otherwise just follows master if ((GetMasterEntity() as EntityZombieFlyingSDX).GetLandingSpot() == Vector3.zero) { Waypoint = GetMasterEntity().GetPosition() + Vector3.up; } else { Waypoint = (GetMasterEntity() as EntityZombieFlyingSDX).GetLandingSpot() + new Vector3((float)((rand.NextDouble() * 2.0 - 1.0) * 3.0), (float)((rand.NextDouble() * 2.0 - 1.0) * 3.0), (float)((rand.NextDouble() * 2.0 - 1.0) * 3.0)); } // } } } } var num = 255; AdjustWayPoint(); // if waypoint is not in the air, change it up // while (world.GetBlock(new Vector3i(Waypoint)).type != BlockValue.Air.type && num > 0) // { // Waypoint.y = Waypoint.y + 1f; // num--; // } } Waypoint.y = Mathf.Min(Waypoint.y, 250f); } if (CourseCheck-- <= 0) { CourseCheck += rand.Next(5) + 2; if (isCourseTraversable(Waypoint, out sqrMagnitude)) { motion += a / sqrMagnitude * 0.1f; } else { Waypoint = GetPosition(); } } } float intendedRotation; intendedRotation = (float)Math.Atan2(motion.x, motion.z) * 180f / 3.14159274f; rotation.y = UpdateRotation(rotation.y, intendedRotation, 10f); }
// flocking logic private void flockTasks() { if (GamePrefs.GetBool(EnumGamePrefs.DebugStopEnemiesMoving) || GameStats.GetInt(EnumGameStats.GameState) == 2) { return; } if (this.world.IsRemote()) { return; } if (this.IsDead()) { return; } if (masterEntity == null && !hasFlock && maxToSpawn > 0) { SpawnFlock(); } else if (masterEntity == null && hasFlock && oldmasterID > 0) { FindOldMaster(); } base.GetEntitySenses().ClearIfExpired(); if (this.AttackTimeout > 0) { this.AttackTimeout--; } if (this.AttackTimeout <= 0) { Vector3 a = this.Waypoint - this.position; float sqrMagnitude = a.sqrMagnitude; if (sqrMagnitude < 1f || sqrMagnitude > 6400f) { if (!base.isWithinHomeDistanceCurrentPosition() && this.GetMasterEntity() == null && !isHunting) { // uses vanilla code to stay near "home position" if its a "master" Vector3 ye = RandomPositionGenerator.CalcTowards(this, 2 * base.getMaximumHomeDistance(), 2 * base.getMaximumHomeDistance(), 2 * base.getMaximumHomeDistance(), base.getHomePosition().position.ToVector3()); if (!ye.Equals(Vector3.zero)) { if (debug) { Debug.Log("Going Home"); } this.Waypoint = ye; this.HasWaypoint = true; } } else { this.HasWaypoint = false; if (base.GetRevengeTarget() != null && ((base.GetRevengeTarget().GetDistanceSq(this) < 6400f && UnityEngine.Random.value <= 0.5f) || isHunting)) { // if it's targeting an enemy. Notice that if it's hunting I just want it to get it done. this.Waypoint = base.GetRevengeTarget().GetPosition() + Vector3.up; } else { if (this.GetMasterEntity() == null) { // if it finds a target block nearby, it will go for it. Not attack it, just go near it // this will make them "destroy" crops for example, if we make them target crop blocks. if (FindLandSpot()) { // going for landing spot this.Waypoint = landPosition + new Vector3((float)((this.rand.RandomDouble * 2.0 - 1.0) * 3.0), (float)((this.rand.RandomDouble * 2.0 - 1.0) * 3.0), (float)((this.rand.RandomDouble * 2.0 - 1.0) * 3.0)); } else { // chooses a random waypoint - vanilla code this.Waypoint = base.GetPosition() + new Vector3((float)((this.rand.RandomDouble * 2.0 - 1.0) * 16.0), (float)((this.rand.RandomDouble * 2.0 - 1.0) * 16.0), (float)((this.rand.RandomDouble * 2.0 - 1.0) * 16.0)); // maximum Y. Just to avoid them going too high (out of sight, out of heart) int maxY = this.world.GetHeight((int)this.Waypoint.x, (int)this.Waypoint.z) + maxHeight; if (this.Waypoint.y > maxY) { this.Waypoint.y = maxY; if (debug) { Debug.Log("Prevented it from going higher"); } } } } else { if ((this.GetMasterEntity() as EntityZombieFlockSDX).GetRevengeTarget() != null) { // attacks the same target as master this.SetRevengeTarget((this.GetMasterEntity() as EntityZombieFlockSDX).GetRevengeTarget()); this.Waypoint = (this.GetMasterEntity() as EntityZombieFlockSDX).GetRevengeTarget().GetPosition() + Vector3.up; } else { // if the master has a landing spot, it goes to random position near the landing spot, otherwise just follows master if ((this.GetMasterEntity() as EntityZombieFlockSDX).GetLandingSpot() == Vector3.zero) { this.Waypoint = this.GetMasterEntity().GetPosition() + Vector3.up; } else { this.Waypoint = (this.GetMasterEntity() as EntityZombieFlockSDX).GetLandingSpot() + new Vector3((float)((this.rand.RandomDouble * 2.0 - 1.0) * 3.0), (float)((this.rand.RandomDouble * 2.0 - 1.0) * 3.0), (float)((this.rand.RandomDouble * 2.0 - 1.0) * 3.0)); } } } } int num = 255; // if waypoint is not in the air, change it up while (this.world.GetBlock(new Vector3i(this.Waypoint)).type != BlockValue.Air.type && num > 0) { this.Waypoint.y = this.Waypoint.y + 1f; num--; } } this.Waypoint.y = Mathf.Min(this.Waypoint.y, 250f); } if (this.CourseCheck-- <= 0) { this.CourseCheck += this.rand.RandomRange(5) + 2; //if (base.isCourseTraversable(this.Waypoint, out sqrMagnitude)) //{ // this.motion += a / sqrMagnitude * 0.1f; //} //else //{ this.Waypoint = base.GetPosition(); //} } } if (base.GetRevengeTarget() != null) { if (!retaliateAttack && !targetPlayers && !isHunting) { base.SetRevengeTarget(null); } else if (base.GetRevengeTarget().IsDead()) { base.SetRevengeTarget(null); isHunting = false; } } // if it's a parent and has no target, then it will look for one. if ((base.GetRevengeTarget() == null) && this.GetMasterEntity() == null) { if (this.TargetInterval-- <= 0) { isHunting = false; if (targetPlayers) { // if it's an agressive animal, will look for a player to attack FindClosestPlayer(); } if ((base.GetRevengeTarget() == null)) { if (naturalEnemies != null) { if (naturalEnemies.Length > 0) { // if it has natural enemies, will look for one to attack FindNaturalEnemy(); } } } if (base.GetRevengeTarget() != null) { this.TargetInterval = 20; } } } float intendedRotation; if (!this.HasWaypoint) { if (base.GetRevengeTarget() != null) { float distanceSq; if ((distanceSq = base.GetRevengeTarget().GetDistanceSq(this)) < 6400f) { float y = base.GetRevengeTarget().position.x - this.position.x; float x = base.GetRevengeTarget().position.z - this.position.z; if (distanceSq < 5f) { intendedRotation = Mathf.Atan2(y, x) * 180f / 3.14159274f; } else { intendedRotation = (float)Math.Atan2((double)this.motion.x, (double)this.motion.z) * 180f / 3.14159274f; if (this.motion.magnitude < 0.25f) { this.motion = this.motion.normalized * 0.25f; } } if (this.AttackTimeout <= 0) { if (distanceSq < 2.8f) { if (this.position.y >= base.GetRevengeTarget().position.y) { if (!isHunting) { if (this.position.y <= base.GetRevengeTarget().getHeadPosition().y - 0.25f) { if (base.Attack(false)) { this.AttackTimeout = base.GetAttackTimeoutTicks(); base.Attack(true); } } } else { // just marks the "target" to unload, as if it had captured it. if (UnityEngine.Random.value <= 0.5f) { if (debug) { Debug.Log("Eating the target!!!"); } base.GetRevengeTarget().MarkToUnload(); // stops hunting to look for another suitable target after a bit isHunting = false; base.SetRevengeTarget(null); this.TargetInterval = 50; } } } } } this.rotation.y = EntityAlive.UpdateRotation(this.rotation.y, intendedRotation, 10f); return; } } } intendedRotation = (float)Math.Atan2((double)this.motion.x, (double)this.motion.z) * 180f / 3.14159274f; this.rotation.y = EntityAlive.UpdateRotation(this.rotation.y, intendedRotation, 10f); }