HuffmanTree::HuffmanTree(uint64_t symbols, uint64_t *bits, uint64_t len) { _symbols = symbols; BitReader reader = BitReader(bits, len); uint64_t w = 0; uint64_t s_size = _symbols - 1; while (s_size) { w++; s_size >>= 1; } uint64_t pos = 0; vector<HuffmanTreeNode *> stack; stack.reserve(symbols); while (pos < len) { uint64_t bit; reader.read(&bit, 1); pos++; HuffmanTreeNode *node; if (bit) { // leaf node uint64_t symbol; reader.read(&symbol, w); pos += w; node = new HuffmanTreeNode(symbol, 0); _leaves[symbol] = node; } else { // internal node node = new HuffmanTreeNode(); } if (!stack.empty()) { HuffmanTreeNode *&back = stack.back(); if (!back->_left) { back->setLeft(node); } else if (!back->_right) { back->setRight(node); stack.pop_back(); } } else { _root = node; } if (!bit) { stack.push_back(node); } } }
bool ProcessStat(unsigned int stat, BitReader &reader, ItemProperty &itemProp) { if (stat > STAT_MAX) { return false; } StatProperties *bits = GetStatProperties(stat); unsigned int saveBits = bits->saveBits; unsigned int saveParamBits = bits->saveParamBits; unsigned int saveAdd = bits->saveAdd; itemProp.stat = stat; if (saveParamBits > 0) { switch (stat) { case STAT_CLASSSKILLS: { itemProp.characterClass = reader.read(saveParamBits); itemProp.value = reader.read(saveBits); return true; } case STAT_NONCLASSSKILL: case STAT_SINGLESKILL: { itemProp.skill = reader.read(saveParamBits); itemProp.value = reader.read(saveBits); return true; } case STAT_ELEMENTALSKILLS: { ulong element = reader.read(saveParamBits); itemProp.value = reader.read(saveBits); return true; } case STAT_AURA: { itemProp.skill = reader.read(saveParamBits); itemProp.value = reader.read(saveBits); return true; } case STAT_REANIMATE: { itemProp.monster = reader.read(saveParamBits); itemProp.value = reader.read(saveBits); return true; } case STAT_SKILLTAB: { itemProp.tab = reader.read(3); itemProp.characterClass = reader.read(3); ulong unknown = reader.read(10); itemProp.value = reader.read(saveBits); return true; } case STAT_SKILLONDEATH: case STAT_SKILLONHIT: case STAT_SKILLONKILL: case STAT_SKILLONLEVELUP: case STAT_SKILLONSTRIKING: case STAT_SKILLWHENSTRUCK: { itemProp.level = reader.read(6); itemProp.skill = reader.read(10); itemProp.skillChance = reader.read(saveBits); return true; } case STAT_CHARGED: { itemProp.level = reader.read(6); itemProp.skill = reader.read(10); itemProp.charges = reader.read(8); itemProp.maximumCharges = reader.read(8); return true; } case STAT_STATE: case STAT_ATTCKRTNGVSMONSTERTYPE: case STAT_DAMAGETOMONSTERTYPE: { // For some reason heroin_glands doesn't read these, even though // they have saveParamBits; maybe they don't occur in practice? itemProp.value = reader.read(saveBits) - saveAdd; return true; } default: reader.read(saveParamBits); reader.read(saveBits); return true; } } if (bits->op >= 2 && bits->op <= 5) { itemProp.perLevel = reader.read(saveBits); return true; } switch (stat) { case STAT_ENHANCEDMAXIMUMDAMAGE: case STAT_ENHANCEDMINIMUMDAMAGE: { itemProp.minimum = reader.read(saveBits); itemProp.maximum = reader.read(saveBits); return true; } case STAT_MINIMUMFIREDAMAGE: { itemProp.minimum = reader.read(saveBits); itemProp.maximum = reader.read(GetStatProperties(STAT_MAXIMUMFIREDAMAGE)->saveBits); return true; } case STAT_MINIMUMLIGHTNINGDAMAGE: { itemProp.minimum = reader.read(saveBits); itemProp.maximum = reader.read(GetStatProperties(STAT_MAXIMUMLIGHTNINGDAMAGE)->saveBits); return true; } case STAT_MINIMUMMAGICALDAMAGE: { itemProp.minimum = reader.read(saveBits); itemProp.maximum = reader.read(GetStatProperties(STAT_MAXIMUMMAGICALDAMAGE)->saveBits); return true; } case STAT_MINIMUMCOLDDAMAGE: { itemProp.minimum = reader.read(saveBits); itemProp.maximum = reader.read(GetStatProperties(STAT_MAXIMUMCOLDDAMAGE)->saveBits); itemProp.length = reader.read(GetStatProperties(STAT_COLDDAMAGELENGTH)->saveBits); return true; } case STAT_MINIMUMPOISONDAMAGE: { itemProp.minimum = reader.read(saveBits); itemProp.maximum = reader.read(GetStatProperties(STAT_MAXIMUMPOISONDAMAGE)->saveBits); itemProp.length = reader.read(GetStatProperties(STAT_POISONDAMAGELENGTH)->saveBits); return true; } case STAT_REPAIRSDURABILITY: case STAT_REPLENISHESQUANTITY: { itemProp.value = reader.read(saveBits); return true; } default: { itemProp.value = reader.read(saveBits) - saveAdd; return true; } } }