void cEnchantments::ParseFromNBT(const cParsedNBT & a_NBT, int a_EnchListTagIdx) { // Read the enchantments from the specified NBT list tag (ench or StoredEnchantments) // Verify that the tag is a list: if (a_NBT.GetType(a_EnchListTagIdx) != TAG_List) { LOGWARNING("%s: Invalid EnchListTag type: exp %d, got %d. Enchantments not parsed", __FUNCTION__, TAG_List, a_NBT.GetType(a_EnchListTagIdx) ); ASSERT(!"Bad EnchListTag type"); return; } // Verify that the list is of Compounds: if (a_NBT.GetChildrenType(a_EnchListTagIdx) != TAG_Compound) { LOGWARNING("%s: Invalid NBT list children type: exp %d, got %d. Enchantments not parsed", __FUNCTION__, TAG_Compound, a_NBT.GetChildrenType(a_EnchListTagIdx) ); ASSERT(!"Bad EnchListTag children type"); return; } Clear(); // Iterate over all the compound children, parse an enchantment from each: for (int tag = a_NBT.GetFirstChild(a_EnchListTagIdx); tag >= 0; tag = a_NBT.GetNextSibling(tag)) { // tag is the compound inside the "ench" list tag ASSERT(a_NBT.GetType(tag) == TAG_Compound); // Search for the id and lvl tags' values: int id = -1, lvl = -1; for (int ch = a_NBT.GetFirstChild(tag); ch >= 0; ch = a_NBT.GetNextSibling(ch)) { if (a_NBT.GetType(ch) != TAG_Short) { continue; } if (a_NBT.GetName(ch) == "id") { id = a_NBT.GetShort(ch); } else if (a_NBT.GetName(ch) == "lvl") { lvl = a_NBT.GetShort(ch); } } // for ch - children of the compound tag if ((id == -1) || (lvl <= 0)) { // Failed to parse either the id or the lvl, skip this compound continue; } // Store the enchantment: m_Enchantments[id] = lvl; } // for tag - children of the ench list tag }
void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNBT & a_NBT, int a_TagIdx, const ENUM_ITEM_ID a_Type) { if (a_TagIdx < 0) { return; } switch (a_Type) { case E_ITEM_FIREWORK_STAR: { for (int explosiontag = a_NBT.GetFirstChild(a_TagIdx); explosiontag >= 0; explosiontag = a_NBT.GetNextSibling(explosiontag)) { eTagType TagType = a_NBT.GetType(explosiontag); if (TagType == TAG_Byte) // Custon name tag { AString ExplosionName = a_NBT.GetName(explosiontag); if (ExplosionName == "Flicker") { a_FireworkItem.m_HasFlicker = (a_NBT.GetByte(explosiontag) == 1); } else if (ExplosionName == "Trail") { a_FireworkItem.m_HasTrail = (a_NBT.GetByte(explosiontag) == 1); } else if (ExplosionName == "Type") { a_FireworkItem.m_Type = a_NBT.GetByte(explosiontag); } } else if (TagType == TAG_IntArray) { AString ExplosionName = a_NBT.GetName(explosiontag); if (ExplosionName == "Colors") { // Divide by four as data length returned in bytes int DataLength = a_NBT.GetDataLength(explosiontag); // round to the next highest multiple of four DataLength -= DataLength % 4; if (DataLength == 0) { continue; } const char * ColourData = (a_NBT.GetData(explosiontag)); for (int i = 0; i < DataLength; i += 4 /* Size of network int*/) { a_FireworkItem.m_Colours.push_back(GetBEInt(ColourData + i)); } } else if (ExplosionName == "FadeColors") { int DataLength = a_NBT.GetDataLength(explosiontag) / 4; // round to the next highest multiple of four DataLength -= DataLength % 4; if (DataLength == 0) { continue; } const char * FadeColourData = (a_NBT.GetData(explosiontag)); for (int i = 0; i < DataLength; i += 4 /* Size of network int*/) { a_FireworkItem.m_FadeColours.push_back(GetBEInt(FadeColourData + i)); } } } } break; } case E_ITEM_FIREWORK_ROCKET: { for (int fireworkstag = a_NBT.GetFirstChild(a_TagIdx); fireworkstag >= 0; fireworkstag = a_NBT.GetNextSibling(fireworkstag)) { eTagType TagType = a_NBT.GetType(fireworkstag); if (TagType == TAG_Byte) // Custon name tag { if (a_NBT.GetName(fireworkstag) == "Flight") { a_FireworkItem.m_FlightTimeInTicks = a_NBT.GetByte(fireworkstag) * 20; } } else if ((TagType == TAG_List) && (a_NBT.GetName(fireworkstag) == "Explosions")) { int ExplosionsChild = a_NBT.GetFirstChild(fireworkstag); if ((a_NBT.GetType(ExplosionsChild) == TAG_Compound) && (a_NBT.GetName(ExplosionsChild).empty())) { ParseFromNBT(a_FireworkItem, a_NBT, ExplosionsChild, E_ITEM_FIREWORK_STAR); } } } break; } default: ASSERT(!"Unhandled firework item!"); break; } }