예제 #1
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);
            }
        }
예제 #2
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);
            }
        }
예제 #3
0
        private static void _WriteStatParamData(BitBuffer bitBuffer, int bitCount, int paramShift, bool paramIsOffset, Xls.TableCodes tableCode)
        {
            if (bitCount <= 0)
            {
                bitBuffer.WriteBool(false);
                return;
            }

            bitBuffer.WriteBool(true);

            bitBuffer.WriteBits(bitCount, 6);

            int paramOperationsFlags = 0;
            if (paramShift > 0) paramOperationsFlags |= 0x01;
            if (paramIsOffset) paramOperationsFlags |= 0x02;

            bitBuffer.WriteBits(paramOperationsFlags, 2);
            if ((paramOperationsFlags & 0x01) != 0)
            {
                bitBuffer.WriteBits(paramShift, 3);
            }
            if ((paramOperationsFlags & 0x02) != 0)
            {
                bitBuffer.WriteBool(paramIsOffset);
            }

            bool hasTableCode = (tableCode != Xls.TableCodes.Null && tableCode != Xls.TableCodes.None);

            bitBuffer.WriteBool(!hasTableCode);
            if (hasTableCode)
            {
                bitBuffer.WriteUInt16((uint)tableCode);
            }
        }
예제 #4
0
        private void _WriteStatValue(BitBuffer bitBuffer, int value, Object valueRow, ExcelFile valueTable, int bitCount, StatContext statContext)
        {
            if (bitCount <= 0) return;

            if (valueTable == null)
            {
                bitBuffer.WriteBits(value, bitCount);
                return;
            }

            if (valueRow == null)
            {
                bitBuffer.WriteBits(0, bitCount);
                return;
            }

            if (statContext == StatContext.UseRows)
            {
                int rowIndex = valueTable.Rows.IndexOf(valueRow);
                bitBuffer.WriteBits(rowIndex, bitCount);
            }
            else
            {
                int code = _fileManager.GetCodeFromRow(valueTable.TableCode, valueRow);
                bitBuffer.WriteBits(code, bitCount);
            }
        }