Example #1
0
    public static Tuple <int, int> GetTileIndex(int posx, int posy, HexagonDirection dir, int range)
    {
        var offsetX = 0;
        var offsetY = 0;

        switch (dir)
        {
        case HexagonDirection.UpRight:
            offsetY = range;
            offsetX = range / 2;
            if (range % 2 == 1 && posy % 2 == 1)
            {
                offsetX++;
            }
            break;

        case HexagonDirection.UpLeft:
            offsetY = range;
            offsetX = -range / 2;
            if (range % 2 == 1 && posy % 2 == 0)
            {
                offsetX--;
            }
            break;

        case HexagonDirection.DownRight:
            offsetY = -range;
            offsetX = range / 2;
            if (range % 2 == 1 && posy % 2 == 1)
            {
                offsetX++;
            }
            break;

        case HexagonDirection.DownLeft:
            offsetY = -range;
            offsetX = -range / 2;
            if (range % 2 == 1 && posy % 2 == 0)
            {
                offsetX--;
            }
            break;

        case HexagonDirection.Right:
            offsetX = range;
            break;

        case HexagonDirection.Left:
            offsetX = -range;
            break;
        }

        return(Tuple.Create(posx + offsetX, posy + offsetY));
    }
    public HexagonTile GetNeighbor(HexagonTile p, HexagonDirection direction)
    {
        int dX = 0;
        int dZ = 0;

        switch (direction)
        {
        case HexagonDirection.TOP:
            dZ = 1;
            break;

        case HexagonDirection.BOTTOM:
            dZ = -1;
            break;

        case HexagonDirection.LEFT_TOP:
            dX = -1;
            dZ = p.TileX % 2 == 0 ? 0 : 1;
            break;

        case HexagonDirection.LEFT_BOTTOM:
            dX = -1;
            dZ = p.TileX % 2 == 0 ? -1 : 0;
            break;

        case HexagonDirection.RIGHT_TOP:
            dX = 1;
            dZ = p.TileX % 2 == 0 ? 0 : 1;
            break;

        case HexagonDirection.RIGHT_BOTTOM:
            dX = 1;
            dZ = p.TileX % 2 == 0 ? -1 : 0;
            break;
        }

        GameObject temp = this[new Point(p.TileX + dX, p.TileZ + dZ)];

        if (temp == null)
        {
            return(null);
        }
        return(temp.GetComponent <HexagonTile>());
    }
 public override void BuffTeam(string team, HexagonCell myCell) // every unit that is in the team, if they are next to the hero, buff them
 {
     if (team == "P1")
     {
         for (int i = 1; i < editor.P1Team.Count; i++)                                     // for every unit
         {
             for (HexagonDirection d = HexagonDirection.NE; d <= HexagonDirection.NW; d++) // for every neighboring cell
             {
                 HexagonCell neighbor = myCell.GetNeighbor(d);
                 if (neighbor != null && neighbor.unitOnTile == editor.P1Team[i]) // if the unit is next to the hero
                 {
                     Buff(editor.P1Team[i]);
                     wasBuffed.Add(editor.P1Team[i]);
                     defense += 5;
                 }
             }
         }
     }
     else
     {
         for (int i = 1; i < editor.P2Team.Count; i++)                                     // for every unit
         {
             for (HexagonDirection d = HexagonDirection.NE; d <= HexagonDirection.NW; d++) // for every neighboring cell
             {
                 HexagonCell neighbor = myCell.GetNeighbor(d);
                 //There is some kind of BUG happening here when a unit dies next to a fortess hero
                 if (neighbor != null && neighbor.unitOnTile == editor.P2Team[i]) // if the unit is next to the hero
                 {
                     Buff(editor.P2Team[i]);
                     wasBuffed.Add(editor.P2Team[i]);
                     defense += 5;
                 }
             }
         }
     }
 }
Example #4
0
 public static Tuple <int, int> GetTileIndex(int posx, int posy, HexagonDirection dir, int range)
 {
     return(TileIndexComputer.GetTileIndex(posx, posy, dir, range));
 }
Example #5
0
 public static HexagonDirection Opposite(this HexagonDirection direction)
 {
     return((int)direction < 3 ? direction + 3 : direction - 3);
 }
 public void SetNeighbor(HexagonDirection direction, HexagonCell cell)
 {
     neighbors[(int)direction] = cell;
     cell.neighbors[(int)direction.Opposite()] = this;
 }
 public HexagonCell GetNeighbor(HexagonDirection direction)
 {
     return(neighbors[(int)direction]);
 }
Example #8
0
    public IEnumerator Kidnap(Grid hexGrid, HexagonCell unitCell) // kidnap a random dumbass
    {
        Debug.Log("kidnap the unit");
        end_attack_without_retaliate = true;
        attacked_unit_has_died       = false;

        string name = unitCell.unitOnTile.unit_name;

        attackRange = specialRange;

        //add a call to a retaliate function on the other unit
        List <HexagonCell> targetable = new List <HexagonCell>();

        //Debug.Log(unitCell.unitOnTile.unit_name + " atttacking: ");
        foreach (HexagonCell cell in hexGrid.cells)
        {
            if (unitCell.coords.FindDistanceTo(cell.coords) <= attackRange &&
                unitCell.coords.FindDistanceTo(cell.coords) > 0 &&
                cell.occupied &&
                !cell.unitOnTile.dead &&
                tag != cell.unitOnTile.tag)
            {
                targetable.Add(cell);
            }
        }

        if (targetable.Count >= 1)
        {
            editor.cursor.Assign_Position(this.transform.position, hexGrid.GetCell(this.transform.position).coords);
            Vector3 _new_Camera_Pos = new Vector3(this.transform.position.x, this.transform.position.y, editor.Main_Cam.transform.position.z);
            editor.Main_Cam.transform.position = Vector3.Lerp(editor.Main_Cam.transform.position, _new_Camera_Pos, 1f);

            yield return(new WaitForSeconds(0.3f));

            int selectedTarget = ChosenEnemy(targetable);

            float crit_chance = Random.value;
            float miss_chance = Random.value;
            float damage;
            if (targetable[selectedTarget].GetComponent <HeroUnit>() != null)
            {
                damage = (current_attack * 1.5f) - targetable[selectedTarget].unitOnTile.defense;
            }
            else
            {
                damage = current_attack - targetable[selectedTarget].unitOnTile.defense;
            }
            Debug.Log("Damage: " + damage);
            int  dmg_txt       = (int)damage;
            bool crit_happened = false;

            editor.printState();
            if (targetable[selectedTarget].unitOnTile.FloatingTextPrefab)
            {
                //Debug.Log("fadef");
                if (miss_chance <= miss)
                {
                    damage = 0;
                }
                else
                {
                    if (crit_chance <= crit && miss_chance > miss)
                    {
                        int rand = Random.Range(0, 2);
                        if (rand == 0)
                        {
                            GameObject.FindGameObjectWithTag("SoundManager").GetComponent <SoundManager>().PlayOneFromList(GameObject.FindGameObjectWithTag("SoundManager").GetComponent <SoundManager>().critSounds);
                        }
                        damage        = current_attack * crit_multiplier;
                        crit_happened = true;
                    }
                }
                dmg_txt = (int)damage;
            }



            //for (HexagonDirection d = HexagonDirection.NE; d <= HexagonDirection.NW; d++)
            //{
            //    HexagonCell neighbor = unitCell.GetNeighbor(d);
            //    if (!neighbor.occupied && neighbor.tag != "Wall" && targetable[selectedTarget].unitOnTile.GetComponent<HeroUnit>() == null) // if a neighbor to the hero is not occupied or wall unit not hero
            //    {
            //        targetable[selectedTarget].unitOnTile.transform.position = neighbor.transform.position; // move the bitch
            //        neighbor.occupied = true;
            //        neighbor.unitOnTile = targetable[selectedTarget].unitOnTile;
            //        temp_attacked_unit = neighbor.unitOnTile;
            //        temp_attacked_cell = neighbor;
            //        targetable[selectedTarget].occupied = false;
            //        targetable[selectedTarget].unitOnTile = null;
            //        //correctly sort kidnapped unit's meshes
            //        editor.re_sort_unit_position(temp_attacked_unit, temp_attacked_cell);
            //        break;
            //    }
            //}

            StartUnit   attacked_unit;
            HexagonCell attacked_cell;
            if (temp_attacked_unit != null)
            {
                attacked_unit = temp_attacked_unit;
                attacked_cell = temp_attacked_cell;
            }
            else
            {
                attacked_unit = targetable[selectedTarget].unitOnTile;
                attacked_cell = targetable[selectedTarget];
            }
            HexagonCoord current = unitCell.coords;

            if (attacked_cell.gameObject.transform.position.x > transform.position.x) //unit is to the right
            {
                if (!direction)                                                       //facing left, so needs to face right
                {
                    transform.localScale = new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z);
                    direction            = true;
                }
            }
            else //unit is to the left
            {
                if (direction)
                {
                    transform.localScale = new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z);
                    direction            = false;
                }
            }

            //-------------------------- Testing Kidnapp Stuff ----------------------

            StartCoroutine(move_to_kidnap(attacked_unit.gameObject, attacked_unit, attacked_cell, targetable[selectedTarget]));
            if (targetable[selectedTarget].unitOnTile.GetComponent <HeroUnit>() == null)
            {
                yield return(new WaitForSeconds(1.40f)); //---- for sync with kidnap to
            }
            else
            {
                yield return(new WaitForSeconds(2.10f)); //---- for sync with kidnap to
            }



            for (HexagonDirection d = HexagonDirection.NE; d <= HexagonDirection.NW; d++)
            {
                HexagonCell neighbor = unitCell.GetNeighbor(d);
                if (!neighbor.occupied && neighbor.tag != "Wall" && targetable[selectedTarget].unitOnTile.GetComponent <HeroUnit>() == null) // if a neighbor to the hero is not occupied or wall unit not hero
                {
                    targetable[selectedTarget].unitOnTile.transform.position = neighbor.transform.position;                                  // move the bitch
                    neighbor.occupied   = true;
                    neighbor.unitOnTile = targetable[selectedTarget].unitOnTile;
                    temp_attacked_unit  = neighbor.unitOnTile;
                    temp_attacked_cell  = neighbor;
                    targetable[selectedTarget].occupied   = false;
                    targetable[selectedTarget].unitOnTile = null;
                    //correctly sort kidnapped unit's meshes
                    editor.re_sort_unit_position(temp_attacked_unit, temp_attacked_cell);
                    break;
                }
            }

            yield return(new WaitForSeconds(0.26f)); //---- for sync with kidnap to


            if (temp_attacked_unit != null)
            {
                attacked_unit = temp_attacked_unit;
                attacked_cell = temp_attacked_cell;
            }
            else
            {
                attacked_unit = targetable[selectedTarget].unitOnTile;
                attacked_cell = targetable[selectedTarget];
            }

            if (attacked_cell.gameObject.transform.position.x > transform.position.x) //unit is to the right
            {
                if (!direction)                                                       //facing left, so needs to face right
                {
                    transform.localScale = new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z);
                    direction            = true;
                }
            }
            else //unit is to the left
            {
                if (direction)
                {
                    transform.localScale = new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z);
                    direction            = false;
                }
            }

            //-------------------------- Testing Kidnapp Stuff ---------------------- ^^^^

            if (attacked_unit.FloatingTextPrefab)
            {
                GameObject damagetext = Instantiate(attacked_unit.FloatingTextPrefab, attacked_unit.transform.position, Quaternion.identity, attacked_unit.transform);
                if (damage == 0)
                {
                    damagetext.GetComponent <TextMesh>().text = "MISS";
                    int rand = Random.Range(0, 2);
                    if (rand == 0)
                    {
                        GameObject.FindGameObjectWithTag("SoundManager").GetComponent <SoundManager>().PlayOneFromList(GameObject.FindGameObjectWithTag("SoundManager").GetComponent <SoundManager>().missSounds);
                    }
                    damagetext.GetComponent <TextMesh>().color         = Color.white;
                    damagetext.GetComponent <TextMesh>().characterSize = 0.06f;
                }


                if (damage != 0)
                {
                    damagetext.GetComponent <TextMesh>().text = dmg_txt.ToString();
                    if (crit_happened)
                    {
                        damagetext.GetComponent <TextMesh>().color         = Color.red;
                        damagetext.GetComponent <TextMesh>().characterSize = 0.03f + (0.06f * ((float)dmg_txt / 75f));
                    }
                    else
                    {
                        damagetext.GetComponent <TextMesh>().color         = Color.yellow;
                        damagetext.GetComponent <TextMesh>().characterSize = 0.03f + (0.06f * ((float)dmg_txt / 75f));
                    }
                }

                if (Mathf.Sign(damagetext.transform.parent.localScale.x) == -1 && Mathf.Sign(damagetext.transform.localScale.x) == 1)
                {
                    damagetext.gameObject.transform.localScale = new Vector3(damagetext.transform.localScale.x * -1, damagetext.transform.localScale.y,
                                                                             damagetext.transform.localScale.z);

                    //damagetext.GetComponent<TextMesh>().color = Color.green;
                    //Debug.Log("BackWards Text");
                }
                else
                {
                    if (Mathf.Sign(damagetext.transform.parent.localScale.x) == 1 && Mathf.Sign(damagetext.transform.localScale.x) == -1)
                    {
                        damagetext.gameObject.transform.localScale = new Vector3(damagetext.transform.localScale.x * -1, damagetext.transform.localScale.y,
                                                                                 damagetext.transform.localScale.z);
                    }
                }
            }
            Debug.Log(name + " attacked " + attacked_unit.unit_name + " for " + damage);
            TakeDamage(attacked_unit, damage);


            //Debug.Log("he dead");
            if (attacked_unit.current_health <= 0)
            {
                GameObject.FindGameObjectWithTag("SoundManager").GetComponent <SoundManager>().PlayOneFromList(GameObject.FindGameObjectWithTag("SoundManager").GetComponent <SoundManager>().killSounds);

                if (attacked_unit.tag == "TeamBuff") // was a buffmonster
                {
                    GameObject buffItem = Instantiate(FloatingBuffPrefab, transform.position, Quaternion.identity, transform);
                    int        randBuff = Random.Range(0, 4);
                    //give correct buff accordingly
                    Debug.Log("acquiring buff");
                    if (randBuff == 0) // movement buff
                    {
                        buffItem.GetComponent <SpriteRenderer>().sprite = mobilityBuff;
                        Debug.Log(name + " got a movement buff");
                        current_mobility += 1;
                        move_buff         = true;
                        if (current_health != health)
                        {
                            current_health += 10;
                        }
                    }
                    else if (randBuff == 1) // crit buff
                    {
                        buffItem.GetComponent <SpriteRenderer>().sprite = critBuff;
                        Debug.Log(name + " got a crit buff");
                        crit     += 0.20f;
                        crit_buff = true;
                        if (current_health != health)
                        {
                            current_health += 10;
                        }
                    }
                    else if (randBuff == 2) // attack buff
                    {
                        Debug.Log(name + " got an attack buff");
                        buffItem.GetComponent <SpriteRenderer>().sprite = attackBuff;
                        attack         += 25;
                        current_attack += 25;
                        attack_buff     = true;
                        if (current_health != health)
                        {
                            current_health += 10;
                        }
                    }
                    else // health buff
                    {
                        Debug.Log(name + " got a health buff");
                        buffItem.GetComponent <SpriteRenderer>().sprite = healthBuff;
                        health         += 100;
                        current_health += 100;

                        health_buff = true;
                    }

                    if (current_health > (health * 0.4f))
                    {
                        this.anim.SetBool("Injured", false);
                        this.Injured = false;
                    }

                    gameObject.GetComponentInChildren <Buff_UI_Manager>().update_current_buffs(this);

                    float healthpercent = current_health / health;             //    120/180 = .667

                    float attack_deduction = 1 - healthpercent;                //   1 - .667 = .333
                    float reduction        = attack_deduction / 2;
                    float new_attack       = attacked_unit.attack * reduction; //   72 * .333 = 23.76
                    current_attack = attack + new_attack;                      // 72 - 23.76 = 48
                }
                end_attack_without_retaliate = true;
                attacked_unit_has_died       = true;
                StartCoroutine(Attack(hexGrid, unitCell, attacked_cell));
                //int index = targetable[rand_index].coords.X_coord + targetable[rand_index].coords.Z_coord * hexGrid.width + targetable[rand_index].coords.Z_coord / 2;
                //editor.RemoveUnitInfo(targetable[rand_index], index);

                editor.Units_To_Delete.Add(attacked_cell);
                attacked_unit.dead = true;


                yield return(new WaitForSeconds(0.3f));

                StartCoroutine(attacked_unit.Hit());
                StartCoroutine(attacked_unit.Blink(editor.Unit_Hurt_Color, attacked_unit, Time.time + 1f));

                //attacked_unit.Fade_Out_Body();
                //Should start some sort of DEATH ANIMATION COROUTINE HERE
                specialAttackCounter = 3;
                attackRange          = 1;
                temp_attacked_cell   = null;
                temp_attacked_unit   = null;
            }
            else
            {
                if (unitCell.coords.FindDistanceTo(attacked_cell.coords) <= attacked_cell.unitOnTile.attackRange)
                {
                    end_attack_without_retaliate = false;
                }
                else
                {
                    end_attack_without_retaliate = true;
                }
                if (current_health - 20 <= 0 && attacked_unit.gameObject.GetComponent <FortressHero>() != null)
                {
                    end_attack_without_retaliate = true;
                }

                StartCoroutine(Attack(hexGrid, unitCell, attacked_cell));
                yield return(new WaitForSeconds(0.3f));

                //if (attacked_unit.gameObject.GetComponent<FortressHero>() != null && damage != 0) // handling of if attacking fortress hero
                //{
                //    Debug.Log("Hurt by fortress hero's armor");
                //    if (FloatingTextPrefab)
                //    {
                //        GameObject damagetext = Instantiate(FloatingTextPrefab, transform.position, Quaternion.identity, transform);
                //        damagetext.GetComponent<TextMesh>().text = 20.ToString();
                //        damagetext.GetComponent<TextMesh>().color = Color.yellow;
                //        damagetext.GetComponent<TextMesh>().characterSize = 0.03f + (0.06f * (20f / 75f));
                //        if (Mathf.Sign(damagetext.transform.parent.localScale.x) == -1 && Mathf.Sign(damagetext.transform.localScale.x) == 1)
                //        {
                //            damagetext.gameObject.transform.localScale = new Vector3(damagetext.transform.localScale.x * -1, damagetext.transform.localScale.y,
                //                damagetext.transform.localScale.z);

                //            //damagetext.GetComponent<TextMesh>().color = Color.green;
                //            //Debug.Log("BackWards Text");
                //        }
                //        else
                //        {
                //            if (Mathf.Sign(damagetext.transform.parent.localScale.x) == 1 && Mathf.Sign(damagetext.transform.localScale.x) == -1)
                //            {
                //                damagetext.gameObject.transform.localScale = new Vector3(damagetext.transform.localScale.x * -1, damagetext.transform.localScale.y,
                //                    damagetext.transform.localScale.z);
                //            }
                //        }
                //    }

                //    TakeDamage(this, 20f);
                //    StartCoroutine(AttackToHit());
                //    StartCoroutine(Blink(editor.Unit_Hurt_Color, this, Time.time + 1f));
                //    if (current_health <= 0) // pretty sure there's more code needed here but i'll ask christophe later
                //    {
                //        editor.Units_To_Delete.Add(unitCell);
                //        dead = true;
                //    }

                //}
                StartCoroutine(attacked_unit.Hit());
                StartCoroutine(attacked_unit.Blink(editor.Unit_Hurt_Color, attacked_unit, Time.time + 1f));
            }
            specialAttackCounter = 3;
            attackRange          = 1;
            temp_attacked_cell   = null;
            temp_attacked_unit   = null;
        }
        else
        {
            specialAttackCounter = 0;
            attackRange          = 1;
            currently_attacking  = false;
        }
    }
Example #9
0
    public void ShowPath(HexagonCell current, int mobility, int range, Color color_m, Color color_a) // displays the movement capabilities of a unit using A*
    {
        List <HexagonCell> frontier = new List <HexagonCell>();

        for (int i = 0; i < cells.Length; i++)
        {
            cells[i].Distance = int.MaxValue;
        }

        HexagonCell fromCell = current;

        //fromCell.spriteRenderer.color = color_m;
        fromCell.Show_Move_Icon();
        fromCell.Distance = 0;
        frontier.Add(fromCell);
        while (frontier.Count > 0)
        {
            HexagonCell curr = frontier[0];
            frontier.RemoveAt(0);
            if (curr.distance == mobility)
            {
                //curr.spriteRenderer.color = color_m;
                curr.Show_Move_Icon();
                continue;
            }
            for (HexagonDirection d = HexagonDirection.NE; d <= HexagonDirection.NW; d++)
            {
                HexagonCell neighbor = curr.GetNeighbor(d);
                if (neighbor == null || neighbor.Distance != int.MaxValue) // no tile there, or explored already
                {
                    continue;
                }
                if (!neighbor.traversable)// if a wall
                {
                    continue;
                }
                if (neighbor.occupied && neighbor.unitOnTile.tag != current.unitOnTile.tag) // if there is an enemy unit on that tile
                {
                    continue;
                }
                int distance = curr.Distance;

                /*if(water)
                 * distance += 3
                 * else if(grass)
                 * distance += 2
                 */
                if (neighbor.tag == "Water")
                {
                    distance += 2;
                }
                else
                {
                    distance += 1;
                }

                if (distance > mobility)
                {
                    continue;
                }
                if (distance < neighbor.Distance)
                {
                    neighbor.Show_Move_Icon();
                    neighbor.Distance = distance;
                    frontier.Add(neighbor);
                }
                frontier.Sort((x, y) => x.Distance.CompareTo(y.Distance));
            }
        }
    }
Example #10
0
    Stack <HexagonCell> Search(HexagonCell fromCell, HexagonCell toCell) // searrch creates a stack of the shortest path given a to and from tile.  this is used for movement animations
    {
        Stack <HexagonCell> result = new Stack <HexagonCell>();

        for (int i = 0; i < cells.Length; i++)
        {
            cells[i].Distance = int.MaxValue;
        }
        List <HexagonCell> frontier = new List <HexagonCell>();

        fromCell.Distance = 0;
        frontier.Add(fromCell);
        while (frontier.Count > 0)
        {
            HexagonCell current = frontier[0];
            frontier.RemoveAt(0);

            if (current == toCell)
            {
                result.Push(toCell);
                current = current.PathFrom;
                while (current != fromCell)
                {
                    result.Push(current);
                    current = current.PathFrom;
                }
                return(result);
            }
            for (HexagonDirection d = HexagonDirection.NE; d <= HexagonDirection.NW; d++)
            {
                HexagonCell neighbor = current.GetNeighbor(d);
                if (neighbor == null || neighbor.Distance != int.MaxValue)
                {
                    continue;
                }
                if (!neighbor.traversable) // if its not traversable end here
                {
                    continue;
                }
                if (neighbor.unitOnTile != null && neighbor.occupied && neighbor.unitOnTile.tag != fromCell.unitOnTile.tag) // if there is an enemy unit on that tile
                {
                    continue;
                }
                int distance = current.Distance;

                /*if(water)
                 * distance += 3
                 * else if(grass)
                 * distance += 2
                 */
                if (current.tag == "Water") // for water tiles increase by 2
                {
                    distance += 2;
                }
                else  // for any other tile increase by 1 (default)
                {
                    distance += 1;
                }

                if (neighbor.Distance == int.MaxValue) // if not traversed yet
                {
                    neighbor.Distance = distance;
                    neighbor.PathFrom = current;
                    frontier.Add(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    neighbor.Distance = distance;
                    neighbor.PathFrom = current;
                }
                frontier.Sort((x, y) => x.Distance.CompareTo(y.Distance));
            }
        }
        return(result = new Stack <HexagonCell>());
    }
Example #11
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="cell"></param>
        /// <returns></returns>
        private bool Search(HexagonCell fromCell, HexagonCell toCell, int speed)
        {
            this.searchFrontierPhase += 2;

            if (this.searchFrontier == null)
            {
                this.searchFrontier = new HexagonCellPriorityQueue();
            }
            else
            {
                this.searchFrontier.Clear();
            }

            // toCell.EnableHighlight(Color.red);
            fromCell.SearchPhase = searchFrontierPhase;
            fromCell.Distance    = 0;
            this.searchFrontier.Enqueue(fromCell);
            while (this.searchFrontier.Count > 0)
            {
                // yield return delay;
                HexagonCell current = searchFrontier.Dequeue();
                current.SearchPhase += 1;

                // 找到目标单元格时结束循环
                if (current == toCell)
                {
                    return(true);
                }

                // 计算移动到目的需要的回合数

                int currentTurn = (current.Distance - 1) / speed;
                for (HexagonDirection d = HexagonDirection.NE; d <= HexagonDirection.NW; d++)
                {
                    HexagonCell neighbor = current.GetNeighbor(d);
                    if (neighbor == null || neighbor.SearchPhase > searchFrontierPhase)
                    {
                        continue;
                    }
                    if (neighbor.Unit)
                    {
                        //  单元格中有单位的时候跳过这个单元格
                        continue;
                    }
                    // 避开有水的地方
                    //if (neighbor.IsUnderwater)
                    //{
                    //    continue;
                    //}
                    // 避开悬崖
                    //if (current.GetEdgeType(neighbor) == HexEdgeType.Cliff)
                    //{
                    //    continue;
                    //}
                    // 沿着道路移动更快
                    // int distance = current.Distance;
                    // 根据移动成本计算
                    int moveCost = 1;
                    //if (current.HasRoadThroughEdge(d))
                    //{
                    //    moveCost = 1;
                    //}
                    //else if (current.Walled != neighbor.Walled)
                    //{
                    //    continue;
                    //}
                    //else
                    //{
                    //    moveCost = edgeType == HexEdgeType.Flat ? 5 : 10;
                    //    moveCost += neighbor.UrbanLevel + neighbor.FarmLevel +
                    //    neighbor.PlantLevel;
                    //}
                    int distance = current.Distance + moveCost;
                    // distance += 1;

                    // 计算移动到目的需要的回合数
                    int turn = (distance - 1) / speed;
                    if (turn > currentTurn)
                    {
                        distance = turn * speed + moveCost;
                    }


                    //if (neighbor.Distance == int.MaxValue)
                    if (neighbor.SearchPhase < this.searchFrontierPhase)
                    {
                        neighbor.SearchPhase = this.searchFrontierPhase;
                        neighbor.Distance    = distance;
                        // neighbor.SetLabel(turn.ToString());
                        neighbor.PathFrom        = current;
                        neighbor.SearchHeuristic = neighbor.Coordinates.DistanceTo(toCell.Coordinates);
                        this.searchFrontier.Enqueue(neighbor);
                    }
                    else if (distance < neighbor.Distance)
                    {
                        neighbor.Distance = distance;
                        // neighbor.SetLabel(turn.ToString());
                        neighbor.PathFrom = current;
                    }
                }
            }

            return(false);
        }
 public static HexagonDirection Next2(this HexagonDirection direction)
 {
     direction += 2;
     return(direction <= HexagonDirection.NW ? direction : (direction - 6));
 }
 public static HexagonDirection Previous2(this HexagonDirection direction)
 {
     direction -= 2;
     return(direction >= HexagonDirection.NE ? direction : (direction + 6));
 }
 public static HexagonDirection Next(this HexagonDirection direction)
 {
     return(direction == HexagonDirection.NW ? HexagonDirection.NE : (direction + 1));
 }
 public static HexagonDirection Previous(this HexagonDirection direction)
 {
     return(direction == HexagonDirection.NE ? HexagonDirection.NW : (direction - 1));
 }