Ejemplo n.º 1
0
    /*
     * ExecuteMovementGivenTarget
     *
     * given a target to move towards, find the
     * closest tile and move that way
     *
     * @param Unit unit - the unit that is undergoing the movement
     * @param Vector3 target - the vector to optimistically move towards
     * @returns void
     */
    public void ExecuteMovementGivenTarget(Unit unit, Vector3 target)
    {
        //get a list of walkable tiles around the unit
        List <Tiles> walkable = GetArea.GetAreaOfSafeMoveable(map.GetTileAtPos(unit.transform.position), unit.movementPoints, map, unit);

        //worst possible score to start
        float bestMoveScore = float.MaxValue;

        //reference to the best tile that has been found
        Tiles bestTargetTile = null;

        //get the size of the walkable list
        int walkSize = walkable.Count;

        //iterate through all walkable tiles
        for (int i = 0; i < walkSize; i++)
        {
            //store in a temp variable
            Tiles tile = walkable[i];

            //get the squared distance to the tile
            float sqrDistance = (tile.transform.position - target).sqrMagnitude;

            if (sqrDistance < bestMoveScore && tile.unit == null)
            {
                //bestTargetTile the best score
                bestTargetTile = tile;
                bestMoveScore  = sqrDistance;
            }
        }

        //move towards the best tile if one was found
        if (bestTargetTile != null)
        {
            Move(unit, bestTargetTile.pos);
        }
    }
    /*
     * Update
     * overrides UnitCommand's Update()
     *
     * called once per frame while the command is active
     *
     * @returns void
     */
    public override void Update()
    {
        if (m_tilePath == null)
        {
            //get the start and end of the path
            Tiles startingTile = map.GetTileAtPos(unit.transform.position);

            startingTile.unit = null;

            //get the tile path to follow
            if (isSafeMove)
            {
                m_tilePath = AStar.GetSafeAStarPath(startingTile, endTile, unit, GetArea.GetAreaOfSafeMoveable(startingTile, unit.movementPoints, map, unit));
            }
            else
            {
                m_tilePath = AStar.GetAStarPath(startingTile, endTile, unit);
            }

            //the path is clear, and the unit can move there
            if (m_tilePath.Count > 0 && m_tilePath.Count <= unit.movementPoints)
            {
                //subtract the path distance from the movement points
                unit.movementPoints -= m_tilePath.Count;

                startingTile.unit = null;
                endTile.unit      = unit;
            }
            else
            {
                //Stop walking Anim
                if (unit.ArtLink != null)
                {
                    unit.ArtLink.SetBool("IsWalking", false);
                }

                //the path failed
                startingTile.unit = unit;
                failedCallback();
                return;
            }
        }

        m_timer += Time.deltaTime;

        //check if there is still a path to follow
        if (m_tilePath.Count > 0 && m_timer > m_waitTime)
        {
            if (m_finishedWaiting == false)
            {
                m_finishedWaiting = true;

                if (unit.ArtLink != null)
                {
                    unit.ArtLink.SetBool("IsWalking", true);
                }
            }

            //get the next position to go to
            Tiles nextTile = m_tilePath[0];

            //the 3D target of the movement
            Vector3 target = new Vector3(nextTile.pos.x, 0.15f, nextTile.pos.z);

            Vector3 relative = target - unit.transform.position;

            if (relative.magnitude < unit.movementSpeed * Time.deltaTime)
            {
                //this is a healing tile, heal the unit
                if (nextTile.IsHealing(false, unit))
                {
                    unit.Heal(GameManagment.stats.tileHealthGained);
                }

                //this is a trap tile, it could kill the unit
                if (nextTile.tileType == eTileType.PLACABLETRAP || nextTile.tileType == eTileType.DAMAGE)
                {
                    m_timer           = 0;
                    m_finishedWaiting = false;

                    if (unit.ArtLink != null)
                    {
                        unit.ArtLink.SetTrigger("TakeDamage");
                    }

                    unit.Defend(GameManagment.stats.trapTileDamage);

                    //explosion is required
                    if (nextTile.tileType == eTileType.PLACABLETRAP)
                    {
                        //reset the explosion
                        ParticleLibrary.explosionSystem.transform.position = nextTile.transform.position;
                        ParticleLibrary.explosionSystem.time = 0.0f;
                        ParticleLibrary.explosionSystem.Play();
                    }

                    //Stop walking Anim
                    if (unit.ArtLink != null)
                    {
                        unit.ArtLink.SetBool("IsWalking", false);
                    }
                }

                unit.transform.position = target;
                m_tilePath.RemoveAt(0);

                if (unit.playerID == 0)
                {
                    StatisticsTracker.tilesCrossed++;
                }
            }
            else
            {
                unit.transform.position += relative.normalized * unit.movementSpeed * Time.deltaTime;
            }
        }
        else if (m_timer > m_waitTime)
        {
            if (endTile.tileType == eTileType.PLACABLEDEFENSE || endTile.tileType == eTileType.DEFENSE)
            {
                //defensive buff
                endTile.unit.armour = endTile.unit.baseArmour + 1;
            }
            else
            {
                //remove the defensive buff
                endTile.unit.armour = endTile.unit.baseArmour;
            }
            successCallback();

            //Stop walking Anim
            if (unit.ArtLink != null)
            {
                unit.ArtLink.SetBool("IsWalking", false);
            }

            return;
        }
    }