예제 #1
0
 public static void Serialize(UnitObjectStats.Stat stats, string path)
 {
     XmlSerializer serializer = new XmlSerializer(typeof(UnitObjectStats.Stat));
     TextWriter tw = new StreamWriter(path);
     serializer.Serialize(tw, stats);
     tw.Close();
 }
예제 #2
0
 private void _Init()
 {
     SaveLocations = new List<SaveLocation>(3); // always seen as 3 (1 for each difficulty - even if not applicable on the char yet)
     StateCodes1 = new List<Int32>();
     StateCodes2 = new List<Int32>();
     Bookmarks = new List<Bookmark>();
     Stats = new UnitObjectStats(FileManager, _debugOutputLoadingProgress);
     Items = new List<UnitObject>();
     Appearance = new UnitAppearance();
     Hotkeys = new List<Hotkey>();
     Position = new Vector3();
     Normal = new Vector3();
 }
예제 #3
0
        private int _GenerateUnitObject(ref byte[] buffer, int offset, int maxBytes, UInt64 bitField, ObjectContext context, UInt64 itemsBitField, ObjectContext itemsContext, UnitObjectStats.StatContext statsContext)
        {
            int byteCount;

            lock (_bitBuffer)
            {
                if (buffer == null)
                {
                    _bitBuffer.CreateBuffer();
                }
                else
                {
                    _bitBuffer.SetBuffer(buffer, offset, maxBytes);
                }

                // BitField and Context could possibly be done "automatically", but it'd require changing  every _TestBit()
                //            to a set of TestContext ranges and such; simplier like this - and essentially the same result
                _WriteUnit(bitField, context, itemsBitField, itemsContext, statsContext); // no items supplied

                byteCount = _bitBuffer.BytesUsed;

                if (buffer == null)
                {
                    buffer = _bitBuffer.GetBuffer();
                }
                _bitBuffer.FreeBuffer();
            }

            return byteCount;
        }
예제 #4
0
        private void _WriteUnit(UInt64 bitField, ObjectContext context, UInt64 itemsBitField, ObjectContext itemsContext, UnitObjectStats.StatContext statContext, BitBuffer bitBuffer = null)
        {
            _bitField = bitField;
            _context = context;
            Stats.Context = statContext;
            if (bitBuffer != null) _bitBuffer = bitBuffer;

            /***** Unit Header *****
             * Version                                          16                  Should be 0x00BF for SP client, 0x00CD for Resurrection client.
             * Usage                                            8                   0 for SP. For Resurrection client; 2 for char select, 4 for item drop
             * bitFieldCount                                    8                   Must be <= 2. I haven't tested with it != 2 though.
             * {
             *      bitField                                    32                  Each bit determines if 'x' is read in or not.
             * }
             *
             * if (TestBit(bitField, 0x1D))
             * {
             *      bitCount                                    32                  Bit count of entire unit object.
             * }
             *
             * if (TestBit(bitField, 0x00))
             * {
             *      BeginFlag                                   32                  Flags used to check data/position alignment.
             * }
             *
             * if (TestBit(bitField, 0x1C))
             * {
             *      timeStamp1                                  32                  I'm not actually sure what these three things are but they can be set to 0x00000000
             *      timeStamp2                                  32                  and it will still be loaded fine. I call them time stamps simply because the first
             *      timeStamp3                                  32                  one changes every time the file is saved.
             * }
             *
             * if (TestBit(bitField, 0x1F))
             * {
             *      unknownCount                                4                   count + 8 is what must be written. e.g. If count = 3, then write 11.
             *      {
             *          unknown                                 16                  // TO BE DETERMINED
             *          unknown                                 16                  // TO BE DETERMINED
             *      }
             * }
             *
             * if (TestBit(bitField, 0x20))
             * {
             *      characterFlagCount                          8                   Character state flags
             *      {                                                               e.g. Elite, Hardcore, Hardcore Dead, etc.
             *          characterFlag                           16                  However it should be noted that the game doesn't actually appear to use these.
             *      }                                                               It uses the ones located further down.
             * }
             *
             ***** Unit Body *****                                                  (the header "chunk" is read in its own function in-game - hence I call it a header, lol)
             *
             * if (TestBit(bitField, 0x1B))
             * {
             *      BookmarkCount                               5                   Count of following block - only seen as 1 (only 1 row in Bookmarks table - "hotkeys")
             *      {
             *          Code                                    16                  Code value of offset - code is from Bookmarks table.
             *          Offset                                  32                  Bit Offset value
             *      }
             * }
             *
             * if (TestBit(bitField, 0x05))
             * {
             *      Unknown                                     32                  Seen in MP only - unknown usage.
             * }
             *
             * UnitType                                         4                   The type of .. Is this from UnitType table?
             * UnitCode                                         16                  The code value of the
             *
             * if (TestBit(bitField, 0x17))
             * {                                                                    This chunk is read in by a secondary non-standard function.
             *      ObjectId                                    64                  Contains a unique id for this unit object (e.g. item hash id to stop duping, etc).
             * }
             *
             * if (TestBit(bitField, 0x03) || TestBit(bitField, 0x01))
             * {
             *      IsInventory                                 1                   Is true if UnitObject is item in inventory. False if item is a "world drop" (i.e. drop from monster)
             *      {
             *          if (TestBit(bitField, 0x02))
             *          {
             *              Unknown                             32                  // UNTESTED
             *          }
             *
             *          InventoryType                           16                  Inventory item is within.
             *          InventoryPositionX                      12                  X Position of item in inventory.
             *          InventoryPositionY                      12                  Y Position of item in inventory.
             *
             *          Unknown                                 64                  Non-standard function reading - unknown usage.
             *      }
             *      else
             *      {
             *          Unknown0103Int1                         32                  These values have something to do with an "item dropped" world positioning etc
             *                                                                      i.e. only applicable to MP clients.
             *          Unknown0103Float11                      32
             *          Unknown0103Float12                      32
             *          Unknown0103Float13                      32
             *
             *          Unknown0103Float21                      32
             *          Unknown0103Float22                      32
             *          Unknown0103Float23                      32
             *
             *          Unknown0103Float31                      32
             *          Unknown0103Float32                      32
             *          Unknown0103Float33                      32
             *
             *          Unknown0103Int2                         10
             *
             *          Unknown0103Float5                       32
             *
             *          Unknown0103Float6                       32
             *      }
             * }
             *
             * if (TestBit(bitField, 0x06))
             * {
             *      unknownBool                                 1                   // TO BE DETEREMINED
             * }                                                                    // If exists has always been 1.
             *
             * if (TestBit(bitField, 0x09))
             * {
             *      unknown                                     8                   // TO BE DETERMINED
             * }
             *
             * if (TestBit(bitField, 0x07))
             * {
             *      CharacterHeight                             8                   Height of character.
             *      CharacterWidth                              8                   Width of character.
             * }
             *
             * if (TestBit(bitField, 0x08))
             * {
             *      UnicodeCharCount                            8                   Number of (unicode) characters in following string.
             *      CharacterName                               8*2*count           Character's name in Unicode (no \0) - doesn't appear to be actually used in-game...
             * }
             *
             * if (TestBit(bitField, 0x0A))
             * {
             *      characterFlagCount                          8                   Character state flags
             *      {                                                               e.g. Elite, Hardcore, Hardcore Dead, etc.
             *          characterFlag                           16                  These flags actually affect in-game (unlike the previous set which
             *      }                                                               appear to be unused).
             * }
             *
             * if (Context > 2 && (Context <= 6 || Context != 7))                   These would be applicable to MP only - SP has Usage == 0
             * {
             *      ContextBool                                 1                   True if following value is present.
             *      {
             *          ContextBoolValu                         4                   // TO BE DETERMINED
             *      }
             * }
             *
             * IsDead                                           1                   Does NOT influence HC dead! If the character died right before saving this flag is set to 1
             *
             * if (TestBit(bitField, 0x0D))
             * {
             *      UNIT STAT BLOCK                                                 See WriteStatBlock().
             * }
             *
             * HasAppearanceDetails                             1                   Bool type.
             * {
             *      EquippedItemCount                           3                   Count of equipped items.
             *      {
             *          if (TestBit(bitField, 0x0F))
             *          {
             *              Unknown                             32                  // UNTESTED
             *          }
             *
             *          ItemCode                                16                  Code of item equipped.
             *
             *          if (TestBit(bitField, 0x22))
             *          {
             *              Unknown                             8                   Read from ReadBitsShift()
             *          }
             *
             *          if (TestBit(bitField, 0x18))
             *          {
             *              AffixCount                          3 (+1 Ver > 0xC0)   Count of affix codes.
             *              {
             *                  Code                            32                  Code of affix.
             *              }
             *          }
             *      }
             *
             *      Unknown                                     16                  // TO BE DETEREMINED
             *
             *      if (TestBit(bitField, 0x16))
             *      {
             *          Unknown                                 64                  Non-standard function reading (as above).
             *      }
             *
             *      if (TestBit(bitField, 0x23))
             *      {
             *          Unknown                                 16                  // TO BE DETEREMINED
             *      }
             *
             *      if (TestBit(bitField, 0x11))
             *      {
             *          WardrobeLayerHeadCount                  4                   Count of WardrobeLayers for Head
             *          {
             *              Code                                16                  Code of WardrobeLayer.
             *          }
             *
             *          WardrobeAppearanceGroupCount            3                   Count of model appearance parts.
             *          {
             *              Code                                16                  Code of WardrobeAppearanceGroup - Order is: body, head, hair, face accessory.
             *          }
             *
             *          ColorCount                              4                   Count of following block.
             *          {
             *              ColorPaletteIndicies                8                   Not sure... Is this row index? Code?
             *          }
             *      }
             *
             *      if (TestBit(bitField, 0x10))
             *      {
             *          WardrobeLayerCount                      16                  Count of equipped gears.
             *          {
             *              Code                                16                  Code of equipped item wardrobe layer.
             *              UnknownBool                         1                   Bool type.
             *              {
             *                  Unknown                         2                   // TO BE DETEREMINED
             *              }
             *          }
             *      }
             * }
             *
             *
             * ItemBitOffset                                    32                  Bit offset to end of all item blocks.
             * ItemCount                                        10                  Count of items.
             * {
             *      ITEMS
             * }
             *
             *
             * if (TestBit(bitField1, 0x1A))
             * {
             *      WeaponConfigFlag                            32                  Must be 0x91103A74.
             *
             *      EndFlagBitOffset                            32                  Bit offset to end flag.
             *      WeaponConfigCount                           6                   Count of weapon configs.
             *      {
             *          Code                                    16                  Code of weapon.
             *          UnknownCount                            4                   Count of following block - Must be 0x02.
             *          {
             *              Exists                              1                   Bool type.
             *              {
             *                  Unknown                         32                  // TO BE DETEREMINED
             *              }
             *          }
             *
             *          UnknownCount                            4                   Count of...?
             *          {
             *              Exists                              1                   Bool type.
             *              {
             *                  Unknown                         32                  // TO BE DETEREMINED
             *              }
             *          }
             *
             *          Code                                    32                  Code of something...?
             *      }
             * }
             *
             * if (TestBit(bitField, 0x00))
             * {
             *      EndFlag                                     32                  Flags used to check data/position alignment.
             * }
             */

            int bitCountEofOffset = -1;
            bool isItem = (UnitType == UnitTypes.Item);
            bool isMonster = (UnitType == UnitTypes.Monster);

            /***** Unit Header *****/

            int bitCountStart = _bitBuffer.BitOffset;

            _version = CurrentVersion;
            _bitBuffer.WriteBits(_version, 16);
            _bitBuffer.WriteBits((int)_context, 8);
            _bitBuffer.WriteBits(0x02, 8);
            {
                _bitBuffer.WriteUInt64(_bitField);
            }

            if (_TestBit(Bits.Bit1DBitCountEof))
            {
                bitCountEofOffset = _bitBuffer.BitOffset;
                _bitBuffer.WriteInt32(0x00000000);
            }

            if (_TestBit(Bits.Bit00FlagAlignment))
            {
                _bitBuffer.WriteUInt32((isItem || isMonster) ? ItemMagicWord : ObjectMagicWord);
            }

            if (_TestBit(Bits.Bit1CTimeStamps))
            {
                _bitBuffer.WriteInt32(_timeStamp1);
                _bitBuffer.WriteInt32(_timeStamp2);
                _bitBuffer.WriteInt32(_timeStamp3);
            }

            if (_TestBit(Bits.Bit1FSaveLocations))
            {
                int saveLocationsCount = SaveLocations.Count;
                _bitBuffer.WriteBitsShift(saveLocationsCount, 4);
                foreach (SaveLocation saveLocation in SaveLocations)
                {
                    if (saveLocation.Level == null || saveLocation.Difficulty == null)
                    {
                        const ushort noCode = 0xFFFF;
                        _bitBuffer.WriteUInt16(noCode);
                        _bitBuffer.WriteUInt16(noCode);
                    }
                    else
                    {
                        _bitBuffer.WriteUInt16((ushort)saveLocation.Level.code);
                        _bitBuffer.WriteUInt16((ushort)saveLocation.Difficulty.code);
                    }
                }
            }

            if (_TestBit(Bits.Bit20States1) && (!isItem || !isMonster))
            {
                int stateCount = StateCodes1.Count;
                _bitBuffer.WriteBits(stateCount, 8);

                foreach (short stateCode in StateCodes1)
                {
                    _bitBuffer.WriteInt16(stateCode);
                }
            }

            /***** Unit Body *****/

            int bitOffsetHotkeys = 0;
            if (_TestBit(Bits.Bit1BBookmarks))
            {
                int bitOffsetsCount = Bookmarks.Count;

                _bitBuffer.WriteBits(bitOffsetsCount, 5);
                for (int i = 0; i < bitOffsetsCount; i++)
                {
                    _bitBuffer.WriteUInt16(Bookmarks[i].Code);
                    bitOffsetHotkeys = _bitBuffer.BitOffset;
                    _bitBuffer.WriteInt32(0x00000000);
                }
            }

            if (_TestBit(Bits.Bit05Unknown))
            {
                _bitBuffer.WriteInt32(UnitObjectId);
            }

            _bitBuffer.WriteBits((int)UnitType, 4);
            if (UnitData == null && UnitCode == 0) throw new Exceptions.UnitObjectException("Unexpected null UnitData object.");
            _bitBuffer.WriteInt16((UnitData == null) ? UnitCode : UnitData.code); // characters from SP or mods may have items not found - we don't want to delete them (todo: or do we?)

            if (_TestBit(Bits.Bit17ObjectId))
            {
                _bitBuffer.WriteUInt64(ObjectId);
            }

            if (_TestBit(Bits.Bit01Unknown) || _TestBit(Bits.Bit03Unknown))
            {
                _bitBuffer.WriteBool(IsInventory);
                if (IsInventory) // item is in inventory
                {
                    if (_TestBit(Bits.Bit02Unknown))
                    {
                        _bitBuffer.WriteInt32(Unknown02);
                    }

                    _bitBuffer.WriteBits(InventoryLocationIndex, 12);
                    _bitBuffer.WriteBits(InventoryPositionX, 12);
                    _bitBuffer.WriteBits(InventoryPositionY, 12);
                    _bitBuffer.WriteBits(Unknown04, 4);

                    _bitBuffer.WriteNonStandardFunc(Unknown0103Int64);
                }
                else // item is a "world drop"
                {
                    _bitBuffer.WriteInt32(RoomId);

                    _bitBuffer.WriteFloat(Position.X);
                    _bitBuffer.WriteFloat(Position.Y);
                    _bitBuffer.WriteFloat(Position.Z);

                    _bitBuffer.WriteFloat(Unknown0103Float21);
                    _bitBuffer.WriteFloat(Unknown0103Float22);
                    _bitBuffer.WriteFloat(Unknown0103Float23);

                    _bitBuffer.WriteFloat(Normal.X);
                    _bitBuffer.WriteFloat(Normal.Y);
                    _bitBuffer.WriteFloat(Normal.Z);

                    _bitBuffer.WriteBits(Unknown0103Int2, 10);

                    _bitBuffer.WriteFloat(Unknown0103Float4);

                    _bitBuffer.WriteFloat(Unknown0103Float5);
                }
            }

            if (_TestBit(Bits.Bit06Unknown))
            {
                _bitBuffer.WriteBool(UnknownBool06);
                if (!UnknownBool06)
                {
                    throw new Exceptions.UnitObjectNotImplementedException("_WriteUnit : if (!UnknownBool06)");
                }
            }

            if (_TestBit(Bits.Bit09ItemLookGroup))
            {
                _bitBuffer.WriteByte(ItemLookGroupCode);
            }

            if (_TestBit(Bits.Bit07CharacterShape))
            {
                _bitBuffer.WriteByte(CharacterHeight);
                _bitBuffer.WriteByte(CharacterBulk);
            }

            if (_TestBit(Bits.Bit08CharacterName) && !String.IsNullOrEmpty(Name))
            {
                _bitBuffer.WriteBits(_charNameBytes.Length / 2, 8); // is Unicode string without \0
                foreach (byte b in _charNameBytes)
                {
                    _bitBuffer.WriteByte(b);
                }
            }

            if (_TestBit(Bits.Bit0AStates2))
            {
                int stateCount = StateCodes2.Count;
                _bitBuffer.WriteBits(stateCount, 8);

                foreach (short stateCode in StateCodes2)
                {
                    _bitBuffer.WriteInt16(stateCode);
                }
            }

            if (_context > ObjectContext.CharSelect && (_context <= ObjectContext.Unknown6 || _context != ObjectContext.Unknown7)) // so if == 0, 1, 2, 7, then *don't* do this
            {
                _bitBuffer.WriteBool(ContextBool);
                if (ContextBool)
                {
                    _bitBuffer.WriteBits(ContextBoolValue, 4);
                }
            }

            _bitBuffer.WriteBool(IsDead);

            if (_TestBit(Bits.Bit0DStats))
            {
                Stats.WriteStats(_bitBuffer, true);
            }
            else if (_TestBit(Bits.Bit14CharSelectStats))
            {
                int charLevel = Stats.GetStatValueOrDefault("level");
                int charPvpRank = Stats.GetStatValueOrDefault("pvp_rank");
                _bitBuffer.WriteByte(charLevel);
                _bitBuffer.WriteByte(charPvpRank);

                if (_TestBit(Bits.Bit1ECharSelectStatsMaxDifficulty))
                {
                    int maxDifficulty = Stats.GetStatValueOrDefault("difficulty_max");
                    _bitBuffer.WriteBits(maxDifficulty, 3);
                }
            }

            _bitBuffer.WriteBool(HasAppearanceDetails);
            if (HasAppearanceDetails)
            {
                int equippedItemCount = Appearance.EquippedItems.Count;
                _bitBuffer.WriteBits(equippedItemCount, 3);
                for (int i = 0; i < equippedItemCount; i++)
                {
                    UnitAppearance.EquippedItem equippedItem = Appearance.EquippedItems[i];

                    if (_TestBit(Bits.Bit0FEquippedItemUnknown))
                    {
                        _bitBuffer.WriteInt32(equippedItem.Unknown0F);
                    }

                    _bitBuffer.WriteUInt16(equippedItem.ItemCode);

                    if (_TestBit(Bits.Bit22EquippedItemRowIndex))
                    {
                        _bitBuffer.WriteBitsShift(equippedItem.ItemRowIndex, 8);
                    }

                    if (_TestBit(Bits.Bit18EquippedItemAffix))
                    {
                        int bitCount = (_version > 0xC0) ? 4 : 3;
                        int affixCount = equippedItem.AffixCodes.Count;
                        _bitBuffer.WriteBits(affixCount, bitCount);
                        for (int j = 0; j < affixCount; j++)
                        {
                            _bitBuffer.WriteBits(equippedItem.AffixCodes[j], 32);
                        }
                    }
                }

                _bitBuffer.WriteBits(Appearance.ArmorColorSetCode, 16);

                if (_TestBit(Bits.Bit16AppearanceUnknown64Bits))
                {
                    _bitBuffer.WriteNonStandardFunc(Appearance.Unknown16);
                }

                if (_TestBit(Bits.Bit23AppearanceUnknownColorSetCode))
                {
                    _bitBuffer.WriteInt16(Appearance.Unknown23ColorSetsCode);
                }

                if (_TestBit(Bits.Bit11WardrobeLayers))
                {
                    int wardrobeLayerCount = Appearance.WardrobeLayerBases.Count;
                    _bitBuffer.WriteBits(wardrobeLayerCount, 4);
                    for (int i = 0; i < wardrobeLayerCount; i++)
                    {
                        _bitBuffer.WriteBits(Appearance.WardrobeLayerBases[i], 16);
                    }
                }

                int wardrobeAppearanceGroupCount = Appearance.WardrobeAppearanceGroups.Count;
                _bitBuffer.WriteBits(wardrobeAppearanceGroupCount, 3);
                for (int i = 0; i < wardrobeAppearanceGroupCount; i++)
                {
                    _bitBuffer.WriteBits(Appearance.WardrobeAppearanceGroups[i], 16);
                }

                int colorPaletteCount = Appearance.ColorPaletteIndicies.Count;
                _bitBuffer.WriteBits(colorPaletteCount, 4);
                for (int i = 0; i < colorPaletteCount; i++)
                {
                    _bitBuffer.WriteBits(Appearance.ColorPaletteIndicies[i], 8);
                }

                if (_TestBit(Bits.Bit10LayerAppearances))
                {
                    _bitBuffer.WriteBits(Appearance.LayerAppearanceCount, 16);
                    for (int i = 0; i < Appearance.LayerAppearanceCount; i++)
                    {
                        _bitBuffer.WriteBits(Appearance.LayerAppearances[i].WardrobeLayerCode, 16);
                        _bitBuffer.WriteBits(Appearance.LayerAppearances[i].UnknownBool ? 1 : 0, 1);
                        if (Appearance.LayerAppearances[i].UnknownBool)
                        {
                            _bitBuffer.WriteBits(Appearance.LayerAppearances[i].UnknownBoolValue, 2);
                        }
                    }
                }
            }

            if (_TestBit(Bits.Bit12Items))
            {
                int itemBitOffset = _bitBuffer.BitOffset;
                _bitBuffer.WriteBits(0x00000000, 32);

                int itemCount = Items.Count;
                _bitBuffer.WriteBits(itemCount, 10);
                for (int i = 0; i < itemCount; i++)
                {
                    Items[i]._WriteUnit(itemsBitField, itemsContext, itemsBitField, itemsContext, statContext, _bitBuffer);
                }

                _bitBuffer.WriteBits(_bitBuffer.BitOffset, 32, itemBitOffset);
            }

            if (_TestBit(Bits.Bit1AHotkeys))
            {
                if (bitOffsetHotkeys > 0)
                {
                    _bitBuffer.WriteBits(_bitBuffer.BitOffset, 32, bitOffsetHotkeys);
                }

                _bitBuffer.WriteUInt32(HotkeysMagicWord);

                int endFlagBitOffset = _bitBuffer.BitOffset;
                _bitBuffer.WriteBits(0x00000000, 32);

                int weaponConfigCount = Hotkeys.Count;
                _bitBuffer.WriteBits(weaponConfigCount, 6);
                foreach (Hotkey hotkey in Hotkeys)
                {
                    _bitBuffer.WriteBits(hotkey.Code, 16);
                    _bitBuffer.WriteBits(hotkey.UnknownCount, 4);
                    for (int i = 0; i < hotkey.UnknownCount; i++)
                    {
                        _bitBuffer.WriteBits(hotkey.UnknownExists[i] ? 1 : 0, 1);
                        if (hotkey.UnknownExists[i])
                        {
                            _bitBuffer.WriteBits(hotkey.UnknownValues[i], 32);
                        }
                    }

                    // yes this chunk looks the same as above - the above chunk though is in a specific function and can differ at 1 point
                    // also, it can be != 2
                    _bitBuffer.WriteBits(hotkey.SkillCount, 4);
                    for (int i = 0; i < hotkey.SkillCount; i++)
                    {
                        _bitBuffer.WriteBits(hotkey.SkillExists[i] ? 1 : 0, 1);
                        if (hotkey.SkillExists[i])
                        {
                            _bitBuffer.WriteBits(hotkey.SkillCode[i], 32);
                        }
                    }

                    _bitBuffer.WriteBits(hotkey.UnitTypeCode, 32);
                }

                _bitBuffer.WriteBits(_bitBuffer.BitOffset, 32, endFlagBitOffset);
            }

            _bitBuffer.WriteUInt32(ItemMagicWord); // "`4R+"

            if (_TestBit(Bits.Bit1DBitCountEof))
            {
                _bitBuffer.WriteBits(_bitBuffer.BitOffset - bitCountStart, 32, bitCountEofOffset);
            }
        }
예제 #5
0
 //public WayPointControl(UnitObjectStats.Stat.Values values) : this()
 public WayPointControl(UnitObjectStats.Stat.StatValue values)
     : this()
 {
     wayPointValues = values;
 }
예제 #6
0
        private Skill InitializeSkill(DataTable table, UnitObjectStats.Stat.StatValue skillBlock)
        {
            DataRow[] availableSkillRows = table.Select("code = " + skillBlock.Param1);

            string name = availableSkillRows[0]["displayName_string"].ToString();
            string description = availableSkillRows[0]["descriptionString_string"].ToString();
            string iconName = (string)availableSkillRows[0]["smallIcon"];
            int maxLevel = (int)availableSkillRows[0]["maxLevel"];
            int row = (int)availableSkillRows[0]["skillPageRow"];
            int column = (int)availableSkillRows[0]["skillPageColumn"];

            List<int> requiredSkills = new List<int>();
            List<int> levelsOfRequiredSkills = new List<int>();

            for (int counter = 1; counter < 5; counter++)
            {
                int requiredSkill = (int)availableSkillRows[0]["requiredSkills" + counter];
                if (requiredSkill >= 0)
                {
                    requiredSkills.Add(requiredSkill);
                }
                int requiredLevel = (int)availableSkillRows[0]["levelsOfrequiredSkills" + counter];
                if (requiredLevel >= 0)
                {
                    levelsOfRequiredSkills.Add(requiredLevel);
                }
            }
            return new Skill(name, description, iconName, maxLevel, new Point(column, row), requiredSkills.ToArray(), levelsOfRequiredSkills.ToArray(), skillBlock);
        }
예제 #7
0
        /*
         * This is how the table lookup works:
         * if Attribute1 set -> Attribute1 = tableID && values.Attribute1 set -> values.Attribute1 = codeID
         * if Attribute1 not set -> Resource = tableID && values.Attribute1 set -> values.Attribute1 = codeID
         * if Attribute1 not set -> Resource = tableID && values.Attribute1 not set -> values.stat = codeID
         */
        private void SetStatValues(UnitObjectStats.Stat stat)
        {
            int heightOffset = 0;
            for (int i = 0; i < stat.Length; i++)
            {
                UnitObjectStats.Stat.StatValue statValues = stat[i];

                bool hasExtraAttribute = false;
                string lookUpString;
                for (int j = 0; j < 3; j++)
                {
                    if (stat.GetParamAt(j) == Xls.TableCodes.Null) break;

                    Label eaValueLabel = new Label { Text = "Attr" + j + ": ", Width = 40, Top = 3 + heightOffset };
                    TextBox eaMappingTextBox = new TextBox { Left = eaValueLabel.Right, Top = heightOffset, Width = 80 };
                    TextBox eaValueTextBox = new TextBox { Left = eaValueLabel.Right + eaMappingTextBox.Width };
                    eaValueLabel.Top = heightOffset;
                    eaValueTextBox.Width = 80;

                    if (stat.Name.Equals(ItemValueNames.minigame_category_needed.ToString(), StringComparison.InvariantCultureIgnoreCase))
                    {
                        // checks for minigame entries by using the values as the minigame doesn't define any tables -> Yes it does... needs some reworking
                        lookUpString = GetMinigameGoal(stat.Values[i].Param1, stat.Values[i].Param2);
                    }
                    else
                    {
                        lookUpString = _itemFunctions.MapIdToString(stat, stat.GetParamAt(j), stat.Values[i].GetParamAt(j));
                    }

                    if (lookUpString != string.Empty)
                    {
                        eaMappingTextBox.Text = lookUpString;
                        eaValueTextBox.Text = stat.Values[i].GetParamAt(j).ToString();
                    }
                    else
                    {
                        eaMappingTextBox.DataBindings.Add("Text", statValues, "Attribute" + (j + 1));
                        eaValueTextBox.Text = stat.Values[i].GetParamAt(j).ToString();
                    }

                    panel1.Controls.Add(eaValueLabel);
                    panel1.Controls.Add(eaMappingTextBox);
                    panel1.Controls.Add(eaValueTextBox);

                    heightOffset += 25;
                    hasExtraAttribute = true;
                }

                int leftOffset = 0;
                if (hasExtraAttribute)
                {
                    leftOffset += 35;
                }

                Label valueLabel = new Label { Text = "Value: ", Left = leftOffset, Width = 40, Top = 3 + heightOffset };
                TextBox valueTextBox = new TextBox { Left = valueLabel.Right, Top = heightOffset };

                //lookUpString = _itemFunctions.MapIdToString(stat, stat.Resource, stat.Values[i].Value);
                lookUpString = _itemFunctions.MapIdToString(stat, stat.Param1TableCode, stat.Values[i].Value);
                if (!String.IsNullOrEmpty(lookUpString))
                {
                    valueTextBox.Text = lookUpString;
                }
                else
                {
                    valueTextBox.DataBindings.Add("Text", statValues, "Stat");
                }

                panel1.Controls.Add(valueLabel);
                panel1.Controls.Add(valueTextBox);

                heightOffset += 45;
            }
        }
예제 #8
0
        // not needed anymore (name is obtained automatically)
        //private void GenerateUnitNameStrings(UnitObject[] units, Hashtable hash)
        //{
        //    if (hash == null) hash = new Hashtable();
        //    try
        //    {
        //        UnitObjectStats.Stat stat;
        //        foreach (UnitObject unit in units)
        //        {
        //            for (int counter = 0; counter < unit.Stats.Stats.Count; counter++)
        //            {
        //                stat = unit.Stats.Stats[counter];
        //                String name;
        //                if (hash.Contains(stat.Code))
        //                {
        //                    name = (string)hash[stat.Code];
        //                }
        //                else
        //                {
        //                    DataRow[] statRows = statsTable.Select("code = " + stat.Code);
        //                    name = (string)statRows[0]["stat"];
        //                    if (name != null)
        //                    {
        //                        hash.Add(stat.Code, name);
        //                    }
        //                }
        //                unit.Stats[counter].Name = name;
        //            }
        //            GenerateUnitNameStrings(unit.Items.ToArray(), hash);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        MessageBox.Show(ex.Message, "GenerateUnitNameStrings");
        //    }
        //}
        public string MapIdToString(UnitObjectStats.Stat stat, Xls.TableCodes tableId, int lookupId)
        {
            string value = string.Empty;

            if (stat.Values.Count != 0)
            {
                String select = String.Format("code = '{0}'", lookupId);
                DataTable table = null;// todo: rewrite  _dataSet.GetExcelTableFromCode((uint)tableId);
                DataRow[] row;

                if (table != null)
                {
                    row = table.Select(select);

                    if (row != null && row.Length != 0)
                    {
                        value = (string)row[0][1];
                    }
                }
            }

            return value;
        }
예제 #9
0
 public Skill(string name, string description, string iconName, int maxLevel, Point position, int[] requiredSkills, int[] levelsOfRequiredSkills, UnitObjectStats.Stat.StatValue skillBlock)
 {
     _name = name;
     _description = description;
     _iconName = iconName;
     _maxLevel = maxLevel;
     _position = position;
     _requiredSkills = requiredSkills;
     _levelsOfRequiredSkills = levelsOfRequiredSkills;
     _skillBlock = skillBlock;
 }
예제 #10
0
        public static bool SetComplexValue(UnitObject unit, string valueName, UnitObjectStats.Stat stat)
        {
            //if (!initialized) return;

            foreach (UnitObjectStats.Stat unitStats in unit.Stats.Stats.Values)
            {
                if (unitStats.Name != valueName) continue;

                return true;
            }

            //for (int counter = 0; counter < unit.Stats.Stats.Count; counter++)
            //{
            //    UnitObjectStats.Stat unitStats = unit.Stats[counter];

            //    if (unitStats.Name != valueName) continue;

            //    unitStats = stat;
            //    return true;
            //}

            return false;
        }
예제 #11
0
        private void _WriteStat(BitBuffer bitBuffer, UnitObjectStats statBlock, Stat stat)
        {
            /***** Stat Block *****
             * if (Context == 1)
             * {
             *      RowIndex                                    11                  RowIndex to Stats table - used in MP context.
             * }
             * else
             * {
             *      Code                                        16                  Code from Stats excel table.
             *
             *      ParamsCount                                 2                   Count of following.
             *      {
             *          Exists                                  1                   Simple bool test.
             *          {
             *              ParamBitCount                       6                   Number of bits used in file.
             *
             *              ParamOperationsFlags                2                   Operations to be done to param value
             *              if (ParamOperationsFlags & 0x01)
             *              {
             *                  ParamShift                      3                   Not seen used - but is in ASM.
             *              }
             *              if (ParamOperationsFlags & 0x02)
             *              {
             *                  ParamIsOffset                   1                   Param is offset - unknown usage.
             *              }
             *
             *              NoTableCode                         1                   Bool type.
             *              if (!NoTableCode)
             *              {
             *                  ParamTableCode                  16                  Like StatCode, allows param value to refer to an excel table.
             *              }
             *          }
             *      }
             *
             *      BitCount                                    6                   Number of bits used in file for stat value.
             *
             *      ValueOperationsFlags                        3                   Operations to be performed on stat value.
             *      if (otherAttributeFlag & 0x01)
             *      {
             *          ValueShift                              4                   Value shift - unknown usage. Probably used server-side to allow for greater ranges.
             *      }
             *      if (otherAttributeFlag & 0x02)
             *      {
             *          ValueOffset                             12                  Value if offset. Real value: Value -= ValueOffset;
             *      }
             *      if (otherAttributeFlag & 0x04)
             *      {
             *          ValueIsOffset                           1                   Not to be confused with ValueOffset - IsOffset usage unknown (similar to ParamIsOffset)
             *      }
             *
             *      NoValueTableCode                            2                   ASM only considered 0x00 - any other value and ValueTableCode is not read in.
             *      if (!NoValueTableCode)
             *      {
             *          ValueTableCode                          16                  Allows value to refer to an excel table.
             *      }
             *
             * } // end if (Context == 1)
             *
             *
             * HasMultipleValues                                1                   Bool type.
             * {
             *      ValueCount                                  10                  Number of times to read in stat values.
             * }
             *
             * for (ValueCount)                                                     If HasMultipleValues == false, then obviously we still want to read
             * {                                                                    in at least once... So really it's like a do {} while() chunk.
             *      for (ParamsCount)
             *      {
             *          ParamValue                              ParamBitCount       The extra attribute for the applicable value below.
             *      }
             *
             *      StatValue                                   BitCount            The actual stat value.
             * }
             */

            StatsRow statData = stat.StatRow;
            int valueBitCount;
            int[] paramsBitCounts = new int[MaxParams];

            if (statBlock.Context == StatContext.UseRows)
            {
                valueBitCount = statData.valbits;
                paramsBitCounts[0] = statData.param1Bits; // todo: this could be an issue if we have to write a value greater than the bits can handle
                paramsBitCounts[1] = statData.param2Bits;
                paramsBitCounts[2] = statData.param3Bits;
                paramsBitCounts[3] = statData.param4Bits;

                int rowIndex = _fileManager.GetStatRowIndexFromCode((short) statData.code);
                if (rowIndex == -1) throw new Exceptions.UnitObjectException("Error: Stat row index not found for Stat = " + statData);
                bitBuffer.WriteBits(rowIndex, 11);

                if (statData.ParamCount > 0) bitBuffer.WriteBool(true);
                if (statData.ParamCount > 1) bitBuffer.WriteBool(true);
                if (statData.ParamCount > 2) bitBuffer.WriteBool(true);
                if (statData.ParamCount > 3) bitBuffer.WriteBool(true);
            }
            else
            {
                valueBitCount = (statData.valTable == -1) ? statData.valbits : 32;  // on sp side - the bit count is equal to the bit count of the code field (32 for int, 16 for short, etc), but this will do
                paramsBitCounts[0] = (statData.param1Table == -1) ? statData.param1Bits : 32; // todo: this could be an issue if we have to write a value greater than the bits can handle
                paramsBitCounts[1] = (statData.param2Table == -1) ? statData.param2Bits : 32;
                paramsBitCounts[2] = (statData.param3Table == -1) ? statData.param3Bits : 32;
                paramsBitCounts[3] = (statData.param4Table == -1) ? statData.param4Bits : 32;

                bitBuffer.WriteUInt16((uint)statData.code);
                bitBuffer.WriteBits(statData.ParamCount, 2);

                if (statData.ParamCount > 0) _WriteStatParamData(bitBuffer, paramsBitCounts[0], statData.param1Shift, statData.param1Offs != 0, stat.Param1TableCode);
                if (statData.ParamCount > 1) _WriteStatParamData(bitBuffer, paramsBitCounts[1], statData.param2Shift, statData.param2Offs != 0, stat.Param2TableCode);
                if (statData.ParamCount > 2) _WriteStatParamData(bitBuffer, paramsBitCounts[2], statData.param3Shift, statData.param3Offs != 0, stat.Param3TableCode);
                if (statData.ParamCount > 3) _WriteStatParamData(bitBuffer, paramsBitCounts[3], statData.param4Shift, statData.param4Offs != 0, stat.Param4TableCode);

                bitBuffer.WriteBits(valueBitCount, 6);

                int valueOperationsFlags = 0;
                if (stat.StatRow.valShift > 0) valueOperationsFlags |= 0x01;
                if (stat.StatRow.valOffs > 0) valueOperationsFlags |= 0x02;
                if (stat.StatRow.offset > 0) valueOperationsFlags |= 0x04;

                bitBuffer.WriteBits(valueOperationsFlags, 3);
                if ((valueOperationsFlags & 0x01) != 0)
                {
                    bitBuffer.WriteBits(stat.StatRow.valShift, 4);
                }
                if ((valueOperationsFlags & 0x02) != 0)
                {
                    bitBuffer.WriteBits(stat.StatRow.valOffs, 12);
                }
                if ((valueOperationsFlags & 0x04) != 0)
                {
                    bitBuffer.WriteBool(true);
                }

                int noValueTableCode = (stat.ValueTable != null) ? 0 : 1;
                bitBuffer.WriteBits(noValueTableCode, 2);
                if (stat.ValueTable != null)
                {
                    bitBuffer.WriteUInt16((uint)stat.ValueTableCode);
                }
            }

            int valueCount = stat.Values.Count;
            bool hasMultipleValues = (valueCount > 1);

            bitBuffer.WriteBool(hasMultipleValues);
            if (hasMultipleValues)
            {
                int valueCountBits = (statBlock._version <= 7) ? 7 : 10;
                bitBuffer.WriteBits(valueCount, valueCountBits);
            }

            foreach (Stat.StatValue statValue in stat.Values)
            {
                if (statData.ParamCount >= 1) _WriteStatValue(bitBuffer, statValue.Param1, statValue.Param1Row, stat.Param1Table, paramsBitCounts[0], statBlock.Context);
                if (statData.ParamCount >= 2) _WriteStatValue(bitBuffer, statValue.Param2, statValue.Param2Row, stat.Param2Table, paramsBitCounts[1], statBlock.Context);
                if (statData.ParamCount >= 3) _WriteStatValue(bitBuffer, statValue.Param3, statValue.Param3Row, stat.Param3Table, paramsBitCounts[2], statBlock.Context);
                if (statData.ParamCount >= 4) _WriteStatValue(bitBuffer, statValue.Param4, statValue.Param4Row, stat.Param4Table, paramsBitCounts[3], statBlock.Context);

                int valueOffset = (stat.StatRow.valOffs + stat.StatRow.offset);
                int valueShift = (stat.StatRow.valShift - stat.StatRow.shift);

                statValue.Value += valueOffset;
                statValue.Value >>= valueShift;

                _WriteStatValue(bitBuffer, statValue.Value, statValue.ValueRow, stat.ValueTable, valueBitCount, statBlock.Context);
            }
        }
예제 #12
0
        private Stat _ReadStat(BitBuffer bitBuffer, UnitObjectStats statBlock)
        {
            Stat stat = new Stat();

            int statIndex = statBlock.Stats.Count;
            int valueShift = 0;
            int valueOffset = 0;
            bool isOffset = false;
            StatsRow statData;

            int valueBitCount;
            int[] paramsBitCounts = new int[MaxParams];

            if (statBlock.Context == StatContext.UseRows)
            {
                int rowIndex = bitBuffer.ReadBits(11); // todo: make this a static value - this bit count is determined by FileManager._GetTableRowBitMax() of the Stats row count
                statData = stat.StatRow = _fileManager.GetStatRowFromIndex(rowIndex);
                if (statData == null) throw new Exceptions.UnitObjectException(String.Format("Error stats[{0}].RowIndex = {1} not found.\nCannot have null stat - not known param count will break bit offset.", statIndex, rowIndex));
                valueBitCount = statData.valbits;

                if (statData.ParamCount > 0 && bitBuffer.ReadBool()) paramsBitCounts[0] = statData.param1Bits;
                if (statData.ParamCount > 1 && bitBuffer.ReadBool()) paramsBitCounts[1] = statData.param2Bits;
                if (statData.ParamCount > 2 && bitBuffer.ReadBool()) paramsBitCounts[2] = statData.param3Bits;
                if (statData.ParamCount > 3 && bitBuffer.ReadBool()) paramsBitCounts[3] = statData.param4Bits;

                if (_debugOutputLoadingProgress)
                {
                    Debug.WriteLine(String.Format("stats[{0}].Name = {1}, .Code = {2} (0x{3:X4}), .ParamCount = {4}", statIndex, stat.Name, stat.Code, (uint)stat.Code, statData.ParamCount));

                    Xls.TableCodes tableCode = (stat.ValueTable == null) ? Xls.TableCodes.Null : stat.ValueTable.TableCode;
                    int noValueTableCode = (stat.ValueTable == null) ? 1 : 0;
                    Debug.WriteLine(String.Format("stats[{0}].NoValueTableCode = {1}, .ValueTableCode = 0x{2:X4}, .ValueTable = {3}", statIndex, noValueTableCode, (uint)tableCode, tableCode));

                    if (statData.ParamCount >= 1) Debug.WriteLine(String.Format("stats[{0}].Param1.BitCount = {1}, .Table = {2}", statIndex, paramsBitCounts[0], stat.Param1TableCode));
                    if (statData.ParamCount >= 2) Debug.WriteLine(String.Format("stats[{0}].Param2.BitCount = {1}, .Table = {2}", statIndex, paramsBitCounts[1], stat.Param2TableCode));
                    if (statData.ParamCount >= 3) Debug.WriteLine(String.Format("stats[{0}].Param3.BitCount = {1}, .Table = {2}", statIndex, paramsBitCounts[2], stat.Param3TableCode));
                    if (statData.ParamCount >= 4) Debug.WriteLine(String.Format("stats[{0}].Param4.BitCount = {1}, .Table = {2}", statIndex, paramsBitCounts[3], stat.Param4TableCode));
                }
            }
            else
            {
                ushort code = bitBuffer.ReadUInt16();
                statData = stat.StatRow = _fileManager.GetStatRowFromCode((short)code);
                if (stat.StatRow == null) throw new Exceptions.UnitObjectException(String.Format("Error: stat.Code = {0} (0x{0:X4}) not found.\nCannot have null stat - not known param count will break bit offset.", code));

                int paramsCount = bitBuffer.ReadBits(2);
                if (_debugOutputLoadingProgress)
                {
                    Debug.WriteLine(String.Format("stats[{0}].Name = {1}, stat.Code = {2} (0x{3:X4}), stat.ParamCount = {4}", statIndex, stat.Name, code, (uint)code, paramsCount));
                }
                if (paramsCount > statData.ParamCount) Debug.WriteLine(String.Format("Unexpected large params count of {0}. Expecting count <= {1}", paramsCount, statData.ParamCount));

                for (int i = 0; i < paramsCount; i++)
                {
                    bool exists = bitBuffer.ReadBool();
                    if (!exists) continue;

                    paramsBitCounts[i] = bitBuffer.ReadBits(6);

                    int paramOperationsFlags = bitBuffer.ReadBits(2);
                    int paramShift = 0;
                    bool paramIsOffset = false;
                    if ((paramOperationsFlags & 0x01) != 0)
                    {
                        paramShift = bitBuffer.ReadBits(3);
                    }
                    if ((paramOperationsFlags & 0x02) != 0)
                    {
                        paramIsOffset = bitBuffer.ReadBool();
                    }

                    bool hasTableCode = !bitBuffer.ReadBool();
                    Xls.TableCodes paramTableCode = Xls.TableCodes.Null;
                    if (hasTableCode)
                    {
                        paramTableCode = (Xls.TableCodes)bitBuffer.ReadUInt16();

                        Xls.TableCodes expetedTableCode = Xls.TableCodes.Null;
                        switch (i)
                        {
                            case 0: expetedTableCode = stat.Param1TableCode; break;
                            case 1: expetedTableCode = stat.Param2TableCode; break;
                            case 2: expetedTableCode = stat.Param3TableCode; break;
                            case 3: expetedTableCode = stat.Param4TableCode; break;
                        }

                        if (expetedTableCode != paramTableCode) throw new Exceptions.UnitObjectException(String.Format("Unexpected param value table supplied. Expecting {0}, got {1}", expetedTableCode, paramTableCode));
                    }

                    if (_debugOutputLoadingProgress)
                    {
                        Debug.WriteLine(String.Format("stats[{0}].Param{1}.BitCount = {2}, .ParamOperationsFlags = {3}, .ParamShift = {4}, .ParamIsOffset = {5}, .HasTableCode = {6}, .TableCode = {7}, .Table = {8}",
                            statIndex, i, paramsBitCounts[i], paramOperationsFlags, paramShift, paramIsOffset, hasTableCode, (uint)paramTableCode, paramTableCode));
                    }
                }

                valueBitCount = bitBuffer.ReadBits(6);

                int valueOperationsFlags = bitBuffer.ReadBits(3);
                if ((valueOperationsFlags & 0x01) != 0)
                {
                    valueShift = bitBuffer.ReadBits(4); // valShift
                }
                if ((valueOperationsFlags & 0x02) != 0)
                {
                    valueOffset = bitBuffer.ReadBits(12); // valOffset
                }
                if ((valueOperationsFlags & 0x04) != 0)
                {
                    isOffset = bitBuffer.ReadBool();
                }
                if (_debugOutputLoadingProgress)
                {
                    Debug.WriteLine(String.Format("stats[{0}].BitCount = {1}, .ValueOperationsFlags = {2}, .ValueShift = {3}, .ValueOffset = {4}, .IsOffset = {5}",
                        statIndex, valueBitCount, valueOperationsFlags, valueShift, valueOffset, isOffset));
                }

                int noValueTableCode = bitBuffer.ReadBits(2);
                Debug.Assert(noValueTableCode != 2); // never seen... seen in stats column in Monsters table

                Xls.TableCodes tableCode = Xls.TableCodes.Null;
                if (noValueTableCode == 0)
                {
                    tableCode = (Xls.TableCodes)bitBuffer.ReadUInt16();

                    Xls.TableCodes expectedTableCode = stat.ValueTableCode;
                    if (expectedTableCode != tableCode) throw new Exceptions.UnitObjectException(String.Format("Unexpected stat value table supplied. Expecting {0}, got {1}", expectedTableCode, tableCode));
                }
                if (_debugOutputLoadingProgress)
                {
                    Debug.WriteLine(String.Format("stats[{0}].NoValueTableCode = {1}, .ValueTableCode = 0x{2:X4}, .ValueTable = {3}", statIndex, noValueTableCode, (uint)tableCode, tableCode));
                }
            }

            bool hasMultipleValues = bitBuffer.ReadBool();
            int valueCount = 1;
            if (hasMultipleValues)
            {
                int valueCountBits = (statBlock._version <= 7) ? 8 : 10;
                valueCount = bitBuffer.ReadBits(valueCountBits);
            }

            if (_debugOutputLoadingProgress)
            {
                Debug.WriteLine(String.Format("stats[{0}].HasMultipleValues = {1}, .ValueCount = {2}", statIndex, hasMultipleValues, valueCount));
            }

            for (int i = 0; i < valueCount; i++)
            {
                Stat.StatValue statValue = new Stat.StatValue();

                _ReadStatValue(bitBuffer, paramsBitCounts[0], ref statValue.Param1, stat.Param1Table, ref statValue.Param1Row, statBlock.Context);
                _ReadStatValue(bitBuffer, paramsBitCounts[1], ref statValue.Param2, stat.Param2Table, ref statValue.Param2Row, statBlock.Context);
                _ReadStatValue(bitBuffer, paramsBitCounts[2], ref statValue.Param3, stat.Param3Table, ref statValue.Param3Row, statBlock.Context);
                _ReadStatValue(bitBuffer, paramsBitCounts[3], ref statValue.Param4, stat.Param4Table, ref statValue.Param4Row, statBlock.Context);

                _ReadStatValue(bitBuffer, valueBitCount, ref statValue.Value, stat.ValueTable, ref statValue.ValueRow, statBlock.Context);

                // this seems to work
                // todo: do this for writing stats
                if (valueOffset == 0)
                    valueOffset = (stat.StatRow.valOffs + stat.StatRow.offset);
                if (valueShift == 0)
                    valueShift = (stat.StatRow.valShift - stat.StatRow.shift);

                statValue.Value -= valueOffset; // not going to bother with this for now
                statValue.Value <<= valueShift; // not sure what this is for either - possibly server-side to increase accuracy/value range I guess - but values aren't saved with it...
                //if (value.IsOffset) statValue.Value--; // do this to *row index* though, not code - not sure about non-table relations values...

                stat.Values.Add(statValue);

                if (_debugOutputLoadingProgress)
                {
                    if (paramsBitCounts[0] > 0) Debug.WriteLine(String.Format("stats[{0}].Param1 = {1}", statIndex, statValue.Param1));
                    if (paramsBitCounts[1] > 0) Debug.WriteLine(String.Format("stats[{0}].Param2 = {1}", statIndex, statValue.Param2));
                    if (paramsBitCounts[2] > 0) Debug.WriteLine(String.Format("stats[{0}].Param3 = {1}", statIndex, statValue.Param3));
                    if (paramsBitCounts[3] > 0) Debug.WriteLine(String.Format("stats[{0}].Param4 = {1}", statIndex, statValue.Param4));
                    Debug.WriteLine(String.Format("stats[{0}].Value = {1}", statIndex, statValue.Value));
                }
            }

            return stat;
        }
예제 #13
0
        public void WriteStats(BitBuffer bitBuffer, UnitObjectStats stats, bool writeNameCount = false)
        {
            /***** Stat Block Header *****
             * Version                                          16                  Stat block header - Must be 0x000A.
             * Context                                          3                   Use 0 for Code usage, 1 for RowIndex usage, 2 for... ?
             *
             * StatSelectorCount                                6                   Not sure of use - but uses StatSelector table
             * {
             *      Code                                        16                  Code from StatSelector table     (if Context != 1)
             *      RowIndex                                    5                   RowIndex from StatSelector table (if Context == 1)
             *
             *      StatCount                                   16                  Count of following stats.
             *      {
             *          STATS                                                       See WriteStat().
             *      }
             * }
             *
             * StatCount                                        16                  Count of following stats.
             * {
             *      STATS                                                           See WriteStat().
             * }
             *
             * // todo: update me (same StatSelector stuff from above)
             * if (WriteNameCount)                                                  This is TRUE by default. Set to FALSE when writing a stat block
             * {                                                                    from the below name stat block chunk.
             *      NameCount                                   8                   I think this has something to do with item names.
             *      {
             *          Code                                    16                  Code from StatSelector table     (if Context != 1)
             *          RowIndex                                5                   RowIndex from StatSelector table (if Context == 1)
             *
             *          STAT BLOCK                                                  See WriteStatBlock().
             *      }
             * }
             */

            bitBuffer.WriteBits(stats._version, 16);
            bitBuffer.WriteBits((int)stats.Context, 3);

            bitBuffer.WriteBits(stats.StatSelectors.Count, 6);
            foreach (StatSelector statSelector in stats.StatSelectors)
            {
                if (stats.Context == StatContext.UseRows)
                {
                    bitBuffer.WriteBits(statSelector.RowIndex, 5);
                }
                else
                {
                    bitBuffer.WriteUInt16(statSelector.Code);
                }

                bitBuffer.WriteBits(statSelector.Stats.Count, 16);
                foreach (Stat stat in statSelector.Stats)
                {
                    _WriteStat(bitBuffer, stats, stat);
                }
            }

            bitBuffer.WriteBits(stats.Stats.Count, 16);

            foreach (Stat stat in stats.Stats.Values.OrderBy(stat => stat.Code))
            {
                _WriteStat(bitBuffer, stats, stat);
            }

            if (!writeNameCount) return;

            bitBuffer.WriteBits(stats.Names.Count, 8);
            foreach (StatName statName in stats.Names)
            {
                bitBuffer.WriteBits(statName.Unknown1, 16);
                WriteStats(bitBuffer, statName.Stats, false);
            }
        }
예제 #14
0
        /// <summary>
        /// Read stats from a serialised byte array
        /// </summary>
        /// <param name="bitBuffer">The current buffer state.</param>
        /// <param name="stats">The stats block to populate.</param>
        /// <param name="readNameCount">TODO</param>
        public void ReadStats(BitBuffer bitBuffer, UnitObjectStats stats, bool readNameCount = false)
        {
            stats._version = bitBuffer.ReadBits(16);
            stats.Context = (StatContext)bitBuffer.ReadBits(3);
            if (_debugOutputLoadingProgress)
            {
                Debug.WriteLine(String.Format("stats.Version = {0}, stats.Context = {1} (0x{2:X2})", stats._version, stats.Context, (int)stats.Context));
            }
            if (stats._version != 0x0A)
            {
                throw new Exceptions.NotSupportedVersionException("0x0A", "0x" + stats._version.ToString("X2"));
            }

            int statSelectorCount = bitBuffer.ReadBits(6);
            if (_debugOutputLoadingProgress)
            {
                Debug.WriteLine(String.Format("stats.StatSelectorCount = {0}", statSelectorCount));
            }
            for (int i = 0; i < statSelectorCount; i++)
            {
                StatSelector statSelector = new StatSelector();

                if (stats.Context == StatContext.UseRows)
                {
                    statSelector.RowIndex = bitBuffer.ReadBits(5);
                    statSelector.StatSelectorRow = (ExcelTablesRow)_fileManager.GetRowFromIndex(Xls.TableCodes.STATS_SELECTOR, statSelector.RowIndex); // StatsSelector table
                }
                else
                {
                    statSelector.Code = bitBuffer.ReadUInt16();
                    statSelector.StatSelectorRow = (ExcelTablesRow)_fileManager.GetRowFromCode(Xls.TableCodes.STATS_SELECTOR, (short)statSelector.Code); // StatsSelector table
                }

                int selectorStatCount = bitBuffer.ReadInt16();
                if (_debugOutputLoadingProgress)
                {
                    Debug.WriteLine(String.Format("StatSelectors[{0}].Name = {1}, .Code = 0x{2:X4}, .RowIndex = {3}, .StatCount = {4}",
                        i, statSelector.Name, statSelector.Code, statSelector.RowIndex, selectorStatCount));
                }

                for (int j = 0; j < selectorStatCount; j++)
                {
                    Stat stat = _ReadStat(bitBuffer, stats);
                    statSelector.Stats.Add(stat);
                }

                stats.StatSelectors.Add(statSelector);
            }

            int statCount = bitBuffer.ReadBits(16);
            if (_debugOutputLoadingProgress)
            {
                Debug.WriteLine(String.Format("stats.StatCount = {0}", statCount));
            }
            for (int i = 0; i < statCount; i++)
            {
                Stat stat = _ReadStat(bitBuffer, stats);
                stats.Stats[stat.StatRow.code] = stat;
            }

            if (!readNameCount) return;
            stats.NameCount = bitBuffer.ReadBits(8);
            if (_debugOutputLoadingProgress)
            {
                Debug.WriteLine(String.Format("stats.NameCount = {0}", stats.NameCount));
            }

            for (int i = 0; i < stats.NameCount; i++)
            {
                StatName name = new StatName
                {
                    Unknown1 = (short)bitBuffer.ReadBits(5),
                    Stats = new UnitObjectStats(_fileManager, _version)
                };
                if (_debugOutputLoadingProgress)
                {
                    Debug.WriteLine(String.Format("stats.Unknown1 = {0}", name.Unknown1));
                }

                ReadStats(bitBuffer, name.Stats, false);
                stats.Names.Add(name);
            }
        }