public static void SpawnMonsters_Random() { List <Tile> spawnTiles = new List <Tile>(); int monsterNum = Formula.CalculateMonsterNum(LevelManager.instance.mazeDifficulty); int distancePlayer = Formula.CalculateMonsterPlayerLeastDistance(LevelManager.instance.mazeDifficulty); int distanceMonster = Formula.CalculateMonsterLeastDistance(LevelManager.instance.mazeDifficulty); List <Tile> exclusiveTiles = new List <Tile>(); exclusiveTiles.Add(LevelManager.instance.tileStart); List <Tile> oldList = MazeUTL.UpdateTileListOutOfRange(LevelManager.instance.maze.mazeTileList, exclusiveTiles, distancePlayer); for (int i = 0; i < monsterNum; i++) { oldList = MazeUTL.UpdateTileListOutOfRange(oldList, exclusiveTiles, distanceMonster); Tile spawnTile = oldList[Random.Range(0, oldList.Count)]; spawnTiles.Add(spawnTile); exclusiveTiles.Add(spawnTile); } foreach (Tile tile in spawnTiles) { SpawnMonster(tile); } }
//--------------------------------------- // Detection Logic //--------------------------------------- void UpdateDetectState() { if (MazeUTL.CheckTargetInRangeAndDetectRegion(CurrentTile, level.playerCharacter.CurrentTile, detectRange)) { detectState = DetectState.Alerted; } }
//--------------------------------------- // Action //--------------------------------------- IEnumerator PatrolToNeighborCoroutine() { // Idle for random seconds idleTimer = Random.Range(owner.idleTimeMin, owner.idleTimeMax); while (idleTimer > 0) { //Debug.Log(idleTimer); if (owner.detectState != DetectState.Idle) { break; } idleTimer -= Time.deltaTime; yield return(null); } // Patrol to a random neighbor if (owner.detectState == DetectState.Idle) { List <Tile> neighbors = MazeUTL.GetNeighborTilesWithoutWall(owner.CurrentTile); Tile targetTile = MazeUTL.GetRandomTileFromList(neighbors); owner.TryMoveToTile(targetTile); do { yield return(new WaitForSeconds(0.01f)); } while (owner.CurrentAction == ActionType.Walking); owner.StopWalkingAnim(); } SetActionFinished("PatrolToNeighborCoroutine", true); yield return(null); }
void GenerateDetectRegions(Maze maze) { // Generate regions List <string> regionList = new List <string>(); for (int i = 0; i < maze.mazeLength; i++) { for (int j = 0; j < maze.mazeWidth; j++) { TryUpdateLinearRegionForTile(0, maze.mazeTile[i, j], regionList, maze); TryUpdateLinearRegionForTile(1, maze.mazeTile[i, j], regionList, maze); TryUpdateRectRegionForTile(maze.mazeTile[i, j], regionList, maze); } } maze.detectRegions = regionList; // Assign regions to each tile foreach (Tile tile in maze.mazeTileList) { string tileAddress = MazeUTL.GetTileAddress(tile.X, tile.Z); foreach (string region in regionList) { if (MazeUTL.CheckRegionHasAddress(region, tileAddress)) { tile.detectRegions.Add(region); } } } }
IEnumerator PostReachActionCoroutine() { // If the target is in action range, execute PostReachAction if (reached) { StartCoroutine("PostReachAction"); while (!finishedPostReachAction) { yield return(null); } } // If lost target, turns to Warning state else if (!MazeUTL.CheckTargetInRangeAndDetectRegion(owner.CurrentTile, actionTarget.CurrentTile, owner.detectRange)) { yield return(new WaitForSeconds(0.5f)); if (owner.detectState == DetectState.Alerted) { owner.detectState = DetectState.Warning; } } SetActionFinished("PostReachActionCoroutine", true); yield return(null); }
//--------------------------------------- // Action //--------------------------------------- IEnumerator TryReachActionRangeCoroutine() { CheckReached(); if (!reached) { if (!MazeUTL.CheckTargetInRangeAndDetectRegion(owner.CurrentTile, actionTarget.CurrentTile, actionRange)) { List <Tile> path = MazeUTL.GetShortestPath(owner.CurrentTile, actionTarget.CurrentTile, owner.detectRange); for (int i = 0; i < path.Count; i++) { owner.TryMoveToTile(path[i]); do { CheckReached(); yield return(new WaitForSeconds(0.01f)); } while (owner.CurrentAction == ActionType.Walking); if (reached) { break; } } owner.StopWalkingAnim(); } } SetActionFinished("TryReachActionRangeCoroutine", true); }
public void TryTurn(Tile targetTile) { int dir = MazeUTL.GetNeighborTileDir(currentTile, targetTile); facingRight = dir == 1 ? false : dir == 3 ? true : facingRight; skeletonAnim.skeleton.FlipX = facingRight; }
void GenerateStartPoint_Random(Maze maze) { Tile tile = MazeUTL.GetRandomTileFromList(maze.mazeTileList); tile.SpawnTileItem(level.startPointPrefab); level.tileStart = tile; TilesWithItem.Add(tile); }
public void DisplayRangeTiles() { List <Tile> tiles = MazeUTL.GetRangeTiles(level.playerCharacter.CurrentTile, rangeData); foreach (Tile tile in tiles) { tile.State = TileState.Selectable; } }
protected override void OnDragDropRelease(GameObject surface) { base.OnDragDropRelease(surface); MazeUTL.ResetAllTileState(); if ((surface == null) || (surface.GetComponent <Tile>() == null) || (surface.GetComponent <Tile>().State != TileState.Selectable)) { return; } level.playerCharacter.PlayerAbilities[partType].ActivateAbility(surface.GetComponent <Tile>()); }
public static string GetSharedDetectRegion(Tile org, Tile target) { string targetAddress = MazeUTL.GetTileAddress(target.X, target.Z); foreach (string region in org.detectRegions) { if (CheckRegionHasAddress(region, targetAddress)) { return(region); } } return(null); }
//--------------------------------------- // Action //--------------------------------------- IEnumerator SearchAlertedTargetCoroutine() { Tile previousTile = owner.CurrentTile; // Smart search till the first intersection or being alerted List <Tile> path = MazeUTL.GetShortestPath(owner.CurrentTile, owner.alertedTarget.CurrentTile, (owner.searchRange)); for (int i = 0; i < path.Count; i++) { previousTile = owner.CurrentTile; owner.TryMoveToTile(path[i]); do { yield return(new WaitForSeconds(0.01f)); } while (owner.CurrentAction == ActionType.Walking); if ((owner.detectState == DetectState.Alerted)) { break; } if (MazeUTL.GetNeighborTilesWithoutWall(owner.CurrentTile).Count >= 3) { break; } } // Random search during Warning state while (owner.detectState == DetectState.Warning) { List <Tile> neighbors = MazeUTL.GetNeighborTilesWithoutWall(owner.CurrentTile); if (neighbors.Count > 1) { neighbors.Remove(previousTile); } previousTile = owner.CurrentTile; owner.TryMoveToTile(MazeUTL.GetRandomTileFromList(neighbors)); do { yield return(new WaitForSeconds(0.01f)); } while (owner.CurrentAction == ActionType.Walking); } owner.StopWalkingAnim(); SetActionFinished("SearchAlertedTargetCoroutine", true); yield return(null); }
void GenerateCompass_Random(Maze maze) { int numCompass = Formula.CalculateCompassNum(level.mazeDifficulty); List <Tile> tileList = MazeUTL.UpdateTileListWithDesiredWallLayout(maze.mazeTileList, WallLayout.C); List <Tile> tiles = GetItemSpawnRandomTiles(numCompass, Formula.CalculateItemLeastDistance(LevelManager.instance.mazeDifficulty), new List <Tile>(), tileList, TilesWithItem); Utilities.TryCatchError((tiles.Count < numCompass), "Can't find enough tiles to spawn Compasses. Please check the range condition."); for (int i = 0; i < numCompass; i++) { tiles[i].SpawnTileItem(level.CompassPrefab); TilesWithItem.Add(tiles[i]); } }
void GenerateObjective_Random(Maze maze) { // Make sure the objective is at least half map aways from the start point. Also, make it spawn at C shape wall layout. List <Tile> orgs = new List <Tile>(); orgs.Add(level.tileStart); List <Tile> tileList = MazeUTL.UpdateTileListOutOfRange(maze.mazeTileList, orgs, Formula.CalculateObjectiveLeastDistance(LevelManager.instance.mazeDifficulty)); tileList = MazeUTL.UpdateTileListWithDesiredWallLayout(tileList, WallLayout.C); Tile tile = MazeUTL.GetRandomTileFromList(tileList); tile.SpawnTileItem(level.objectivePrefab); level.tileObjective = tile; TilesWithItem.Add(tile); }
void CheckReached() { if (reached) { return; } if (actionTarget == null) { return; } if (!MazeUTL.CheckTargetInRangeAndDetectRegion(owner.CurrentTile, actionTarget.CurrentTile, actionRange)) { return; } reached = true; }
//--------------------------------------- // Movement //--------------------------------------- public void TryMoveToTile(Tile targetTile) { if (!isAvailable()) { return; } if (targetTile == CurrentTile) { return; } if ((targetTile == null) || (MazeUTL.WallBetweenNeighborTiles(currentTile, targetTile))) { playWalkingAnim = false; return; } MoveToTile(targetTile); }
void GenerateBodyPartChest_Random(Maze maze) { // Calculate the number of items needed to spawn for this maze int numChests = Formula.CalculateBodyPartChestNum(level.mazeDifficulty); numChests = numChests < level.mazeSetting.bodyParts.Count ? numChests : level.mazeSetting.bodyParts.Count; List <Tile> tileList = MazeUTL.UpdateTileListWithDesiredWallLayout(maze.mazeTileList, WallLayout.C); List <Tile> tiles = GetItemSpawnRandomTiles(numChests, Formula.CalculateItemLeastDistance(LevelManager.instance.mazeDifficulty), new List <Tile>(), tileList, TilesWithItem); Utilities.TryCatchError((tiles.Count < numChests), "Can't find enough tiles to spawn Body Part Chests. Please check the range condition."); List <BodyPart> partList = GetBodyPartList(numChests); for (int i = 0; i < numChests; i++) { TileItem item = tiles[i].SpawnTileItem(level.BodyPartChestPrefab); TilesWithItem.Add(tiles[i]); item.bodyPart = partList[i]; } }
//======================================= // Functions //======================================= public static bool CheckRangeDataCondition(Tile org, Tile target, RangeData rangeData) { if (target == null) { return(false); } // Check target if target meets range requirement if (!MazeUTL.CheckTargetInRange(org, target, rangeData.range)) { return(false); } // If target is org, check excludeOrigin if (org == target) { return(!rangeData.excludeOrigin); } // Check uf target is right on the range when excludeTilesBetweenRange is set if (rangeData.excludeTilesBetweenRange) { if (!MazeUTL.CheckTargetIsRightOnRange(org, target, rangeData.range)) { return(false); } } // Check target is in targetTiles if ((rangeData.targetTiles != null) && (rangeData.targetTiles.Count > 0)) { if (!rangeData.targetTiles.Contains(target)) { return(false); } } return(true); }
List <Tile> GetItemSpawnRandomTiles(int numItems, int range, List <Tile> tileList, List <Tile> tilesLeft, List <Tile> exclusiveTiles) { if (numItems <= 0) { return(tileList); } tilesLeft = MazeUTL.UpdateTileListOutOfRange(tilesLeft, exclusiveTiles, range); Tile tile = MazeUTL.GetRandomTileFromList(tilesLeft); tileList.Add(tile); List <Tile> newExclusiveTiles = new List <Tile>(); foreach (Tile t in exclusiveTiles) { newExclusiveTiles.Add(t); } newExclusiveTiles.Add(tile); numItems--; return(GetItemSpawnRandomTiles(numItems, range, tileList, tilesLeft, newExclusiveTiles)); }
string GetLinearRegionConditions(int linearDir, Tile tile, Maze maze, int height, List <int> wallsShouldntContain) { Utilities.TryCatchError(((linearDir < 0) || (linearDir > 1)), "Input parameter 'linearDir' can only be North or East"); if (wallsShouldntContain.Contains(linearDir)) { wallsShouldntContain.Remove(linearDir); } string region = ""; int startID; int length; if (linearDir == 0) { startID = tile.Z; length = maze.mazeLength; } else { startID = tile.X; length = maze.mazeWidth; } for (int i = startID; i < length; i++) { Tile currTile; bool containWrongWalls = false; // Get current tile based on linear direction if (linearDir == 0) { currTile = maze.mazeTile[tile.X, i]; } else { currTile = maze.mazeTile[i, tile.Z]; } // Check if this tile contains walls we don't want foreach (int wall in wallsShouldntContain) { if (MazeUTL.WallOnDir(currTile, wall)) { containWrongWalls = true; break; } } if (containWrongWalls) { break; } // Pass check, add the tile to region region += MazeUTL.GetTileAddress(currTile.X, currTile.Z); // After adding, check if we can keep going to the next tile if (region.Length == height) { break; } if (MazeUTL.WallOnDir(currTile, linearDir)) { break; } } return(region); }
public void TryMoveToDirTile(int dir) { TryMoveToTile(MazeUTL.GetDirNeighborTile(currentTile, dir)); }
public static int CalculateObjectiveLeastDistance(int mazeDifficulty) { return((int)Mathf.Floor(MazeUTL.GetMazeShortestSide() / 2)); // 10 }