private static void ParseTowns(Map map, FileLoader loader, FileLoaderNode otbNode) { var nodeTown = otbNode.Child; while (nodeTown != null) { PropertyReader props; if (!loader.GetProps(nodeTown, out props)) throw new Exception("Could not read town data."); uint townid = props.ReadUInt32(); string townName = props.GetString(); ushort townTempleX = props.ReadUInt16(); ushort townTempleY = props.ReadUInt16(); byte townTempleZ = props.ReadByte(); var town = new Town(townid, townName, new Position(townTempleX, townTempleY, townTempleZ)); map.AddTown(town); nodeTown = nodeTown.Next; } }
public void Save(Map map, string fileName) { throw new NotImplementedException(); }
private static void ParseTileArea(Map map, FileLoader loader, FileLoaderNode otbNode) { PropertyReader props; if (!loader.GetProps(otbNode, out props)) throw new Exception("Invalid map node."); int baseX = props.ReadUInt16(); int baseY = props.ReadUInt16(); int baseZ = props.ReadByte(); var nodeTile = otbNode.Child; while (nodeTile != null) { if (nodeTile.Type == (long)OtbMapNodeType.Tile || nodeTile.Type == (long)OtbMapNodeType.HouseTile) { loader.GetProps(nodeTile, out props); int tileX = baseX + props.ReadByte(); int tileY = baseY + props.ReadByte(); int tileZ = baseZ; bool isHouseTile = false; //House* house = NULL; //Tile tile = null; //Item groundItem = null; //TileFlags tileflags = TileFlags.None; //var tile = new Tile(tileX, tileY, tileZ); // TODO: houses if (nodeTile.Type == (long)OtbMapNodeType.HouseTile) { uint houseId = props.ReadUInt32(); } while (props.PeekChar() != -1) { byte attribute = props.ReadByte(); switch ((OtbmAttribute)attribute) { case OtbmAttribute.TileFlags: { var flags = /*(TileFlags)*/props.ReadUInt32(); //if ((flags & TileFlags.ProtectionZone) == TileFlags.ProtectionZone) // tileflags |= TileFlags.ProtectionZone; //else if ((flags & TileFlags.NoPvpZone) == TileFlags.NoPvpZone) // tileflags |= TileFlags.NoPvpZone; //else if ((flags & TileFlags.PvpZone) == TileFlags.PvpZone) // tileflags |= TileFlags.PvpZone; //if ((flags & TileFlags.NoLogout) == TileFlags.NoLogout) // tileflags |= TileFlags.NoLogout; //if ((flags & TileFlags.Refresh) == TileFlags.Refresh) // tileflags |= TileFlags.Refresh; break; } case OtbmAttribute.Item: { ushort itemId = props.ReadUInt16(); //Item item = Item.Create(itemId); //if (item == null) //{ // Log.Error("Failed to create item."); // return false; //} //if (tile != null) //{ // tile.InternalAddThing(item); // item.StartDecaying(); //} //else if (item.IsGround) // groundItem = item; //else //{ // tile = CreateTile(groundItem, item, tileX, tileY, tileZ); // tile.InternalAddThing(item); // item.StartDecaying(); //} break; } default: throw new Exception(string.Format("{0} Unknown tile attribute.", new Position(tileX, tileY, tileZ))); } } var nodeItem = nodeTile.Child; while (nodeItem != null) { if (nodeItem.Type == (long)OtbMapNodeType.Item) { loader.GetProps(nodeItem, out props); ushort itemId = props.ReadUInt16(); //// TODO: subclass item, different deserializations //// for different types //Item item = Item.Create(itemId); //if (tile != null) //{ // tile.InternalAddThing(item); // item.StartDecaying(); //} //else if (item.IsGround) // groundItem = item; //else //{ // // !tile // tile = CreateTile(groundItem, item, tileX, tileY, tileZ); // tile.InternalAddThing(item); // item.StartDecaying(); //} } else { throw new Exception(string.Format("{0} Unknown node type.", new Position(tileX, tileY, tileZ))); } nodeItem = nodeItem.Next; } //if (tile == null) // tile = CreateTile(groundItem, null, tileX, tileY, tileZ); //tile.SetFlag(tileflags); //SetTile(tileX, tileY, tileZ, tile); } nodeTile = nodeTile.Next; } }
public void Load(Map map, string fileName) { if (!File.Exists(fileName)) throw new Exception(string.Format("File not found {0}.", fileName)); var loader = new FileLoader(); loader.OpenFile(fileName); var node = loader.GetRootNode(); PropertyReader props; if (!loader.GetProps(node, out props)) throw new Exception("Could not read root property."); props.ReadByte(); // junk? var version = props.ReadUInt32(); var width = props.ReadUInt16(); var height = props.ReadUInt16(); var majorVersionItems = props.ReadUInt32(); var minorVersionItems = props.ReadUInt32(); if (version <= 0) { //In otbm version 1 the count variable after splashes/fluidcontainers and stackables //are saved as attributes instead, this solves alot of problems with items //that is changed (stackable/charges/fluidcontainer/splash) during an update. throw new Exception("This map needs to be upgraded by using the latest map editor version to be able to load correctly."); } if (version > 2) throw new Exception("Unknown OTBM version detected, please update your server."); if (majorVersionItems < 3) throw new Exception("This map needs to be upgraded by using the latest map editor version to be able to load correctly."); //if (MajorVersionItems > ItemInfo.MajorVersion) //{ // Log.Error("The map was saved with a different items.otb version, an upgraded items.otb is required."); // return false; //} if (minorVersionItems < (uint)ClientVersion.ClientVersion810) throw new Exception("This map needs to be updated."); //if (MinorVersionItems > ItemInfo.MinorVersion) // Log.Warn("This map needs an updated items.otb."); //if (MinorVersionItems == (uint)ClientVersion.ClientVersion854Bad) // Log.Warn("This map needs uses an incorrect version of items.otb."); Logger.Info(string.Format("Map size: {0}x{1}", width, height)); node = node.Child; if ((OtbMapNodeType)node.Type != OtbMapNodeType.MapData) throw new Exception("Could not read data node."); if (!loader.GetProps(node, out props)) throw new Exception("Could not read map data attributes."); while (props.PeekChar() != -1) { byte attribute = props.ReadByte(); switch ((OtbmAttribute)attribute) { case OtbmAttribute.Description: var description = props.GetString(); Logger.Info(string.Format("Map Description: {0}", description)); break; case OtbmAttribute.ExtSpawnFile: var spawnFile = props.GetString(); break; case OtbmAttribute.ExtHouseFile: var houseFile = props.GetString(); break; default: throw new Exception("Unknown header node."); } } var nodeMapData = node.Child; while (nodeMapData != null) { switch ((OtbMapNodeType)nodeMapData.Type) { case OtbMapNodeType.TileArea: ParseTileArea(map, loader, nodeMapData); break; case OtbMapNodeType.Towns: ParseTowns(map, loader, nodeMapData); break; } nodeMapData = nodeMapData.Next; } }