コード例 #1
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;
        }
コード例 #2
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);
            }
        }