/* * Date: 12/24/2005 * Time: 1:14 AM * * Copyright 2005, Static Boy Productions */ using System; using System.Collections.Generic; using System.Drawing; using Jessie.Utils; namespace Jessie.GameState { public enum jtbvTile { UNEXPLORED, // haven't seen this square yet UNKNOWN, // don't know what's on this square because there's something on top of it UNKNOWN_PASSABLE, // this is a floor/corridor whatever that you can walk on, but can't tell what's there because there's an object on top of it FLOOR, WALL, OPEN_DOOR, BROKEN_DOOR, CLOSED_DOOR, CORRIDOR, DOORWAY, STAIRCASE_UP, STAIRCASE_DOWN, FOUNTAIN, SINK, GRAVE, TREE, UNKNOWN_ALTAR, NEUTRAL_ALTAR, CHAOTIC_ALTAR, LAWFUL_ALTAR, UNALIGNED_ALTAR, UNKNOWN_TRAP, PIT, ARROW_TRAP, BEAR_TRAP, DART_TRAP, MAGIC_TRAP, RUST_TRAP, SQUEAKY_BOARD, LOCKED_DOOR, FALLING_ROCK_TRAP, ANTI_MAGIC_FIELD, FIRE_TRAP, HOLE, TELEPORT_TRAP, SLEEPING_GAS_TRAP, ROLLING_BOULDER_TRAP, TRAP_DOOR, LEVEL_TELEPORTER, WEB, } /// /// Description of jtbvMapSpace. /// public class jtbvMapSpace { public jtbvTile Tile; public jtbvMonster Monster; public bool BreadCrumb; // This is only used for pathfinding. public bool HasItem; public bool IsStore; public List Items; public int SearchStatus; private jtbvGameLevel parent; public jtbvGameLevel Parent { get { return parent; } } public Point Loc; public jtbvMapSpace(jtbvGameLevel level, int x, int y) { parent = level; Loc = new Point(x, y); Items = new List(); SearchStatus = 0; Tile = jtbvTile.UNEXPLORED; Monster = null; } public void UseAppearanceData(char Appearance) { HasItem = false; Monster = null; // Always reset the monster, because they might have moved. switch (Appearance) { case '.': jtbvLog.WriteFile("MovementErrs.log", "Location1"); jtbvLog.WriteFile("MovementErrs.log", "Old tile was " + Tile.ToString() + ", being set to floor"); Tile = jtbvTile.FLOOR; break; case '{': if ((Tile == jtbvTile.UNKNOWN) || (Tile == jtbvTile.UNEXPLORED)) { RequestMoreInfo(); } break; case '-': case '|': RequestMoreInfo(); break; case '#': if ((Tile == jtbvTile.UNKNOWN) || (Tile == jtbvTile.UNEXPLORED)) Tile = jtbvTile.WALL; break; case '_': RequestMoreInfo(); break; case '^': if (!this.IsTrap()) RequestMoreInfo(); break; case '+': RequestMoreInfo(); break; case '>': if (Tile != jtbvTile.STAIRCASE_DOWN) RequestMoreInfo(); // this[cursor] = jtbvMapSquare.STAIRCASE_DOWN; break; case '<': if (Tile != jtbvTile.STAIRCASE_UP) RequestMoreInfo(); // this[cursor] = jtbvMapSquare.STAIRCASE_UP; break; case ' ': if (Tile == jtbvTile.UNKNOWN) Tile = jtbvTile.UNEXPLORED; break; default: RequestMoreInfo(); break; } } public void UseQueryResult(char Symbol, string Description) { jtbvLog.WriteFile("Inquiries.log", "Query result for " + this.Loc.ToString() + " is (" + Symbol.ToString() + ") '" + Description + "'"); HasItem = false; Monster = null; // Always reset the monster, because they might have moved. switch (Description) { case "doorway": Tile = jtbvTile.OPEN_DOOR; break; case "closed door": Tile = jtbvTile.CLOSED_DOOR; break; case "dark part of a room": Tile = jtbvTile.UNEXPLORED; break; case "floor of a room": jtbvLog.WriteFile("MovementErrs.log", "Location2"); jtbvLog.WriteFile("MovementErrs.log", "Former tile was " + Tile.ToString()); Tile = jtbvTile.FLOOR; jtbvLog.WriteFile("MovementErrs.log", "Tile is now " + Tile.ToString()); break; case "lit corridor": case "corridor": jtbvLog.WriteFile("MovementErrs.log", "Location4"); jtbvLog.WriteFile("MovementErrs.log", "Former tile was " + Tile.ToString()); Tile = jtbvTile.CORRIDOR; jtbvLog.WriteFile("MovementErrs.log", "Tile is now " + Tile.ToString()); break; case "wall": Tile = jtbvTile.WALL; break; case "broken door": Tile = jtbvTile.BROKEN_DOOR; break; case "open door": Tile = jtbvTile.OPEN_DOOR; break; case "staircase up": Tile = jtbvTile.STAIRCASE_UP; break; case "staircase down": Tile = jtbvTile.STAIRCASE_DOWN; break; case "lawful altar": Tile = jtbvTile.LAWFUL_ALTAR; break; case "neutral altar": Tile = jtbvTile.NEUTRAL_ALTAR; break; case "chaotic altar": Tile = jtbvTile.CHAOTIC_ALTAR; break; default: // In this case, we don't think it's a dungeon feature, so it must be a monster or an item. if (Tile == jtbvTile.UNEXPLORED) { Tile = jtbvTile.UNKNOWN; } Monster = jtbvMonster.GetMonster(Symbol, Description); if (Monster == null) { this.HasItem = true; //Console.WriteLine("Found an item at loc " + this.Loc.ToString()); //jtbvItem item = jtbvItem.GetItem(sym, desc); } else { jtbvLog.WriteFile("FoundMonsters.log", Monster.Species); //Console.WriteLine("Found monster " + Monster.Species + " at loc " + this.Loc.ToString()); } break; } } private void RequestMoreInfo() { Parent.RequestMoreInfo(this.Loc); } public string GetDrawTile() { string retVal = "~"; // An unknown character switch (Tile) { case jtbvTile.UNEXPLORED: retVal = " "; break; case jtbvTile.FLOOR: retVal = "."; break; case jtbvTile.WALL: retVal = "W"; break; case jtbvTile.OPEN_DOOR: retVal = "d"; break; case jtbvTile.BROKEN_DOOR: retVal = "b"; break; case jtbvTile.CLOSED_DOOR: retVal = "D"; break; case jtbvTile.LOCKED_DOOR: retVal = "D"; break; case jtbvTile.CORRIDOR: retVal = "c"; break; case jtbvTile.DOORWAY: retVal = "w"; break; case jtbvTile.STAIRCASE_UP: retVal = "<"; break; case jtbvTile.STAIRCASE_DOWN: retVal = ">"; break; case jtbvTile.UNKNOWN: retVal = ";"; break; case jtbvTile.UNKNOWN_PASSABLE: retVal = ":"; break; case jtbvTile.FOUNTAIN: retVal = "{"; break; case jtbvTile.SINK: retVal = "#"; break; case jtbvTile.GRAVE: retVal = "("; break; case jtbvTile.UNKNOWN_ALTAR: case jtbvTile.NEUTRAL_ALTAR: case jtbvTile.CHAOTIC_ALTAR: case jtbvTile.LAWFUL_ALTAR: case jtbvTile.UNALIGNED_ALTAR: retVal = "_"; break; case jtbvTile.PIT: case jtbvTile.UNKNOWN_TRAP: case jtbvTile.ARROW_TRAP: case jtbvTile.BEAR_TRAP: case jtbvTile.DART_TRAP: case jtbvTile.MAGIC_TRAP: case jtbvTile.RUST_TRAP: case jtbvTile.SQUEAKY_BOARD: case jtbvTile.FALLING_ROCK_TRAP: case jtbvTile.ANTI_MAGIC_FIELD: case jtbvTile.FIRE_TRAP: case jtbvTile.HOLE: case jtbvTile.TRAP_DOOR: case jtbvTile.TELEPORT_TRAP: case jtbvTile.SLEEPING_GAS_TRAP: case jtbvTile.ROLLING_BOULDER_TRAP: case jtbvTile.LEVEL_TELEPORTER: case jtbvTile.WEB: retVal = "^"; break; case jtbvTile.TREE: retVal = "#"; break; default: retVal = "~"; break; } return retVal; } // Include unknown here. We might later decide that this particular unknown // isn't passable after all, if we try moving onto it but it doesn't work. public bool IsPassable() { bool retVal = false; retVal = (this.GetTravelCost() < 1000); // switch (Tile) // { // case jtbvTile.LOCKED_DOOR: // case jtbvTile.CLOSED_DOOR: // case jtbvTile.OPEN_DOOR: // case jtbvTile.FLOOR: // case jtbvTile.CORRIDOR: // case jtbvTile.DOORWAY: // case jtbvTile.STAIRCASE_UP: // case jtbvTile.STAIRCASE_DOWN: // case jtbvTile.UNKNOWN: // case jtbvTile.UNKNOWN_PASSABLE: // case jtbvTile.FOUNTAIN: // case jtbvTile.SINK: // case jtbvTile.GRAVE: // case jtbvTile.PIT: // case jtbvTile.ARROW_TRAP: // case jtbvTile.NEUTRAL_ALTAR: // case jtbvTile.CHAOTIC_ALTAR: // case jtbvTile.LAWFUL_ALTAR: // case jtbvTile.UNALIGNED_ALTAR: // case jtbvTile.BEAR_TRAP: // case jtbvTile.BROKEN_DOOR: // case jtbvTile.DART_TRAP: // case jtbvTile.MAGIC_TRAP: // case jtbvTile.RUST_TRAP: // case jtbvTile.SQUEAKY_BOARD: // case jtbvTile.FALLING_ROCK_TRAP: // case jtbvTile.ANTI_MAGIC_FIELD: // case jtbvTile.FIRE_TRAP: // case jtbvTile.HOLE: // case jtbvTile.TELEPORT_TRAP: // case jtbvTile.SLEEPING_GAS_TRAP: // case jtbvTile.ROLLING_BOULDER_TRAP: // case jtbvTile.TRAP_DOOR: // case jtbvTile.LEVEL_TELEPORTER: // case jtbvTile.WEB: // case jtbvTile.UNKNOWN_ALTAR: // case jtbvTile.UNKNOWN_TRAP: // retVal = true; // break; // default: // retVal = false; // break; // } if (Monster != null) retVal = false; return retVal; } public bool IsTrap() { bool retVal = false; switch (Tile) { case jtbvTile.PIT: case jtbvTile.UNKNOWN_TRAP: case jtbvTile.ARROW_TRAP: case jtbvTile.BEAR_TRAP: case jtbvTile.DART_TRAP: case jtbvTile.MAGIC_TRAP: case jtbvTile.RUST_TRAP: case jtbvTile.SQUEAKY_BOARD: case jtbvTile.FALLING_ROCK_TRAP: case jtbvTile.ANTI_MAGIC_FIELD: case jtbvTile.FIRE_TRAP: case jtbvTile.HOLE: case jtbvTile.TRAP_DOOR: case jtbvTile.TELEPORT_TRAP: case jtbvTile.SLEEPING_GAS_TRAP: case jtbvTile.ROLLING_BOULDER_TRAP: case jtbvTile.LEVEL_TELEPORTER: case jtbvTile.WEB: retVal = true; break; } return retVal; } public bool IsAltar() { bool retVal = false; switch (Tile) { case jtbvTile.UNALIGNED_ALTAR: case jtbvTile.LAWFUL_ALTAR: case jtbvTile.NEUTRAL_ALTAR: case jtbvTile.CHAOTIC_ALTAR: retVal = true; break; } return retVal; } public int GetTravelCost() { int retVal = 1000; // Default high value switch (Tile) { case jtbvTile.UNEXPLORED: retVal = 1000; break; case jtbvTile.FLOOR: retVal = 1; break; case jtbvTile.OPEN_DOOR: retVal = 1; break; case jtbvTile.BROKEN_DOOR: retVal = 1; break; case jtbvTile.CORRIDOR: retVal = 1; break; case jtbvTile.DOORWAY: retVal = 1; break; case jtbvTile.STAIRCASE_UP: retVal = 1; break; case jtbvTile.STAIRCASE_DOWN: retVal = 1; break; case jtbvTile.FOUNTAIN: retVal = 1; break; case jtbvTile.SINK: retVal = 1; break; case jtbvTile.GRAVE: retVal = 1; break; case jtbvTile.NEUTRAL_ALTAR: retVal = 1; break; case jtbvTile.CHAOTIC_ALTAR: retVal = 1; break; case jtbvTile.LAWFUL_ALTAR: retVal = 1; break; case jtbvTile.UNALIGNED_ALTAR: retVal = 1; break; case jtbvTile.UNKNOWN: retVal = 2; break; case jtbvTile.UNKNOWN_PASSABLE: retVal = 2; break; case jtbvTile.CLOSED_DOOR: retVal = 3; break; case jtbvTile.SQUEAKY_BOARD: retVal = 4; break; case jtbvTile.ANTI_MAGIC_FIELD: retVal = 5; break; case jtbvTile.FALLING_ROCK_TRAP: retVal = 6; break; case jtbvTile.WEB: retVal = 6; break; case jtbvTile.LOCKED_DOOR: retVal = 7; break; case jtbvTile.ROLLING_BOULDER_TRAP: retVal = 8; break; case jtbvTile.ARROW_TRAP: retVal = 10; break; case jtbvTile.DART_TRAP: retVal = 10; break; case jtbvTile.FIRE_TRAP: retVal = 12; break; case jtbvTile.MAGIC_TRAP: retVal = 13; break; case jtbvTile.PIT: retVal = 15; break; case jtbvTile.BEAR_TRAP: retVal = 15; break; case jtbvTile.RUST_TRAP: retVal = 20; break; case jtbvTile.SLEEPING_GAS_TRAP: retVal = 40; break; case jtbvTile.TELEPORT_TRAP: retVal = 80; break; case jtbvTile.HOLE: retVal = 100; break; case jtbvTile.TRAP_DOOR: retVal = 100; break; case jtbvTile.LEVEL_TELEPORTER: retVal = 500; break; case jtbvTile.WALL: retVal = 1000; break; default: retVal = 1000; break; } return retVal; } public List AdjacentSquares { get { List tmp = new List(); // First pass adds the coaligned ones for (int x = Loc.X-1; x <= Loc.X+1; x++) { for (int y = Loc.Y-1; y <= Loc.Y+1; y++) { if (!((x == Loc.X) && (y == Loc.Y))) if ((x >= 0) && (y >= 0) && (x < jtbvGameLevel.MAP_WIDTH) && (y < jtbvGameLevel.MAP_HEIGHT)) if (jtbvUtils.PointsAreSquared(this, Parent[x,y])) tmp.Add(Parent[x,y]); } } // Second pass adds the diagonals for (int x = Loc.X-1; x <= Loc.X+1; x++) { for (int y = Loc.Y-1; y <= Loc.Y+1; y++) { if (!((x == Loc.X) && (y == Loc.Y))) if ((x >= 0) && (y >= 0) && (x < jtbvGameLevel.MAP_WIDTH) && (y < jtbvGameLevel.MAP_HEIGHT)) if (!jtbvUtils.PointsAreSquared(this, Parent[x,y])) tmp.Add(Parent[x,y]); } } return tmp; } } public int Danger { get{ int retVal = 0; if (this.Monster != null) retVal = this.Monster.Danger; return retVal; } } public bool IsClosedDoor { get{ bool retVal = false; if ((this.Tile == jtbvTile.CLOSED_DOOR) || (this.Tile == jtbvTile.LOCKED_DOOR)) retVal = true; return retVal; } } public bool IsDeadEnd { get{ bool retVal = false; int passableCnt = 0; foreach (jtbvMapSpace test in this.AdjacentSquares) { if (test.IsPassable()) passableCnt++; } if (passableCnt <= 1) retVal = true; return retVal; } } public void SetSearched() { this.SearchStatus++; jtbvLog.WriteFile("Explore.log", "Setting search status for " + this.Loc.ToString() + " to " + this.SearchStatus.ToString()); foreach (jtbvMapSpace space in this.AdjacentSquares) { space.SearchStatus++; jtbvLog.WriteFile("Explore.log", "Setting search status for " + space.Loc.ToString() + " to " + space.SearchStatus.ToString()); } } public int LowestAdjacentSearchValue() { int lowest = this.SearchStatus; foreach (jtbvMapSpace tmp in this.AdjacentSquares) { if (tmp.SearchStatus < lowest) lowest = tmp.SearchStatus; } return lowest; } } }