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