public virtual void Deserialize(FileReader fileReader, BinaryNode itemNode, PropertyReader reader) { Deserialize(reader); }
private void ParseTileArea(FileReader reader, BinaryNode otbNode, bool replaceTiles, ISet <ulong> tileLocations) { PropertyReader props = reader.GetPropertyReader(otbNode); int baseX = props.ReadUInt16(); int baseY = props.ReadUInt16(); int baseZ = props.ReadByte(); BinaryNode nodeTile = otbNode.Child; while (nodeTile != null) { if (nodeTile.Type == (long)OtMapNodeTypes.TILE || nodeTile.Type == (long)OtMapNodeTypes.HOUSETILE) { props = reader.GetPropertyReader(nodeTile); var tileLocation = new Position(baseX + props.ReadByte(), baseY + props.ReadByte(), baseZ); var tile = new Tile(tileLocation); if (nodeTile.Type == (long)OtMapNodeTypes.HOUSETILE) { tile.HouseId = props.ReadUInt32(); } while (props.PeekChar() != -1) { byte attribute = props.ReadByte(); switch ((OtMapAttribute)attribute) { case OtMapAttribute.TILE_FLAGS: { tile.mapFlags = props.ReadUInt32(); break; } case OtMapAttribute.ITEM: { ushort itemId = props.ReadUInt16(); var itemType = Items.items[itemId]; if (itemType == null) { throw new Exception("Unkonw item type " + itemId + " in position " + tileLocation + "."); } var item = Item.Create(itemType); tile.addItem(item); break; } default: throw new Exception(string.Format("{0} Unknown tile attribute.", tileLocation)); } } BinaryNode nodeItem = nodeTile.Child; while (nodeItem != null) { if (nodeItem.Type == (long)OtMapNodeTypes.ITEM) { props = reader.GetPropertyReader(nodeItem); ushort itemId = props.ReadUInt16(); var itemType = Items.items[itemId]; if (itemType == null) { throw new Exception("Unkonw item type " + itemId + " in position " + tileLocation + "."); } var item = Item.Create(itemType); item.Deserialize(reader, nodeItem, props); tile.addItem(item); } else { throw new Exception(string.Format("{0} Unknown node type.", tileLocation)); } nodeItem = nodeItem.Next; } // adicionar o tile aqui. setTile(tile.Position, tile, true); } nodeTile = nodeTile.Next; } }
private void LoadOtbm() { if (!File.Exists(FileName)) { throw new Exception(string.Format("File not found {0}.", FileName)); } // FileName = fileName; MapName = Path.GetFileName(FileName); var tileLocations = new HashSet <ulong>(); using (var reader = new FileReader(FileName)) { BinaryNode node = reader.GetRootNode(); PropertyReader props = reader.GetPropertyReader(node); props.ReadByte(); // junk? version = props.ReadUInt32(); Width = props.ReadUInt16(); Height = props.ReadUInt16(); majorVersionItems = props.ReadUInt32(); minorVersionItems = props.ReadUInt32(); if (minorVersionItems != 40) { if (Settings.GetBoolean(Key.BLOCKING_VERSION)) { MessageBox.Show("O mapa não esta na versão 9.6. favor converter o mesmo para 9.6 no RME"); ReadOnly = true; this.FileName = ""; this.MapName = ""; Generic.Abort(); } } 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."); } Items = Global.items; if (version > 3) { throw new Exception("Unknown OTBM version detected."); } 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 > Items.MajorVersion) { throw new Exception("The map was saved with a different items.otb version, an upgraded items.otb is required."); } if (minorVersionItems > Items.MinorVersion) { //Trace.WriteLine("This map needs an updated items.otb."); } node = node.Child; reader.clearRootNode(); if ((OtMapNodeTypes)node.Type != OtMapNodeTypes.MAP_DATA) { throw new Exception("Could not read data node."); } props = reader.GetPropertyReader(node); while (props.PeekChar() != -1) { byte attribute = props.ReadByte(); switch ((OtMapAttribute)attribute) { case OtMapAttribute.DESCRIPTION: var description = props.GetString(); //Descriptions.Add(description); break; case OtMapAttribute.EXT_SPAWN_FILE: spawnFile = props.GetString(); break; case OtMapAttribute.EXT_HOUSE_FILE: houseFile = props.GetString(); break; default: throw new Exception("Unknown header node."); } } BinaryNode nodeMapData = node.Child; while (nodeMapData != null) { switch ((OtMapNodeTypes)nodeMapData.Type) { case OtMapNodeTypes.TILE_AREA: ParseTileArea(reader, nodeMapData, replaceTiles, tileLocations); break; case OtMapNodeTypes.TOWNS: ParseTowns(reader, nodeMapData); break; } nodeMapData = nodeMapData.Next; } GC.Collect(); GC.WaitForPendingFinalizers(); } //LoadSpawn(Path.Combine(Path.GetDirectoryName(fileName), spawnFile), tileLocations); }
private bool ParseNode(BinaryNode node) { // qtVezes++; var currentNode = node; int val; while (true) { // read node type val = fileStream.ReadByte(); if (val != -1) { currentNode.Type = val; var setPropSize = false; while (true) { // search child and next node val = fileStream.ReadByte(); if (val == BinaryNode.NODE_START) { var childNode = new BinaryNode { Start = fileStream.Position }; setPropSize = true; currentNode.PropsSize = fileStream.Position - currentNode.Start - 2; currentNode.Child = childNode; if (!ParseNode(childNode)) { return(false); } } else if (val == BinaryNode.NODE_END) { if (!setPropSize) { currentNode.PropsSize = fileStream.Position - currentNode.Start - 2; } val = fileStream.ReadByte(); if (val != -1) { if (val == BinaryNode.NODE_START) { // start next node var nextNode = new BinaryNode { Start = fileStream.Position }; currentNode.Next = nextNode; currentNode = nextNode; break; } if (val == BinaryNode.NODE_END) { // up 1 level and move 1 position back // safeTell(pos) && safeSeek(pos) fileStream.Seek(-1, SeekOrigin.Current); return(true); } // bad format return(false); } // end of file? return(true); } else if (val == BinaryNode.ESCAPE) { fileStream.ReadByte(); } } } else { return(false); } } }
public void clearRootNode() { root = null; }
private bool LoadFromOtbVer3(BinaryNode node, FileReader reader) { PropertyReader props = null; while (node != null) { props = reader.GetPropertyReader(node); ItemType item = new ItemType(); byte itemGroup = (byte)node.Type; switch ((OtbItemGroup)itemGroup) { case OtbItemGroup.NONE: item.Group = ItemGroup.None; break; case OtbItemGroup.GROUND: item.Group = ItemGroup.Ground; break; case OtbItemGroup.SPLASH: item.Group = ItemGroup.Splash; break; case OtbItemGroup.FLUID: item.Group = ItemGroup.FluidContainer; break; case OtbItemGroup.CONTAINER: item.Group = ItemGroup.Container; break; case OtbItemGroup.DEPRECATED: item.Group = ItemGroup.Deprecated; break; default: Messages.AddWarning("Unknown item group declaration"); break; } OtbItemFlags flags = (OtbItemFlags)props.ReadUInt32(); item.BlockObject = ((flags & OtbItemFlags.BLOCK_SOLID) == OtbItemFlags.BLOCK_SOLID); item.BlockProjectile = ((flags & OtbItemFlags.BLOCK_PROJECTILE) == OtbItemFlags.BLOCK_PROJECTILE); item.BlockPathFind = ((flags & OtbItemFlags.BLOCK_PATHFIND) == OtbItemFlags.BLOCK_PATHFIND); item.IsPickupable = ((flags & OtbItemFlags.PICKUPABLE) == OtbItemFlags.PICKUPABLE); item.IsMoveable = ((flags & OtbItemFlags.MOVEABLE) == OtbItemFlags.MOVEABLE); item.IsStackable = ((flags & OtbItemFlags.STACKABLE) == OtbItemFlags.STACKABLE); item.FloorChangeDown = ((flags & OtbItemFlags.FLOORCHANGEDOWN) == OtbItemFlags.FLOORCHANGEDOWN); item.FloorChangeNorth = ((flags & OtbItemFlags.FLOORCHANGENORTH) == OtbItemFlags.FLOORCHANGENORTH); item.FloorChangeEast = ((flags & OtbItemFlags.FLOORCHANGEEAST) == OtbItemFlags.FLOORCHANGEEAST); item.FloorChangeSouth = ((flags & OtbItemFlags.FLOORCHANGESOUTH) == OtbItemFlags.FLOORCHANGESOUTH); item.FloorChangeWest = ((flags & OtbItemFlags.FLOORCHANGEWEST) == OtbItemFlags.FLOORCHANGEWEST); item.alwaysOnBottom = ((flags & OtbItemFlags.ALWAYSONTOP) == OtbItemFlags.ALWAYSONTOP); item.IsVertical = ((flags & OtbItemFlags.VERTICAL) == OtbItemFlags.VERTICAL); item.IsHorizontal = ((flags & OtbItemFlags.HORIZONTAL) == OtbItemFlags.HORIZONTAL); item.IsHangable = ((flags & OtbItemFlags.HANGABLE) == OtbItemFlags.HANGABLE); item.IsRotatable = ((flags & OtbItemFlags.ROTABLE) == OtbItemFlags.ROTABLE); item.IsReadable = ((flags & OtbItemFlags.READABLE) == OtbItemFlags.READABLE); item.HasUseWith = ((flags & OtbItemFlags.USEABLE) == OtbItemFlags.USEABLE); item.HasHeight = ((flags & OtbItemFlags.HAS_HEIGHT) == OtbItemFlags.HAS_HEIGHT); item.LookThrough = ((flags & OtbItemFlags.LOOKTHROUGH) == OtbItemFlags.LOOKTHROUGH); item.AllowDistRead = ((flags & OtbItemFlags.ALLOWDISTREAD) == OtbItemFlags.ALLOWDISTREAD); item.IsAnimation = ((flags & OtbItemFlags.ANIMATION) == OtbItemFlags.ANIMATION); item.WalkStack = ((flags & OtbItemFlags.WALKSTACK) == OtbItemFlags.WALKSTACK); while (props.PeekChar() != -1) { byte attribute = props.ReadByte(); UInt16 datalen = props.ReadUInt16(); switch ((OtbItemAttr)attribute) { case OtbItemAttr.ITEM_ATTR_SERVERID: if (datalen != sizeof(UInt16)) { throw new Exception("Unexpected data length of server id block (Should be 2 bytes)"); } item.Id = props.ReadUInt16(); break; case OtbItemAttr.ITEM_ATTR_CLIENTID: if (datalen != sizeof(UInt16)) { throw new Exception("Unexpected data length of client id block (Should be 2 bytes)"); } item.SpriteId = props.ReadUInt16(); break; case OtbItemAttr.ITEM_ATTR_WAREID: if (datalen != sizeof(UInt16)) { throw new Exception("Unexpected data length of ware id block (Should be 2 bytes)"); } item.WareId = props.ReadUInt16(); break; case OtbItemAttr.ITEM_ATTR_SPEED: if (datalen != sizeof(UInt16)) { throw new Exception("Unexpected data length of speed block (Should be 2 bytes)"); } item.GroundSpeed = props.ReadUInt16(); break; case OtbItemAttr.ITEM_ATTR_NAME: item.Name = new string(props.ReadChars(datalen)); break; case OtbItemAttr.ITEM_ATTR_SPRITEHASH: if (datalen != 16) { throw new Exception("Unexpected data length of sprite hash (Should be 16 bytes)"); } item.SpriteHash = props.ReadBytes(16); break; case OtbItemAttr.ITEM_ATTR_MINIMAPCOLOR: if (datalen != 2) { throw new Exception("Unexpected data length of minimap color (Should be 2 bytes)"); } item.MinimapColor = props.ReadUInt16(); break; case OtbItemAttr.ITEM_ATTR_07: //read/write-able if (datalen != 2) { throw new Exception("Unexpected data length of attr 07 (Should be 2 bytes)"); } item.MaxReadWriteChars = props.ReadUInt16(); break; case OtbItemAttr.ITEM_ATTR_08: //readable if (datalen != 2) { throw new Exception("Unexpected data length of attr 08 (Should be 2 bytes)"); } item.MaxReadChars = props.ReadUInt16(); break; case OtbItemAttr.ITEM_ATTR_LIGHT2: if (datalen != sizeof(UInt16) * 2) { throw new Exception("Unexpected data length of item light (2) block"); } item.LightLevel = props.ReadUInt16(); item.LightColor = props.ReadUInt16(); break; case OtbItemAttr.ITEM_ATTR_TOPORDER: if (datalen != sizeof(byte)) { throw new Exception("Unexpected data length of item toporder block (Should be 1 byte)"); } item.AlwaysOnTopOrder = props.ReadByte(); break; default: //skip unknown attributes props.ReadBytes(datalen); break; } } if (MaxId < item.Id) { MaxId = item.Id; } items[item.Id] = item; clientItems[item.SpriteId] = item; node = node.Next; } return(true); }