/* * BIG TODO: REWRITE THIS PARSER - MAKE IT MODULAR SO ITS EASY TO ADD NEW STUFF... * ELSE THIS IS GONNA BE HUGE... */ /// <summary> /// Parses a byte stream into a Map, reading from as a TILED .tmx in csv format /// </summary> public static ServerMap Parse(Stream mapStream) { ServerMap map = new ServerMap(); using (XmlReader reader = XmlReader.Create(mapStream)) { var doc = XDocument.Load(reader); var xMap = doc.Element("map"); // Map Tilesets foreach (var tileset in xMap.Elements("tileset")) { var imgSource = tileset.Element("image").Attribute("source").Value; var tilesetName = imgSource.Split('/').Last(); byte[] image = AssetLoader.LoadedAssets.GetAsset(AssetType.TILESET, tilesetName).ImageData; map.Tilesets.Add(tilesetName, image); } // Map Objects foreach (var xObjectGroup in xMap.Elements("objectgroup")) { var layerType = xObjectGroup.Attribute("name").Value; if (layerType == LAYER_SPAWNERS) { ParseSpawner(xObjectGroup, map); } } // Map Tiles ParseTiles(xMap, map); } return(map); }
private static void ParseTiles(XElement xMap, ServerMap map) { foreach (var xLayer in xMap.Elements("layer")) { var layerType = xLayer.Attribute("name").Value; foreach (var xChunk in xLayer.Element("data").Elements("chunk")) { var csvData = Regex.Replace((string)xChunk.Value, @"\t|\n|\r", ""); var chunkX = Int16.Parse(xChunk.Attribute("x").Value) / Chunk.SIZE; var chunkY = Int16.Parse(xChunk.Attribute("y").Value) / Chunk.SIZE; if (layerType == LAYER_FLOOR) { var chunk = new ServerChunk() { x = chunkX, y = chunkY }; var tileArray = csvData.Split(','); for (int y = 0; y < Chunk.SIZE; y++) { for (int x = 0; x < Chunk.SIZE; x++) { var tile = Int16.Parse(tileArray[x + y * Chunk.SIZE]); chunk.SetTile(x, y, tile); } } map.AddChunk(chunk); } } } }
private static void ParseSpawner(XElement xObjectGroup, ServerMap map) { foreach (var xObject in xObjectGroup.Elements("object")) { var x = Int32.Parse(xObject.Attribute("x").Value) / GameCfg.TILE_SIZE_PIXELS; var y = Int32.Parse(xObject.Attribute("y").Value) / GameCfg.TILE_SIZE_PIXELS; var w = Int32.Parse(xObject.Attribute("width").Value) / GameCfg.TILE_SIZE_PIXELS; var h = Int32.Parse(xObject.Attribute("height").Value) / GameCfg.TILE_SIZE_PIXELS; var maxX = x + w - 1; var maxY = y + h - 1; var spawnerName = xObject.Attribute("name")?.Value; var spawner = new MonsterSpawner() { Min = new Position(x, y), Max = new Position(maxX, maxY) }; var xProperties = xObject.Element("properties"); var xMonster = xProperties.Descendants("property") .FirstOrDefault(el => el.Attribute("name")?.Value == SPAWNER_PROPERTY_MONSTER); var xQtd = xProperties.Descendants("property") .FirstOrDefault(el => el.Attribute("name")?.Value == SPAWNER_PROPERTY_QTD); var xTime = xProperties.Descendants("property") .FirstOrDefault(el => el.Attribute("name")?.Value == SPAWNER_PROPERTY_TIMER); if (xTime != null) { spawner.SpawnTimerSeconds = Int32.Parse(xTime.Attribute("value").Value); } var monsterType = xMonster.Attribute("value").Value.FirstCharToUpper(); var monsterQtd = Int32.Parse(xQtd.Attribute("value").Value); var monsterClass = Type.GetType($"ServerCore.Game.Monsters.{monsterType}"); if (monsterClass == null) { throw new InvalidDataException($"Invalid Monster {monsterType} in spawner {spawnerName}"); } spawner.SpawnerMobs.Add(new SpawnerMob() { Amount = monsterQtd, MonsterClassType = monsterClass }); map.Spawners.Add(spawner); } }
private static void ParseTiles(XElement xMap, ServerMap map) { foreach (var xLayer in xMap.Elements("layer")) { var layerType = xLayer.Attribute("name").Value; foreach (var xChunk in xLayer.Element("data").Elements("chunk")) { var csvData = Regex.Replace((string)xChunk.Value, @"\t|\n|\r", ""); var chunkX = Int16.Parse(xChunk.Attribute("x").Value) / Chunk.SIZE; var chunkY = Int16.Parse(xChunk.Attribute("y").Value) / Chunk.SIZE; if (layerType == LAYER_FLOOR) { var chunk = new ServerChunk() { x = chunkX, y = chunkY }; var tileArray = csvData.Split(','); for (int y = 0; y < Chunk.SIZE; y++) { for (int x = 0; x < Chunk.SIZE; x++) { var tilePositionX = chunk.x * Chunk.SIZE + x; var tilePositionY = chunk.y * Chunk.SIZE + y; var tileId = Int16.Parse(tileArray[x + y * Chunk.SIZE]); chunk.Tiles[x, y] = new MapTile(new Position(tilePositionX, tilePositionY), tileId); } } chunk.BuildChunkPacketData(); map.AddChunk(chunk); } } } }