예제 #1
0
        public bool GetMapTiles(Map map)
        {
            FileLoader loader = new FileLoader();
            loader.OpenFile(fileName);
            Node node = loader.GetRootNode();

            PropertyReader props;

            if (!loader.GetProps(node, out props))
            {
                lastError = "Could not read root property.";
                return false;
            }

            uint version = props.ReadUInt32();
            ushort width = props.ReadUInt16();
            ushort height = props.ReadUInt16();
            uint majorVersionItems = props.ReadUInt32();
            uint minorVersionItems = props.ReadUInt32();

            node = node.Child;

            if ((OtbmNodeType)node.Type != OtbmNodeType.MapData)
            {
                lastError = "Could not read data node.";
                return false;
            }

            if (!loader.GetProps(node, out props))
            {
                lastError = "Could not read map data attributes.";
                return false;
            }

            byte attribute;
            while (props.PeekChar() != -1)
            {
                attribute = props.ReadByte();
                switch ((OtbmAttribute)attribute)
                {
                    case OtbmAttribute.Description:
                        map.Description = props.GetString();
                        break;
                    case OtbmAttribute.ExtSpawnFile:
                        map.SpawnFile = props.GetString();
                        break;
                    case OtbmAttribute.ExtHouseFile:
                        map.HouseFile = props.GetString();
                        break;
                    default:
                        lastError = "Unknown header node.";
                        return false;
                }
            }

            Node nodeMapData = node.Child;

            while (nodeMapData != null)
            {
                switch ((OtbmNodeType)nodeMapData.Type)
                {
                    case OtbmNodeType.TileArea:
                        if (!ParseTileArea(map, loader, nodeMapData)) return false;
                        break;
                    case OtbmNodeType.Towns:
                        if (!ParseTowns(map, loader, nodeMapData)) return false;
                        break;
                }
                nodeMapData = nodeMapData.Next;
            }

            return true;
        }
예제 #2
0
        public IEnumerable <ItemInfo> GetAllItemInfo()
        {
            FileLoader loader = new FileLoader();

            loader.OpenFile(fileName);
            Node node = loader.GetRootNode();

            PropertyReader props;

            if (loader.GetProps(node, out props))
            {
                // 4 byte flags
                // attributes
                // 0x01 = version data
                uint flags = props.ReadUInt32();
                byte attr  = props.ReadByte();
                if (attr == 0x01)
                {
                    ushort datalen = props.ReadUInt16();
                    if (datalen != 140)
                    {
                        yield return(null);

                        yield break;
                    }
                    uint majorVersion = props.ReadUInt32();
                    uint minorVersion = props.ReadUInt32();
                    uint buildNumber  = props.ReadUInt32();
                }
            }

            node = node.Child;

            while (node != null)
            {
                if (!loader.GetProps(node, out props))
                {
                    yield return(null);

                    yield break;
                }

                ItemInfo info = new ItemInfo();

                info.Group = (ItemGroup)node.Type;

                ItemFlags flags = (ItemFlags)props.ReadUInt32();
                info.IsBlocking           = flags.HasFlag(ItemFlags.BlocksSolid);
                info.IsProjectileBlocking = flags.HasFlag(ItemFlags.BlocksProjectile);
                info.IsPathBlocking       = flags.HasFlag(ItemFlags.BlocksPathFinding);
                info.HasHeight            = flags.HasFlag(ItemFlags.HasHeight);
                info.IsUseable            = flags.HasFlag(ItemFlags.Useable);
                info.IsPickupable         = flags.HasFlag(ItemFlags.Pickupable);
                info.IsMoveable           = flags.HasFlag(ItemFlags.Moveable);
                info.IsStackable          = flags.HasFlag(ItemFlags.Stackable);
                info.IsAlwaysOnTop        = flags.HasFlag(ItemFlags.AlwaysOnTop);
                info.IsVertical           = flags.HasFlag(ItemFlags.Vertical);
                info.IsHorizontal         = flags.HasFlag(ItemFlags.Horizontal);
                info.IsHangable           = flags.HasFlag(ItemFlags.Hangable);
                info.IsDistanceReadable   = flags.HasFlag(ItemFlags.AllowDistanceRead);
                info.IsRotatable          = flags.HasFlag(ItemFlags.Rotatable);
                info.IsReadable           = flags.HasFlag(ItemFlags.Readable);
                info.HasClientCharges     = flags.HasFlag(ItemFlags.ClientCharges);
                info.CanLookThrough       = flags.HasFlag(ItemFlags.LookThrough);

                // process flags

                byte   attr;
                ushort datalen;
                while (props.PeekChar() != -1)
                {
                    attr    = props.ReadByte();
                    datalen = props.ReadUInt16();
                    switch ((ItemAttribute)attr)
                    {
                    case ItemAttribute.ServerId:
                        info.Id = props.ReadUInt16();
                        break;

                    case ItemAttribute.ClientId:
                        info.SpriteId = props.ReadUInt16();
                        break;

                    case ItemAttribute.Speed:
                        info.Speed = props.ReadUInt16();
                        break;

                    case ItemAttribute.TopOrder:
                        info.TopOrder = props.ReadByte();
                        break;

                    default:
                        props.ReadBytes(datalen);
                        break;
                    }
                }
                yield return(info);

                node = node.Next;
            }
        }
예제 #3
0
        private bool ParseTowns(Map map, FileLoader loader, Node node)
        {
            PropertyReader props;
            Node nodeTown = node.Child;
            while (nodeTown != null)
            {
                if (!loader.GetProps(nodeTown, out props))
                {
                    lastError = "Could not read town data.";
                    return false;
                }

                uint townid = props.ReadUInt32();
                string townName = props.GetString();
                ushort townTempleX = props.ReadUInt16();
                ushort townTempleY = props.ReadUInt16();
                byte townTempleZ = props.ReadByte();

                Town town = new Town(
                    townid,
                    townName,
                    new Location(townTempleX, townTempleY, townTempleZ));

                map.Towns.Add(town);

                nodeTown = nodeTown.Next;
            }
            return true;
        }
예제 #4
0
        private bool ParseTileArea(Map map, FileLoader loader, Node node)
        {
            PropertyReader props;
            if (!loader.GetProps(node, out props))
            {
                lastError = "Invalid map node.";
                return false;
            }

            int baseX = props.ReadUInt16();
            int baseY = props.ReadUInt16();
            int baseZ = props.ReadByte();

            Node nodeTile = node.Child;

            while (nodeTile != null)
            {
                if (nodeTile.Type == (long)OtbmNodeType.Tile ||
                    nodeTile.Type == (long)OtbmNodeType.HouseTile)
                {
                    loader.GetProps(nodeTile, out props);

                    int tileX = baseX + props.ReadByte();
                    int tileY = baseY + props.ReadByte();
                    int tileZ = baseZ;

                    Tile tile = new Tile();
                    tile.Location = new Location(tileX, tileY, tileZ);

                    // TODO: houses
                    if (nodeTile.Type == (long)OtbmNodeType.HouseTile)
                    {
                        uint houseId = props.ReadUInt32();
                    }

                    byte attribute;
                    while (props.PeekChar() != -1)
                    {
                        attribute = props.ReadByte();
                        switch ((OtbmAttribute)attribute)
                        {
                            case OtbmAttribute.TileFlags:
                            {
                                TileFlags flags = (TileFlags)props.ReadUInt32();
                                if ((flags & TileFlags.ProtectionZone) == TileFlags.ProtectionZone)
                                {
                                    tile.IsProtectionZone = true;
                                }
                                else if ((flags & TileFlags.NoPvpZone) == TileFlags.NoPvpZone)
                                {
                                    tile.IsNoPvpZone = true;
                                }
                                else if ((flags & TileFlags.PvpZone) == TileFlags.PvpZone)
                                {
                                    tile.IsPvpZone = true;
                                }

                                if ((flags & TileFlags.NoLogout) == TileFlags.NoLogout)
                                {
                                    tile.IsNoLogoutZone = true;
                                }

                                if ((flags & TileFlags.Refresh) == TileFlags.Refresh)
                                {
                                    // TODO: Warn about house
                                    tile.IsRefreshZone = true;
                                }
                                break;
                            }
                            case OtbmAttribute.Item:
                            {
                                ushort itemId = props.ReadUInt16();
                                Item item = Item.Create(itemId);

                                // TODO: if isHouseTile && !item.Info.IsMoveable

                                if (item.Info.Group == ItemGroup.Ground)
                                {
                                    tile.Ground = item;
                                }
                                else
                                {
                                    tile.AddItem(item);
                                }
                                break;
                            }
                            default:
                                lastError = tile.Location + " Unknown tile attribute.";
                                return false;
                        }
                    }

                    Node nodeItem = nodeTile.Child;

                    while (nodeItem != null)
                    {
                        if (nodeItem.Type == (long)OtbmNodeType.Item)
                        {
                            loader.GetProps(nodeItem, out props);
                            ushort itemId = props.ReadUInt16();

                            // TODO: subclass item, different deserializations
                            // for different types
                            Item item = Item.Create(itemId);
                            if (item.Info.Group == ItemGroup.Ground)
                            {
                                tile.Ground = item;
                            }
                            else
                            {
                                tile.AddItem(item);
                            }
                        }
                        else
                        {
                            lastError += tile.Location + " Unknown node type.";
                            return false;
                        }
                        nodeItem = nodeItem.Next;
                    }

                    map.SetTile(tile.Location, tile);
                }
                nodeTile = nodeTile.Next;
            }

            return true;
        }
예제 #5
0
        public IEnumerable<ItemInfo> GetAllItemInfo()
        {
            FileLoader loader = new FileLoader();
            loader.OpenFile(fileName);
            Node node = loader.GetRootNode();

            PropertyReader props;

            if (loader.GetProps(node, out props))
            {
                // 4 byte flags
                // attributes
                // 0x01 = version data
                uint flags = props.ReadUInt32();
                byte attr = props.ReadByte();
                if (attr == 0x01)
                {
                    ushort datalen = props.ReadUInt16();
                    if (datalen != 140)
                    {
                        yield return null;
                        yield break;
                    }
                    uint majorVersion = props.ReadUInt32();
                    uint minorVersion = props.ReadUInt32();
                    uint buildNumber = props.ReadUInt32();
                }
            }

            node = node.Child;

            while (node != null)
            {
                if (!loader.GetProps(node, out props))
                {
                    yield return null;
                    yield break;
                }

                ItemInfo info = new ItemInfo();

                info.Group = (ItemGroup)node.Type;

                ItemFlags flags = (ItemFlags)props.ReadUInt32();
                info.IsBlocking = flags.HasFlag(ItemFlags.BlocksSolid);
                info.IsProjectileBlocking = flags.HasFlag(ItemFlags.BlocksProjectile);
                info.IsPathBlocking = flags.HasFlag(ItemFlags.BlocksPathFinding);
                info.HasHeight = flags.HasFlag(ItemFlags.HasHeight);
                info.IsUseable = flags.HasFlag(ItemFlags.Useable);
                info.IsPickupable = flags.HasFlag(ItemFlags.Pickupable);
                info.IsMoveable = flags.HasFlag(ItemFlags.Moveable);
                info.IsStackable = flags.HasFlag(ItemFlags.Stackable);
                info.IsAlwaysOnTop = flags.HasFlag(ItemFlags.AlwaysOnTop);
                info.IsVertical = flags.HasFlag(ItemFlags.Vertical);
                info.IsHorizontal = flags.HasFlag(ItemFlags.Horizontal);
                info.IsHangable = flags.HasFlag(ItemFlags.Hangable);
                info.IsDistanceReadable = flags.HasFlag(ItemFlags.AllowDistanceRead);
                info.IsRotatable = flags.HasFlag(ItemFlags.Rotatable);
                info.IsReadable = flags.HasFlag(ItemFlags.Readable);
                info.HasClientCharges = flags.HasFlag(ItemFlags.ClientCharges);
                info.CanLookThrough = flags.HasFlag(ItemFlags.LookThrough);

                // process flags

                byte attr;
                ushort datalen;
                while (props.PeekChar() != -1)
                {
                    attr = props.ReadByte();
                    datalen = props.ReadUInt16();
                    switch ((ItemAttribute)attr)
                    {
                        case ItemAttribute.ServerId:
                            info.Id = props.ReadUInt16();
                            break;
                        case ItemAttribute.ClientId:
                            info.SpriteId = props.ReadUInt16();
                            break;
                        case ItemAttribute.Speed:
                            info.Speed = props.ReadUInt16();
                            break;
                        case ItemAttribute.TopOrder:
                            info.TopOrder = props.ReadByte();
                            break;
                        default:
                            props.ReadBytes(datalen);
                            break;
                    }
                }
                yield return info;
                node = node.Next;
            }
        }
예제 #6
0
        public bool GetMapTiles(Map map)
        {
            FileLoader loader = new FileLoader();

            loader.OpenFile(fileName);
            Node node = loader.GetRootNode();

            PropertyReader props;

            if (!loader.GetProps(node, out props))
            {
                lastError = "Could not read root property.";
                return(false);
            }

            uint   version           = props.ReadUInt32();
            ushort width             = props.ReadUInt16();
            ushort height            = props.ReadUInt16();
            uint   majorVersionItems = props.ReadUInt32();
            uint   minorVersionItems = props.ReadUInt32();

            node = node.Child;

            if ((OtbmNodeType)node.Type != OtbmNodeType.MapData)
            {
                lastError = "Could not read data node.";
                return(false);
            }

            if (!loader.GetProps(node, out props))
            {
                lastError = "Could not read map data attributes.";
                return(false);
            }

            byte attribute;

            while (props.PeekChar() != -1)
            {
                attribute = props.ReadByte();
                switch ((OtbmAttribute)attribute)
                {
                case OtbmAttribute.Description:
                    map.Description = props.GetString();
                    break;

                case OtbmAttribute.ExtSpawnFile:
                    map.SpawnFile = props.GetString();
                    break;

                case OtbmAttribute.ExtHouseFile:
                    map.HouseFile = props.GetString();
                    break;

                default:
                    lastError = "Unknown header node.";
                    return(false);
                }
            }

            Node nodeMapData = node.Child;

            while (nodeMapData != null)
            {
                switch ((OtbmNodeType)nodeMapData.Type)
                {
                case OtbmNodeType.TileArea:
                    if (!ParseTileArea(map, loader, nodeMapData))
                    {
                        return(false);
                    }
                    break;

                case OtbmNodeType.Towns:
                    if (!ParseTowns(map, loader, nodeMapData))
                    {
                        return(false);
                    }
                    break;
                }
                nodeMapData = nodeMapData.Next;
            }

            return(true);
        }
예제 #7
0
        private bool ParseTileArea(Map map, FileLoader loader, Node node)
        {
            PropertyReader props;

            if (!loader.GetProps(node, out props))
            {
                lastError = "Invalid map node.";
                return(false);
            }

            int baseX = props.ReadUInt16();
            int baseY = props.ReadUInt16();
            int baseZ = props.ReadByte();

            Node nodeTile = node.Child;

            while (nodeTile != null)
            {
                if (nodeTile.Type == (long)OtbmNodeType.Tile ||
                    nodeTile.Type == (long)OtbmNodeType.HouseTile)
                {
                    loader.GetProps(nodeTile, out props);

                    int tileX = baseX + props.ReadByte();
                    int tileY = baseY + props.ReadByte();
                    int tileZ = baseZ;

                    Tile tile = new Tile();
                    tile.Location = new Location(tileX, tileY, tileZ);

                    // TODO: houses
                    if (nodeTile.Type == (long)OtbmNodeType.HouseTile)
                    {
                        uint houseId = props.ReadUInt32();
                    }

                    byte attribute;
                    while (props.PeekChar() != -1)
                    {
                        attribute = props.ReadByte();
                        switch ((OtbmAttribute)attribute)
                        {
                        case OtbmAttribute.TileFlags:
                        {
                            TileFlags flags = (TileFlags)props.ReadUInt32();
                            if ((flags & TileFlags.ProtectionZone) == TileFlags.ProtectionZone)
                            {
                                tile.IsProtectionZone = true;
                            }
                            else if ((flags & TileFlags.NoPvpZone) == TileFlags.NoPvpZone)
                            {
                                tile.IsNoPvpZone = true;
                            }
                            else if ((flags & TileFlags.PvpZone) == TileFlags.PvpZone)
                            {
                                tile.IsPvpZone = true;
                            }

                            if ((flags & TileFlags.NoLogout) == TileFlags.NoLogout)
                            {
                                tile.IsNoLogoutZone = true;
                            }

                            if ((flags & TileFlags.Refresh) == TileFlags.Refresh)
                            {
                                // TODO: Warn about house
                                tile.IsRefreshZone = true;
                            }
                            break;
                        }

                        case OtbmAttribute.Item:
                        {
                            ushort itemId = props.ReadUInt16();
                            Item   item   = Item.Create(itemId);

                            // TODO: if isHouseTile && !item.Info.IsMoveable

                            if (item.Info.Group == ItemGroup.Ground)
                            {
                                tile.Ground = item;
                            }
                            else
                            {
                                tile.AddItem(item);
                            }
                            break;
                        }

                        default:
                            lastError = tile.Location + " Unknown tile attribute.";
                            return(false);
                        }
                    }

                    Node nodeItem = nodeTile.Child;

                    while (nodeItem != null)
                    {
                        if (nodeItem.Type == (long)OtbmNodeType.Item)
                        {
                            loader.GetProps(nodeItem, out props);
                            ushort itemId = props.ReadUInt16();

                            // TODO: subclass item, different deserializations
                            // for different types
                            Item item = Item.Create(itemId);
                            if (item.Info.Group == ItemGroup.Ground)
                            {
                                tile.Ground = item;
                            }
                            else
                            {
                                tile.AddItem(item);
                            }
                        }
                        else
                        {
                            lastError += tile.Location + " Unknown node type.";
                            return(false);
                        }
                        nodeItem = nodeItem.Next;
                    }

                    map.SetTile(tile.Location, tile);
                }
                nodeTile = nodeTile.Next;
            }

            return(true);
        }