Пример #1
0
 public virtual void Deserialize(FileReader fileReader, BinaryNode itemNode, PropertyReader reader)
 {
     Deserialize(reader);
 }
Пример #2
0
        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;
            }
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
                }
            }
        }
Пример #5
0
 public void clearRootNode()
 {
     root = null;
 }
Пример #6
0
        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);
        }