/// <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); }
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); } } }