예제 #1
0
        private static void LoadOtb(string fileName)
        {
            var loader = new FileLoader();
            loader.OpenFile(fileName);
            var node = loader.GetRootNode();

            PropertyReader props;

            if (loader.GetProps(node, out props))
            {
                props.ReadByte(); //junk?

                // 4 byte flags
                // attributes
                // 0x01 = version data
                var flags = props.ReadUInt32();
                var attr = props.ReadByte();

                if (attr == 0x01)
                {
                    var datalen = props.ReadUInt16();

                    if (datalen != 140)
                        throw new Exception("Invalid item.otb file.");

                    MajorVersion = props.ReadUInt32();
                    MinorVersion = props.ReadUInt32();
                    BuildNumber = props.ReadUInt32();
                }
            }

            if (MajorVersion == 0xFFFFFFFF)
                Logger.Warn("items.otb using generic client version.");
            else if (MajorVersion < 3)
            {
                throw new Exception("Old version of items.otb detected, a newer version of items.otb is required.");
            }
            else if (MajorVersion > 3)
            {
                throw new Exception("New version of items.otb detected, a newer version of the server is required.");
            }
            //else if(Items::dwMinorVersion != CLIENT_VERSION_861){
            //    std::cout << "Another (client) version of items.otb is required." << std::endl;
            //    return ERROR_INVALID_FORMAT;
            //}

            node = node.Child;

            while (node != null)
            {
                if (!loader.GetProps(node, out props))
                    throw new Exception("Invalid item.otb file.");

                var type = new ItemType { Group = (ItemGroup)node.Type };

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

                // process flags

                while (props.PeekChar() != -1)
                {
                    var attr = props.ReadByte();
                    var datalen = props.ReadUInt16();
                    switch ((ItemAttribute)attr)
                    {
                        case ItemAttribute.ServerId:
                            type.Id = props.ReadUInt16();

                            if (type.Id > 20000)
                            {
                                throw new Exception(string.Format("Invalid item id {0}.", type.Id));
                            }

                            break;
                        case ItemAttribute.ClientId:
                            type.ClientId = props.ReadUInt16();
                            break;
                        case ItemAttribute.Speed:
                            type.Speed = props.ReadUInt16();
                            break;
                        case ItemAttribute.Light2:
                            type.LightLevel = props.ReadUInt16();
                            type.LightColor = props.ReadUInt16();
                            break;
                        case ItemAttribute.TopOrder:
                            type.TopOrder = props.ReadByte();
                            break;
                        default:
                            props.ReadBytes(datalen);
                            break;
                    }
                }

                if (TYPES.ContainsKey(type.Id))
                    Logger.Warn(string.Format("Duplicated item with id {0}", type.Id));
                else
                    TYPES.Add(type.Id, type);

                node = node.Next;
            }
        }
예제 #2
0
        public void Load(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(loader, nodeMapData);
                        break;
                    case OtbMapNodeType.Towns:
                        ParseTowns(loader, nodeMapData);
                        break;
                }
                nodeMapData = nodeMapData.Next;
            }
        }