/// <summary>
 /// Create a client container representation
 /// </summary>
 /// <param name="Data">The item type of the container.</param>
 /// <param name="ContainerID">The server-side ID of the container.</param>
 public ClientContainer(ItemType Data, int ContainerID)
     : base(Data, 1)
 {
     this.ContainerID = ContainerID;
     // Will be set by viewport handler
     Name = "CID#" + ContainerID.ToString();
 }
        public TibiaGameData(Stream DatFile, Stream SpriteFile)
        {
            this.SpriteFile = SpriteFile;

            SprVersion = ReadU32(SpriteFile);
            DatVersion = ReadU32(DatFile);

            //get max id
            ItemCount = ReadU16(DatFile);
            CreatureCount = ReadU16(DatFile);
            EffectCount = ReadU16(DatFile);
            DistanceCount = ReadU16(DatFile);

            UInt16 MinClientID = 100; // tibia.dat start with id 100
            // We don't load distance/effects, if we would, just add effect_count & distance_count here
            UInt16 MaxClientID = (UInt16)((int)ItemCount + (int)CreatureCount + (int)EffectCount + (int)DistanceCount);

            UInt16 ID = MinClientID;
            // loop through all ItemDatabase until we reach the end of file
            while(ID <= MaxClientID)
            {
                GameSprite sType = new GameSprite(ID);
                ItemType iType = new ItemType(ID, sType);
                Sprites[ID] = sType;
                Items[ID] = iType;

                // Is it an effect?
                if (ID >= ItemCount + CreatureCount)
                    sType.AnimationSpeed = 100;
                if (ID >= ItemCount && ID < ItemCount + CreatureCount)
                    { };// sType.RenderOffset = -16;

                // read the options until we find a 0xff
                byte lastopt;
                byte optbyte = 0xff;

                do
                {
                    lastopt = optbyte;
                    optbyte = (byte)DatFile.ReadByte();

                    {
                        //7.4
                        switch(optbyte)
                        {
                            case 0x00:
                                //is groundtile
                                iType.IsGround = true;
                                iType.WalkSpeed = ReadU16(DatFile);
                                iType.AlwaysOnTop = 0;
                                break;
                            case 0x01: // all OnTop
                                iType.AlwaysOnTop = 1;
                                break;
                            case 0x02:
                                iType.CanSeeThrough = true;
                                iType.AlwaysOnTop = 2;
                                break;
                            case 0x03:
                                iType.IsContainer = true;
                                break;
                            case 0x04:
                                iType.IsStackable = true;
                                sType.IsStackable = true;
                                break;
                            case 0x05:
                                iType.IsUseableWith = true;
                                break;
                            case 0x06:
                                iType.IsLadder = true;
                                break;
                            case 0x07:
                                iType.IsReadable = true;
                                iType.IsWriteable = true;
                                iType.MaxTextLength = ReadU16(DatFile);
                                break;
                            case 0x08: // writtable objects that can't be edited
                                iType.IsReadable = true;
                                break;
                            case 0x09: //can contain fluids
                                iType.IsFluidContainer = true;
                                sType.IsFluidContainer = true;
                                break;
                            case 0x0A:
                                iType.IsSplash = true;
                                sType.IsSplash = true;
                                break;
                            case 0x0B:
                                iType.IsSolid = true;
                                break;
                            case 0x0C:
                                iType.Immoveable = true;
                                //Log.Fatal("Unknown attribute 0x0C - " + ID, this);
                                break;
                            case 0x0D: // blocks missiles (walls, magic wall etc)
                                iType.BlockProjectiles = true;
                                break;
                            case 0x0E: // blocks monster movement (flowers, parcels etc)
                                iType.BlockPathfinding = true;
                                break;
                            case 0x0F:
                                iType.CanPickup = true;
                                break;
                            case 0x10:
                                iType.LightLevel = ReadU16(DatFile);
                                iType.LightColor = ReadU16(DatFile);
                                break;
                            case 0x11: // can see what is under (ladder holes, stairs holes etc)
                                sType.FloorTransparent = true;
                                break;
                            case 0x12: // ground tiles that don't cause level change
                                iType.DontFallThrough = true;
                                break;
                            case 0x13: // mostly blocking items, but also items that can pile up in level (boxes, chairs etc)
                                iType.HasHeight = true;
                                sType.RenderHeight = ReadU16(DatFile);
                                break;
                            case 0x14: // player color templates
                                sType.RenderOffset = -8;
                                if (ID >=ItemCount)
                                    sType.ColorTemplate = true;
                                break;
                            case 0x18: // cropses that don't decay
                                iType.StaticCorpse = true;
                                break;
                            case 0x16:
                                // Blocking items, most ground
                                //Log.Debug("Unknown attribute 0x16 - " + ID, this);
                                ReadU16(DatFile);
                                break;
                            case 0x17:  // seems like decorables with 4 states of turning (exception first 4 are unique statues)
                                iType.CanTurn = true;
                                break;
                            case 0x19:  // wall items
                                iType.IsWall = true;
                                break;
                            case 0x1A:
                                // House walls, horizontal and corner, maybe CIP uses them only in houses?
                                break;
                            case 0x1B:  // walls 2 types of them same material (total 4 pairs)
                                break;
                            case 0x1C:  // Creature related, draw health bar with offset perhaps?
                                sType.HealthOffset = 16;
                                break;
                            case 0x1D:  // line spot ...
                                iType.IsFloorChanger = true;
                                 // Always between 1100 and 1115~
                                ReadU16(DatFile);
                                //Log.Debug("Unknown attribute 0x1D - " + ID + " - " + ReadU16(file), this);
                                break;
                            case 0xFF:
                                break;
                            default:
                                throw new System.IO.IOException("Malformed metadata file.");
                        }
                    }
                } while(optbyte != 0xFF);

                // Size and GameSprite data
                sType.Width = DatFile.ReadByte();
                sType.Height = DatFile.ReadByte();
                if((sType.Width > 1) || (sType.Height > 1)){
                    DatFile.ReadByte(); // Pointless?
                }

                sType.BlendFrames = DatFile.ReadByte();
                sType.XDiv = DatFile.ReadByte();
                sType.YDiv = DatFile.ReadByte();
                // 7.6 +
                // sType.ZDiv = file.ReadByte(); // Is this ever used? Maybe it means something else?
                sType.AnimationLength = DatFile.ReadByte();

                // Read the sprite ids
                for(int i = 0; i < sType.SpriteCount; ++i)
                {
                    UInt16 SpriteID = ReadU16(DatFile);
                    GameImage img = GetImage(SpriteID);
                    if(img == null)
                    {
                        img = new GameImage(this, SpriteID);
                        Images[SpriteID] = img;
                    }
                    sType.Images.Add(img);
                }

                ++ID;
            }
        }
 public ClientItem(ItemType Type, int Subtype)
 {
     this.Type = Type;
     this.Subtype = Subtype;
 }