diff --git a/changelog.txt b/changelog.txt index c4eff06b3..1bc585aa1 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 05/08/2016 == +Uleat: Re-coded Titanium client translator 'SerializeItem()' to use coded property assignments over file enumerated ones + == 04/22/2016 == Uleat: Reworked ClientVersion into namespace EQEmu; Added InventoryVersion Uleat: Delinked current inventory slot enumeration and constants from EQEmu::constants and global definition (inv2 pre-work) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 12b656716..6c13aefbc 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -202,13 +202,13 @@ SET(common_headers patches/patches.h patches/sod.h patches/sod_constants.h - patches/sod_itemfields.h +# patches/sod_itemfields.h patches/sod_ops.h patches/sod_structs.h patches/sof.h patches/sof_constants.h - patches/sof_itemfields.h - patches/sof_opcode_list.h +# patches/sof_itemfields.h +# patches/sof_opcode_list.h patches/sof_ops.h patches/sof_structs.h patches/ss_declare.h @@ -216,23 +216,23 @@ SET(common_headers patches/ss_register.h patches/rof.h patches/rof_constants.h - patches/rof_itemfields.h +# patches/rof_itemfields.h patches/rof_ops.h patches/rof_structs.h patches/rof2.h patches/rof2_constants.h - patches/rof2_itemfields.h +# patches/rof2_itemfields.h patches/rof2_ops.h patches/rof2_structs.h patches/titanium.h patches/titanium_constants.h - patches/titanium_itemfields_a.h - patches/titanium_itemfields_b.h +# patches/titanium_itemfields_a.h +# patches/titanium_itemfields_b.h patches/titanium_ops.h patches/titanium_structs.h patches/uf.h patches/uf_constants.h - patches/uf_itemfields.h +# patches/uf_itemfields.h patches/uf_ops.h patches/uf_structs.h SocketLib/Base64.h @@ -255,13 +255,13 @@ SET(common_headers SOURCE_GROUP(Patches FILES patches/patches.h patches/sod.h - patches/sod_itemfields.h +# patches/sod_itemfields.h patches/sod_ops.h patches/sod_constants.h patches/sod_structs.h patches/sof.h - patches/sof_itemfields.h - patches/sof_opcode_list.h +# patches/sof_itemfields.h +# patches/sof_opcode_list.h patches/sof_ops.h patches/sof_constants.h patches/sof_structs.h @@ -269,23 +269,23 @@ SOURCE_GROUP(Patches FILES patches/ss_define.h patches/ss_register.h patches/rof.h - patches/rof_itemfields.h +# patches/rof_itemfields.h patches/rof_ops.h patches/rof_constants.h patches/rof_structs.h patches/rof2.h - patches/rof2_itemfields.h +# patches/rof2_itemfields.h patches/rof2_ops.h patches/rof2_constants.h patches/rof2_structs.h patches/titanium.h - patches/titanium_itemfields_a.h - patches/titanium_itemfields_b.h +# patches/titanium_itemfields_a.h +# patches/titanium_itemfields_b.h patches/titanium_ops.h patches/titanium_constants.h patches/titanium_structs.h patches/uf.h - patches/uf_itemfields.h +# patches/uf_itemfields.h patches/uf_ops.h patches/uf_constants.h patches/uf_structs.h diff --git a/common/patches/titanium.cpp b/common/patches/titanium.cpp index cb291150c..a8a25fd13 100644 --- a/common/patches/titanium.cpp +++ b/common/patches/titanium.cpp @@ -20,7 +20,7 @@ namespace Titanium static OpcodeManager *opcodes = nullptr; static Strategy struct_strategy; - char* SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint8 depth); + std::string SerializeItem(const ItemInst *inst, int16 slot_id_in, uint8 depth); // server to client inventory location converters static inline int16 ServerToTitaniumSlot(uint32 serverSlot); @@ -275,14 +275,12 @@ namespace Titanium InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer; //do the transform... - int r; std::string serial_string; - for (r = 0; r < itemcount; r++, eq++) { - uint32 length; - char *serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &length, 0); - if (serialized) { - serial_string.append(serialized, length + 1); - safe_delete_array(serialized); + for (int r = 0; r < itemcount; r++, eq++) { + std::string serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, 0); // assumed move operation: string& = string&& + if (!serialized.empty()) { + serial_string.append(serialized); + serial_string.push_back('\0'); } else { Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id); @@ -290,9 +288,10 @@ namespace Titanium } - in->size = serial_string.length(); + // do we need to account for a trailing null escape? + in->size = serial_string.size(); in->pBuffer = new unsigned char[in->size]; - memcpy(in->pBuffer, serial_string.c_str(), serial_string.length()); + memcpy(in->pBuffer, serial_string.c_str(), serial_string.size()); delete[] __emu_buffer; @@ -725,22 +724,21 @@ namespace Titanium ItemPacket_Struct *old_item_pkt = (ItemPacket_Struct *)__emu_buffer; InternalSerializedItem_Struct *int_struct = (InternalSerializedItem_Struct *)(old_item_pkt->SerializedItem); - uint32 length; - char *serialized = SerializeItem((ItemInst *)int_struct->inst, int_struct->slot_id, &length, 0); - - if (!serialized) { + std::string serialized = SerializeItem((ItemInst *)int_struct->inst, int_struct->slot_id, 0); // assumed move operation: string& = string&& + if (serialized.empty()) { Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id); delete in; return; } - in->size = length + 5; // ItemPacketType + Serialization + \0 + + in->size = serialized.size() + 5; // ItemPacketType + Serialization + \0 in->pBuffer = new unsigned char[in->size]; ItemPacket_Struct *new_item_pkt = (ItemPacket_Struct *)in->pBuffer; new_item_pkt->PacketType = old_item_pkt->PacketType; - memcpy(new_item_pkt->SerializedItem, serialized, length + 1); + memcpy(new_item_pkt->SerializedItem, serialized.c_str(), serialized.size()); + new_item_pkt->SerializedItem[serialized.size()] = '\0'; delete[] __emu_buffer; - safe_delete_array(serialized); dest->FastQueuePacket(&in, ack_req); } @@ -2079,90 +2077,207 @@ namespace Titanium } // file scope helper methods - char *SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint8 depth) + std::string SerializeItem(const ItemInst *inst, int16 slot_id_in, uint8 depth) { - char *serialization = nullptr; - char *instance = nullptr; - const char *protection = (const char *)"\\\\\\\\\\"; - char *sub_items[10] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; - bool stackable = inst->IsStackable(); - int16 slot_id = ServerToTitaniumSlot(slot_id_in); - uint32 merchant_slot = inst->GetMerchantSlot(); - int16 charges = inst->GetCharges(); - const Item_Struct *item = inst->GetUnscaledItem(); - int i; - uint32 sub_length; + std::string serialization; + std::string instance; + std::string protection = "\\\\\\\\\\"; + const Item_Struct* item = inst->GetUnscaledItem(); - MakeAnyLenString(&instance, - "%i|%i|%i|%i|%i|%i|%i|%i|%i|%i|%i|", - stackable ? charges : 0, - 0, - //(merchant_slot == 0) ? slot_id : merchant_slot, // change when translator activated - (merchant_slot == 0) ? slot_id_in : merchant_slot, - inst->GetPrice(), - (merchant_slot == 0) ? 1 : inst->GetMerchantCount(), - inst->IsScaling() ? inst->GetExp() / 100 : 0, - //merchant_slot, //instance ID, bullshit for now - (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot, - inst->GetRecastTimestamp(), - (stackable ? ((inst->GetItem()->ItemType == ItemTypePotion) ? 1 : 0) : charges), - inst->IsAttuned() ? 1 : 0, - 0 - ); + instance = StringFormat("%i|", (inst->IsStackable() ? inst->GetCharges() : 0)); // stack count + instance.append("0|"); // unknown + instance.append(StringFormat("%i|", (!inst->GetMerchantSlot() ? slot_id_in : inst->GetMerchantSlot()))); // inst slot/merchant slot + instance.append(StringFormat("%i|", inst->GetPrice())); // merchant price + instance.append(StringFormat("%i|", (!inst->GetMerchantSlot() ? 1 : inst->GetMerchantCount()))); // inst count/merchant count + instance.append(StringFormat("%i|", (inst->IsScaling() ? (inst->GetExp() / 100) : 0))); // inst experience + instance.append(StringFormat("%i|", (!inst->GetMerchantSlot() ? inst->GetSerialNumber() : inst->GetMerchantSlot()))); // merchant serial number + instance.append(StringFormat("%i|", inst->GetRecastTimestamp())); // recast timestamp + instance.append(StringFormat("%i|", ((inst->IsStackable() ? ((inst->GetItem()->ItemType == ItemTypePotion) ? 1 : 0) : inst->GetCharges())))); // charge count + instance.append(StringFormat("%i|", (inst->IsAttuned() ? 1 : 0))); // inst attuned + instance.append("0|"); // unknown - for (i = 0; i<10; i++) { - ItemInst *sub = inst->GetItem(i); - if (sub) { - sub_items[i] = SerializeItem(sub, 0, &sub_length, depth + 1); + serialization = StringFormat("%.*s%s", (depth ? (depth - 1) : 0), protection.c_str(), (depth ? "\"" : "")); // For leading quotes (and protection) if a subitem; + serialization.append(StringFormat("%s", instance.c_str())); // Instance data + serialization.append(StringFormat("%.*s\"", depth, protection.c_str())); // Quotes (and protection, if needed) around static data + + serialization.append(StringFormat("%i", item->ItemClass)); // item->ItemClass so we can do |%s instead of %s| + +//#include "titanium_itemfields_a.h" - begin + serialization.append(StringFormat("|%s", item->Name)); + serialization.append(StringFormat("|%s", item->Lore)); + serialization.append(StringFormat("|%s", item->IDFile)); + serialization.append(StringFormat("|%i", item->ID)); +//#include "titanium_itemfields_a.h" - end + serialization.append(StringFormat("|%i", ((item->Weight > 255) ? 255 : item->Weight))); +//#include "titanium_itemfields_b.h" - begin + serialization.append(StringFormat("|%i", item->NoRent)); + serialization.append(StringFormat("|%i", item->NoDrop)); + serialization.append(StringFormat("|%i", item->Size)); + serialization.append(StringFormat("|%i", item->Slots)); + serialization.append(StringFormat("|%i", item->Price)); + serialization.append(StringFormat("|%i", item->Icon)); + serialization.append("|0"); // unknown + serialization.append("|0"); // unknown + serialization.append(StringFormat("|%i", item->BenefitFlag)); + serialization.append(StringFormat("|%i", item->Tradeskills)); + serialization.append(StringFormat("|%i", item->CR)); + serialization.append(StringFormat("|%i", item->DR)); + serialization.append(StringFormat("|%i", item->PR)); + serialization.append(StringFormat("|%i", item->MR)); + serialization.append(StringFormat("|%i", item->FR)); + serialization.append(StringFormat("|%i", item->AStr)); + serialization.append(StringFormat("|%i", item->ASta)); + serialization.append(StringFormat("|%i", item->AAgi)); + serialization.append(StringFormat("|%i", item->ADex)); + serialization.append(StringFormat("|%i", item->ACha)); + serialization.append(StringFormat("|%i", item->AInt)); + serialization.append(StringFormat("|%i", item->AWis)); + serialization.append(StringFormat("|%i", item->HP)); + serialization.append(StringFormat("|%i", item->Mana)); + serialization.append(StringFormat("|%i", item->AC)); + serialization.append(StringFormat("|%i", item->Deity)); + serialization.append(StringFormat("|%i", item->SkillModValue)); + serialization.append(StringFormat("|%i", item->SkillModMax)); + serialization.append(StringFormat("|%i", item->SkillModType)); + serialization.append(StringFormat("|%i", item->BaneDmgRace)); + serialization.append(StringFormat("|%i", item->BaneDmgAmt)); + serialization.append(StringFormat("|%i", item->BaneDmgBody)); + serialization.append(StringFormat("|%i", item->Magic)); + serialization.append(StringFormat("|%i", item->CastTime_)); + serialization.append(StringFormat("|%i", item->ReqLevel)); + serialization.append(StringFormat("|%i", item->BardType)); + serialization.append(StringFormat("|%i", item->BardValue)); + serialization.append(StringFormat("|%i", item->Light)); + serialization.append(StringFormat("|%i", item->Delay)); + serialization.append(StringFormat("|%i", item->RecLevel)); + serialization.append(StringFormat("|%i", item->RecSkill)); + serialization.append(StringFormat("|%i", item->ElemDmgType)); + serialization.append(StringFormat("|%i", item->ElemDmgAmt)); + serialization.append(StringFormat("|%i", item->Range)); + serialization.append(StringFormat("|%i", item->Damage)); + serialization.append(StringFormat("|%i", item->Color)); + serialization.append(StringFormat("|%i", item->Classes)); + serialization.append(StringFormat("|%i", item->Races)); + serialization.append("|0"); // unknown + serialization.append(StringFormat("|%i", item->MaxCharges)); + serialization.append(StringFormat("|%i", item->ItemType)); + serialization.append(StringFormat("|%i", item->Material)); + serialization.append(StringFormat("|%i", item->SellRate)); + serialization.append("|0"); // unknown + serialization.append(StringFormat("|%i", item->CastTime_)); + serialization.append("|0"); // unknown + serialization.append(StringFormat("|%i", item->ProcRate)); + serialization.append(StringFormat("|%i", item->CombatEffects)); + serialization.append(StringFormat("|%i", item->Shielding)); + serialization.append(StringFormat("|%i", item->StunResist)); + serialization.append(StringFormat("|%i", item->StrikeThrough)); + serialization.append(StringFormat("|%i", item->ExtraDmgSkill)); + serialization.append(StringFormat("|%i", item->ExtraDmgAmt)); + serialization.append(StringFormat("|%i", item->SpellShield)); + serialization.append(StringFormat("|%i", item->Avoidance)); + serialization.append(StringFormat("|%i", item->Accuracy)); + serialization.append(StringFormat("|%i", item->CharmFileID)); + serialization.append(StringFormat("|%i", item->FactionMod1)); + serialization.append(StringFormat("|%i", item->FactionMod2)); + serialization.append(StringFormat("|%i", item->FactionMod3)); + serialization.append(StringFormat("|%i", item->FactionMod4)); + serialization.append(StringFormat("|%i", item->FactionAmt1)); + serialization.append(StringFormat("|%i", item->FactionAmt2)); + serialization.append(StringFormat("|%i", item->FactionAmt3)); + serialization.append(StringFormat("|%i", item->FactionAmt4)); + serialization.append(StringFormat("|%s", item->CharmFile)); + serialization.append(StringFormat("|%i", item->AugType)); + serialization.append(StringFormat("|%i", item->AugSlotType[0])); + serialization.append(StringFormat("|%i", item->AugSlotVisible[0])); + serialization.append(StringFormat("|%i", item->AugSlotType[1])); + serialization.append(StringFormat("|%i", item->AugSlotVisible[1])); + serialization.append(StringFormat("|%i", item->AugSlotType[2])); + serialization.append(StringFormat("|%i", item->AugSlotVisible[2])); + serialization.append(StringFormat("|%i", item->AugSlotType[3])); + serialization.append(StringFormat("|%i", item->AugSlotVisible[3])); + serialization.append(StringFormat("|%i", item->AugSlotType[4])); + serialization.append(StringFormat("|%i", item->AugSlotVisible[4])); + serialization.append(StringFormat("|%i", item->LDoNTheme)); + serialization.append(StringFormat("|%i", item->LDoNPrice)); + serialization.append(StringFormat("|%i", item->LDoNSold)); + serialization.append(StringFormat("|%i", item->BagType)); + serialization.append(StringFormat("|%i", item->BagSlots)); + serialization.append(StringFormat("|%i", item->BagSize)); + serialization.append(StringFormat("|%i", item->BagWR)); + serialization.append(StringFormat("|%i", item->Book)); + serialization.append(StringFormat("|%i", item->BookType)); + serialization.append(StringFormat("|%s", item->Filename)); + serialization.append(StringFormat("|%i", item->BaneDmgRaceAmt)); + serialization.append(StringFormat("|%i", item->AugRestrict)); + serialization.append(StringFormat("|%i", item->LoreGroup)); + serialization.append(StringFormat("|%i", item->PendingLoreFlag)); + serialization.append(StringFormat("|%i", item->ArtifactFlag)); + serialization.append(StringFormat("|%i", item->SummonedFlag)); + serialization.append(StringFormat("|%i", item->Favor)); + serialization.append(StringFormat("|%i", item->FVNoDrop)); + serialization.append(StringFormat("|%i", item->Endur)); + serialization.append(StringFormat("|%i", item->DotShielding)); + serialization.append(StringFormat("|%i", item->Attack)); + serialization.append(StringFormat("|%i", item->Regen)); + serialization.append(StringFormat("|%i", item->ManaRegen)); + serialization.append(StringFormat("|%i", item->EnduranceRegen)); + serialization.append(StringFormat("|%i", item->Haste)); + serialization.append(StringFormat("|%i", item->DamageShield)); + serialization.append(StringFormat("|%i", item->RecastDelay)); + serialization.append(StringFormat("|%i", item->RecastType)); + serialization.append(StringFormat("|%i", item->GuildFavor)); + serialization.append(StringFormat("|%i", item->AugDistiller)); + serialization.append("|0"); // unknown + serialization.append("|0"); // unknown + serialization.append(StringFormat("|%i", item->Attuneable)); + serialization.append(StringFormat("|%i", item->NoPet)); + serialization.append("|0"); // unknown + serialization.append(StringFormat("|%i", item->PointType)); + serialization.append(StringFormat("|%i", item->PotionBelt)); + serialization.append(StringFormat("|%i", item->PotionBeltSlots)); + serialization.append(StringFormat("|%i", item->StackSize)); + serialization.append(StringFormat("|%i", item->NoTransfer)); + serialization.append(StringFormat("|%i", item->Stackable)); + serialization.append(StringFormat("|%i", item->Click.Effect)); + serialization.append(StringFormat("|%i", item->Click.Type)); + serialization.append(StringFormat("|%i", item->Click.Level2)); + serialization.append(StringFormat("|%i", item->Click.Level)); + serialization.append("|0"); // Click name + serialization.append(StringFormat("|%i", item->Proc.Effect)); + serialization.append(StringFormat("|%i", item->Proc.Type)); + serialization.append(StringFormat("|%i", item->Proc.Level2)); + serialization.append(StringFormat("|%i", item->Proc.Level)); + serialization.append("|0"); // Proc name + serialization.append(StringFormat("|%i", item->Worn.Effect)); + serialization.append(StringFormat("|%i", item->Worn.Type)); + serialization.append(StringFormat("|%i", item->Worn.Level2)); + serialization.append(StringFormat("|%i", item->Worn.Level)); + serialization.append("|0"); // Worn name + serialization.append(StringFormat("|%i", item->Focus.Effect)); + serialization.append(StringFormat("|%i", item->Focus.Type)); + serialization.append(StringFormat("|%i", item->Focus.Level2)); + serialization.append(StringFormat("|%i", item->Focus.Level)); + serialization.append("|0"); // Focus name + serialization.append(StringFormat("|%i", item->Scroll.Effect)); + serialization.append(StringFormat("|%i", item->Scroll.Type)); + serialization.append(StringFormat("|%i", item->Scroll.Level2)); + serialization.append(StringFormat("|%i", item->Scroll.Level)); + serialization.append("|0"); // Scroll name +//#include "titanium_itemfields_b.h" - end + + serialization.append(StringFormat("%.*s\"", depth, protection.c_str())); // Quotes (and protection, if needed) around static data + for (int index = SUB_INDEX_BEGIN; index < consts::ITEM_CONTAINER_SIZE; ++index) { + ItemInst *sub = inst->GetItem(index); + if (!sub) { + serialization.push_back('|'); // Sub items (empty) + } + else { + std::string sub_item = SerializeItem(sub, 0, (depth + 1)); + serialization.append(StringFormat("|%s", sub_item.c_str())); // Sub items } } + serialization.append(StringFormat("%.*s%s", (depth ? (depth - 1) : 0), protection.c_str(), (depth ? "\"" : ""))); // For trailing quotes (and protection) if a subitem; - *length = MakeAnyLenString(&serialization, - "%.*s%s" // For leading quotes (and protection) if a subitem; - "%s" // Instance data - "%.*s\"" // Quotes (and protection, if needed) around static data - "%i" // item->ItemClass so we can do |%s instead of %s| -#define I(field) "|%i" -#define C(field) "|%s" -#define S(field) "|%s" -#define F(field) "|%f" -#include "titanium_itemfields_a.h" - "|%i" // mask for item->Weight -#include "titanium_itemfields_b.h" - "%.*s\"" // Quotes (and protection, if needed) around static data - "|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s" // Sub items - "%.*s%s" // For trailing quotes (and protection) if a subitem; - , depth ? depth - 1 : 0, protection, (depth) ? "\"" : "" - , instance - , depth, protection - , item->ItemClass -#define I(field) ,item->field -#define C(field) ,field -#define S(field) ,item->field -#define F(field) ,item->field -#include "titanium_itemfields_a.h" - , ((item->Weight > 255) ? (255) : (item->Weight)) -#include "titanium_itemfields_b.h" - , depth, protection - , sub_items[0] ? sub_items[0] : "" - , sub_items[1] ? sub_items[1] : "" - , sub_items[2] ? sub_items[2] : "" - , sub_items[3] ? sub_items[3] : "" - , sub_items[4] ? sub_items[4] : "" - , sub_items[5] ? sub_items[5] : "" - , sub_items[6] ? sub_items[6] : "" - , sub_items[7] ? sub_items[7] : "" - , sub_items[8] ? sub_items[8] : "" - , sub_items[9] ? sub_items[9] : "" - , (depth) ? depth - 1 : 0, protection, (depth) ? "\"" : "" - ); - - for (i = 0; i<10; i++) { - if (sub_items[i]) - safe_delete_array(sub_items[i]); - } - - safe_delete_array(instance); return serialization; } diff --git a/common/patches/titanium_structs.h b/common/patches/titanium_structs.h index 36cf2df3d..03d0ab06e 100644 --- a/common/patches/titanium_structs.h +++ b/common/patches/titanium_structs.h @@ -3341,6 +3341,177 @@ struct LFGuild_GuildToggle_Struct /*616*/ }; +//struct ItemEffect_Struct +//{ +// int16 Effect; +// uint8 Type; +// uint8 Level; +// uint8 Level2; +//}; +// +//struct Item_Struct +//{ +// // "titanium_itemfields_a.h" +// char Name; // "\0" +// char Lore; // "\0" +// char IDFile; // "\0" +// int ID; +// +// int Weight; +// +// // "titanium_itemfields_b.h" +// int NoRent; +// int NoDrop; +// int Size; +// int Slots; +// int Price; +// int Icon; +// char Unk1; // '0' +// char Unk2; // '0' +// int BenefitFlag; +// int Tradeskills; +// int CR; +// int DR; +// int PR; +// int MR; +// int FR; +// int AStr; +// int ASta; +// int AAgi; +// int ADex; +// int ACha; +// int AInt; +// int AWis; +// int HP; +// int Mana; +// int AC; +// int Deity; +// int SkillModValue; +// int SkillModMax; +// int SkillModType; +// int BaneDmgRace; +// int BaneDmgAmt; +// int BaneDmgBody; +// int Magic; +// int CastTime_; +// int ReqLevel; +// int BardType; +// int BardValue; +// int Light; +// int Delay; +// int RecLevel; +// int RecSkill; +// int ElemDmgType; +// int ElemDmgAmt; +// int Range; +// int Damage; +// int Color; +// int Classes; +// int Races; +// char Unk3; // '0' +// int MaxCharges; +// int ItemType; +// int Material; +// int SellRate; +// char Unk4; // '0' +// int _CastTime_; +// char Unk5; // '0' +// int ProcRate; +// int CombatEffects; +// int Shielding; +// int StunResist; +// int StrikeThrough; +// int ExtraDmgSkill; +// int ExtraDmgAmt; +// int SpellShield; +// int Avoidance; +// int Accuracy; +// int CharmFileID; +// int FactionMod1; +// int FactionMod2; +// int FactionMod3; +// int FactionMod4; +// int FactionAmt1; +// int FactionAmt2; +// int FactionAmt3; +// int FactionAmt4; +// char CharmFile; // "\0" +// int AugType; +// +// struct { +// int AugSlotType; +// int AugSlotVisible; +// } AugSlot[5]; +// +// int LDoNTheme; +// int LDoNPrice; +// int LDoNSold; +// int BagType; +// int BagSlots; +// int BagSize; +// int BagWR; +// int Book; +// int BookType; +// char Filename; // "\0" +// int BaneDmgRaceAmt; +// int AugRestrict; +// int LoreGroup; +// int PendingLoreFlag; +// int ArtifactFlag; +// int SummonedFlag; +// int Favor; +// int FVNoDrop; +// int Endur; +// int DotShielding; +// int Attack; +// int Regen; +// int ManaRegen; +// int EnduranceRegen; +// int Haste; +// int DamageShield; +// int RecastDelay; +// int RecastType; +// int GuildFavor; +// int AugDistiller; +// char Unk6; // '0' +// char Unk7; // '0' +// int Attunable; +// int NoPet; +// char Unk8; // '0' +// int PointType; +// int PotionBelt; +// int PotionBeltSlots; +// int StackSize; +// int NoTransfer; +// int Stackable; +// +// int ClickEffect; +// int ClickType; +// int ClickLevel2; +// int ClickLevel; +// char ClickName; // '0' +// int ProcEffect; +// int ProcType; +// int ProcLevel2; +// int ProcLevel; +// char ProcName; // '0' +// int WornEffect; +// int WornType; +// int WornLevel2; +// int WornLevel; +// char WornName; // '0' +// int FocusEffect; +// int FocusType; +// int FocusLevel2; +// int FocusLevel; +// char FocusName; // '0' +// int ScrollEffect; +// int ScrollType; +// int ScrollLevel2; +// int ScrollLevel; +// char ScrollName; // '0' +//}; + }; //end namespace structs }; //end namespace Titanium