コード例 #1
0
    // 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);
    }