using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TalkingIsAFreeAction { public class Area { public class TileDefinition { public string symbol = "?"; public bool solid = false; public string background = "notile"; public string foreground = ""; public string onaction = ""; public string ontouch = ""; public string special = ""; public string carryid = ""; public string parameter = ""; } private enum ReadingMode { None, Settings, Area, Tile, Event } public string[] definition = null; public string name = "area"; public int width = 0; public int height = 0; public Tile[,] tiles; public List objects = new List(); public Dictionary areaEvents = new Dictionary(); public Dictionary tileDefs = new Dictionary(); public bool timerOn = true; public string music = "menu"; public Area(string[] definition) { Initialize(definition); } public void Initialize(string[] definition) { this.definition = definition; List areaDefinition = new List(); List tileDefinitions = new List(); timerOn = true; ReadingMode currentMode = ReadingMode.None; TileDefinition currentTile = new TileDefinition(); string eventName = ""; List eventSoFar = new List(); int currentLine = 0; while (currentLine < definition.Length) { string line = definition[currentLine]; //Remove leading spaces while (line.StartsWith(" ")) line = line.Substring(1); if (!line.StartsWith("//")) { switch (currentMode) { case ReadingMode.Settings: if (line.StartsWith("[/settings]")) { this.tiles = new Tile[width, height]; currentMode = ReadingMode.None; } else { string key = Util.ReadStringBeforeEquals(line); switch (key) { case "width": this.width = Util.ReadIntAfterEquals(line); break; case "height": this.height = Util.ReadIntAfterEquals(line); break; case "name": this.name = Util.ReadStringAfterEquals(line); break; case "timer": if (Util.ReadStringAfterEquals(line) == "off") timerOn = false; break; case "music": this.music = Util.ReadStringAfterEquals(line); break; } } break; case ReadingMode.Area: if (line.StartsWith("[/area]")) currentMode = ReadingMode.None; else areaDefinition.Add(line); break; case ReadingMode.Tile: if (line.StartsWith("[/tile]")) { tileDefinitions.Add(currentTile); currentMode = ReadingMode.None; } else { string key = Util.ReadStringBeforeEquals(line); switch (key) { case "symbol": currentTile.symbol = Util.ReadStringAfterEquals(line); break; case "solid": if (Util.ReadStringAfterEquals(line) == "true") currentTile.solid = true; break; case "background": currentTile.background = Util.ReadStringAfterEquals(line); break; case "foreground": currentTile.foreground = Util.ReadStringAfterEquals(line); break; case "onaction": currentTile.onaction = Util.ReadStringAfterEquals(line); break; case "ontouch": currentTile.ontouch = Util.ReadStringAfterEquals(line); break; case "special": currentTile.special = Util.ReadStringAfterEquals(line); break; case "carryid": currentTile.carryid = Util.ReadStringAfterEquals(line); break; case "parameter": currentTile.parameter = Util.ReadStringAfterEquals(line); break; } } break; case ReadingMode.Event: if (line.StartsWith("[/event]")) { currentMode = ReadingMode.None; areaEvents.Add(eventName, eventSoFar.ToArray()); } else { if (line.StartsWith("START")) { currentLine++; line = definition[currentLine]; while (!line.StartsWith("END")) { eventSoFar.Add(line); currentLine++; line = definition[currentLine]; } } else { string key = Util.ReadStringBeforeEquals(line); switch (key) { case "name": eventName = Util.ReadStringAfterEquals(line); break; } } } break; case ReadingMode.None: if (line.StartsWith("[settings]")) currentMode = ReadingMode.Settings; if (line.StartsWith("[area]")) currentMode = ReadingMode.Area; if (line.StartsWith("[tile]")) { currentMode = ReadingMode.Tile; currentTile = new TileDefinition(); } if (line.StartsWith("[event]")) { currentMode = ReadingMode.Event; eventSoFar = new List(); eventName = ""; } break; } } currentLine++; } //Definition read! Construct area! //...but first, make an index of tile definitions tileDefs = new Dictionary(); for (int i = 0; i < tileDefinitions.Count; i++) { tileDefs.Add(tileDefinitions[i].symbol, tileDefinitions[i]); } //Okay, go! for (int iy = 0; iy < height; iy++) { for (int ix = 0; ix < width; ix++) { string thisTile = areaDefinition[iy].Substring(ix, 1); PlaceTile(thisTile, ix, iy); } } } public void PlaceTile(string symbol, int x, int y) { if (tileDefs.ContainsKey(symbol)) { TileDefinition toPut = tileDefs[symbol]; Tile tile = new Tile(toPut.solid, x, y, toPut.background); tiles[x, y] = tile; if (tile.solid) Physics.passivePhysicsBodies.Add(tile); if (toPut.foreground != "") { bool canSpawn = true; if (Main.carryingObject != null) { if (Main.carryingObject.carryid == toPut.carryid) canSpawn = false; } if (canSpawn) { objects.Add(new Object(toPut.symbol, toPut.foreground, x * Tile.TILE_SIZE_X, y * Tile.TILE_SIZE_Y, toPut.onaction, toPut.ontouch, toPut.special, toPut.carryid, toPut.parameter)); } } } } public void RemoveTile(int x, int y) { VBXSE.SpriteEngine.EraseGObject(tiles[x, y].sprite); if (Physics.passivePhysicsBodies.Contains(tiles[x, y])) Physics.passivePhysicsBodies.Remove(tiles[x, y]); } public void DestroyArea() { for (int iy = 0; iy < height; iy++) { for (int ix = 0; ix < width; ix++) { RemoveTile(ix, iy); } } areaEvents.Clear(); tileDefs.Clear(); for (int i = 0; i < objects.Count; i++) VBXSE.SpriteEngine.EraseGObject(objects[i].sprite); objects.Clear(); } public void Refresh() { DestroyArea(); Initialize(definition); } } }