Пример #1
0
        /// <summary>
        /// 自分の周りの座標で攻撃できる場所を探す
        /// </summary>
        protected bool TryGetAttackTargetPosition(TileFlag targetTileFlag, out Vector2Int targetPos)
        {
            targetPos = Vector2Int.zero;
            _targets.Clear();

            // 現在の座標の周りを調べ行ける場所を目的地とする
            var pos      = _unit.Model.CellPosition.Value;
            var dirArray = Utility.Map.GetDirArray(true);

            for (int i = 0, size = dirArray.GetLength(0); i < size; ++i)
            {
                var addX = dirArray[i, 0];
                var addY = dirArray[i, 1];

                var nextX = pos.x + addX;
                var nextY = pos.y + addY;

                if (!TileDataMap.InRange(nextX, nextY))
                {
                    continue;
                }

                var tileFlag = TileDataMap.GetTileFlag(nextX, nextY);

                // 指定したTileFlagか
                if (!tileFlag.HasAny(targetTileFlag))
                {
                    continue;
                }

                // 斜めの場合は障害物を貫通できるかどうか確認
                if (addX != 0 && addY != 0)
                {
                    // どちらかに障害物があるか
                    var tmp = TileFlag.None;
                    tmp |= _tileDataMap.GetTileFlag(pos.x + addX, pos.y);
                    tmp |= _tileDataMap.GetTileFlag(pos.x, pos.y + addY);

                    // その障害物を越えて攻撃できるか
                    if (!_unit.Model.CanDiagonalAttackTileFlag(tmp))
                    {
                        // 攻撃できないので失敗
                        continue;
                    }
                }

                targetPos = new Vector2Int(nextX, nextY);

                return(true);
            }

            return(false);
        }
Пример #2
0
        private IEnumerator <float> CreateEntrance(TileDataMap prevTildeDataMap)
        {
            if (prevTildeDataMap == null)
            {
                // 部屋のマップを作成する
                TileDataMap.BuildRoomMap();
                yield break;
            }

            // 前マップの下階段の位置に部屋を作成する
            // 下り階段の場所が部屋なら何もしない
            var stepDownPos = prevTildeDataMap.StepDownPos;

            var tileData = TileDataMap.GetTile(stepDownPos.x, stepDownPos.y);

            if (tileData.HasFlag(TileFlag.Floor))
            {
                // 部屋のマップを作成する
                TileDataMap.BuildRoomMap();
                yield break;
            }

            // 3マスで部屋を作成
            var w = Utility.Random.MaxIncludedRange(1, 1);
            var h = Utility.Random.MaxIncludedRange(1, 1);

            // どこかの部屋か道と連結したら終わり
            var xMin = stepDownPos.x - 1;            // - w / 2;
            var xMax = stepDownPos.x + 1;            // + w / 2;
            var yMin = stepDownPos.y - 1;            // - h / 2;
            var yMax = stepDownPos.y + 1;            // + h / 2;

            bool shouldCreateRoad = true;

            // 隣接しているかチェック
            for (int y = yMin; y < yMax; ++y)
            {
                for (int x = xMin; x < xMax; ++x)
                {
                    if (!TileDataMap.InRange(x, y))
                    {
                        continue;
                    }

                    if (TileDataMap.IsAdjacent(x, y, TileFlag.Floor | TileFlag.Road))
                    {
                        shouldCreateRoad = false;
                        break;
                    }
                }
            }

            TileDataMap.FillRect(xMin, yMin, xMax, yMax, TileFlag.Floor,
                                 tileData_ =>
            {
                return(true);
            });

            // 部屋のマップを作成する
            TileDataMap.BuildRoomMap();

            // 道を作る必要がある場合作成
            if (shouldCreateRoad)
            {
                // 部屋マップの値を取得
                var roomValue = TileDataMap.GetRoomIndex(stepDownPos.x, stepDownPos.y);

                // 一番近い部屋か道とつなげる
                var route = new Route.Tracking();
                route.Setup(TileDataMap);

                // 自分の部屋は1とする。
                // 自分以外の部屋か道が見つかったら終わり
                route.Execute(stepDownPos.x, stepDownPos.y,
                              (tracking_, cellPos_, newValue_, oldValue_) =>
                {
                    // 自分の部屋か
                    if (TileDataMap.EqualRoomMapValue(cellPos_.x, cellPos_.y, roomValue))
                    {
                        // すでに書き込まれていたらスキップ
                        if (oldValue_ == 1)
                        {
                            return(-1);
                        }

                        // 自分の部屋は 1 として書き込む
                        return(1);
                    }

                    // 自分が2(部屋の外周)じゃないのに部屋の隣りにいるならばだめ
                    if (newValue_ > 2)
                    {
                        if (Utility.Map.CallDirection(cellPos_.x, cellPos_.y,
                                                      (x_, y_) =>
                        {
                            // 自分の部屋があればおわり
                            return(TileDataMap.EqualRoomMapValue(x_, y_, roomValue));
                        }))
                        {
                            return(-1);
                        }
                    }

                    // 前後左右が自分以外の部屋か道ならおわり
                    Utility.Map.CallDirection(cellPos_.x, cellPos_.y,
                                              (x_, y_) =>
                    {
                        if (!TileDataMap.InRange(x_, y_))
                        {
                            return(false);
                        }

                        if (TileDataMap.EqualRoomMapValue(x_, y_, roomValue))
                        {
                            return(false);
                        }

                        // 部屋か道を見つける
                        var tileFlag = TileDataMap.GetTileFlag(x_, y_);
                        if (tileFlag.HasFlag(TileFlag.Floor) || tileFlag.HasFlag(TileFlag.Road))
                        {
                            tracking_.ProcessFinish();
                            return(true);
                        }

                        return(false);
                    });

                    return(0);
                });

                // ルートを道にする
                var posList = route.GetRoute(route.ForceFinishPos, useDiagonal: false);

                foreach (var pos in posList)
                {
                    // 部屋なら何もしない
                    if (TileDataMap.GetTileFlag(pos.x, pos.y).HasFlag(TileFlag.Floor))
                    {
                        continue;
                    }

                    TileDataMap.SetTileFlag(pos, TileFlag.Road);
                }
            }
        }