From 91932668c6a85d1ce829192b3ec7022e72f500cf Mon Sep 17 00:00:00 2001 From: Guillaume Dupuy Date: Fri, 7 Apr 2017 19:00:36 +0200 Subject: [PATCH] Use item create time / serial to identify them (migration code included) --HG-- branch : item_group --- code/ryzom/client/src/item_group_manager.cpp | 150 ++++++++++++++++--- code/ryzom/client/src/item_group_manager.h | 26 +++- 2 files changed, 151 insertions(+), 25 deletions(-) diff --git a/code/ryzom/client/src/item_group_manager.cpp b/code/ryzom/client/src/item_group_manager.cpp index 6584060ff..c1c49414e 100644 --- a/code/ryzom/client/src/item_group_manager.cpp +++ b/code/ryzom/client/src/item_group_manager.cpp @@ -51,6 +51,12 @@ bool CItemGroup::contains(CDBCtrlSheet *other, SLOT_EQUIPMENT::TSlotEquipment &s for(int i=0;igetItemCreateTime() && item.serial == other->getItemSerial()) + { + slot = item.slot; + return true; + } + // Present for compatibility reasons NLMISC::CSheetId sheet = NLMISC::CSheetId(other->getSheetId()); if (sheet.toString() == item.sheetName && other->getQuality() == item.quality && other->getItemWeight() == item.weight && other->getItemColor() == item.color && @@ -65,9 +71,9 @@ bool CItemGroup::contains(CDBCtrlSheet *other, SLOT_EQUIPMENT::TSlotEquipment &s return false; } -void CItemGroup::addItem(std::string sheetName, uint16 quality, uint32 weight, uint8 color, SLOT_EQUIPMENT::TSlotEquipment slot) +void CItemGroup::addItem(sint32 createTime, sint32 serial, SLOT_EQUIPMENT::TSlotEquipment slot) { - Items.push_back(CItem(sheetName, quality, weight, color, slot)); + Items.push_back(CItem(createTime, serial, slot)); } void CItemGroup::addRemove(std::string slotName) @@ -90,15 +96,24 @@ void CItemGroup::writeTo(xmlNodePtr node) { CItem item = Items[i]; xmlNodePtr itemNode = xmlNewChild(groupNode, NULL, (const xmlChar*)"item", NULL); - xmlSetProp (itemNode, (const xmlChar*)"sheetName", (const xmlChar*)item.sheetName.c_str()); - xmlSetProp (itemNode, (const xmlChar*)"quality", (const xmlChar*)NLMISC::toString(item.quality).c_str()); - xmlSetProp (itemNode, (const xmlChar*)"weight", (const xmlChar*)NLMISC::toString(item.weight).c_str()); - xmlSetProp (itemNode, (const xmlChar*)"color", (const xmlChar*)NLMISC::toString(item.color).c_str()); - xmlSetProp (itemNode, (const xmlChar*)"minPrice", (const xmlChar*)NLMISC::toString(item.minPrice).c_str()); - xmlSetProp (itemNode, (const xmlChar*)"maxPrice", (const xmlChar*)NLMISC::toString(item.maxPrice).c_str()); + if(item.useCreateTime()) + { + xmlSetProp (itemNode, (const xmlChar*)"createTime", (const xmlChar*)NLMISC::toString(item.createTime).c_str()); + xmlSetProp (itemNode, (const xmlChar*)"serial", (const xmlChar*)NLMISC::toString(item.serial).c_str()); + } + // Present for compatibility reasons + else + { + xmlSetProp (itemNode, (const xmlChar*)"sheetName", (const xmlChar*)item.sheetName.c_str()); + xmlSetProp (itemNode, (const xmlChar*)"quality", (const xmlChar*)NLMISC::toString(item.quality).c_str()); + xmlSetProp (itemNode, (const xmlChar*)"weight", (const xmlChar*)NLMISC::toString(item.weight).c_str()); + xmlSetProp (itemNode, (const xmlChar*)"color", (const xmlChar*)NLMISC::toString(item.color).c_str()); + xmlSetProp (itemNode, (const xmlChar*)"minPrice", (const xmlChar*)NLMISC::toString(item.minPrice).c_str()); + xmlSetProp (itemNode, (const xmlChar*)"maxPrice", (const xmlChar*)NLMISC::toString(item.maxPrice).c_str()); + } // We need to save slot only if it's useful for clarity - if(item.slot == SLOT_EQUIPMENT::HANDL || item.slot == SLOT_EQUIPMENT::HANDR) - xmlSetProp(itemNode, (const xmlChar*)"slot", (const xmlChar*)SLOT_EQUIPMENT::toString(item.slot).c_str()); + //if(item.slot == SLOT_EQUIPMENT::HANDL || item.slot == SLOT_EQUIPMENT::HANDR) + xmlSetProp(itemNode, (const xmlChar*)"slot", (const xmlChar*)SLOT_EQUIPMENT::toString(item.slot).c_str()); } for(int i=0;i::max()); - ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"slot"); - std::string slot; - if (ptrName) NLMISC::fromString((const char*)ptrName, slot); - item.slot = SLOT_EQUIPMENT::stringToSlotEquipment(NLMISC::toUpper(slot)); - //Old version of groups.xml could save unknown sheets, remove them for clarity - if(item.sheetName != "unknown.unknown") - Items.push_back(item); + + Items.push_back(item); } if (strcmp((char*)curNode->name, "remove") == 0) { @@ -159,10 +178,12 @@ CItemGroupManager::CItemGroupManager() { _EndInvalidAction = 0; _StartInvalidAction = 0; + _MigrationDone = false; } void CItemGroupManager::init() { + _MigrationDone = false; loadGroups(); linkInterface(); } @@ -300,6 +321,98 @@ void CItemGroupManager::update() _EndInvalidAction = 0; validActions(); } + //Migration code, present for compatibility reasons + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + if(!_MigrationDone && pIM) + { + NLMISC::CCDBNodeLeaf *node = NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:CDB_INIT_IN_PROGRESS"); + if(node) + { + if(!node->getValueBool()) + { + nlinfo("Starting migration"); + migrateGroups(); + _MigrationDone = true; + nlinfo("Item group migration from old system to new system is done !"); + } + } + } + +} + +bool CItemGroupManager::migrateGroups() +{ + std::vector newGroups; + //This is not very optimised, but this will be executed only once (and removed in the near future) + for(int i=0; i < _Groups.size(); i++) + { + CItemGroup group = _Groups[i]; + //Migrate the group only if there is items inside, and the first one hasn't been migrated + bool needMigration = group.Items.size() > 0 && !group.Items[0].useCreateTime(); + if(!needMigration) + { + newGroups.push_back(group); + continue; + } + //If we are here, migrate the group + newGroups.push_back(migrateGroup(group)); + } + _Groups.clear(); + _Groups = newGroups; + return true; +} + +CItemGroup CItemGroupManager::migrateGroup(CItemGroup group) +{ + //Get all matching items from all inventory + CItemGroup out; + out.name = group.name; + for (int i=0; i < INVENTORIES::TInventory::NUM_ALL_INVENTORY; i++) + { + INVENTORIES::TInventory inventory = (INVENTORIES::TInventory)i; + std::vector items = matchingItems(&group, inventory); + for(int j = 0; j < items.size(); j++) + { + SLOT_EQUIPMENT::TSlotEquipment slot = SLOT_EQUIPMENT::UNDEFINED; + //slot might be undefined here, but we want it for clarity purpose in the xml (to easily find lines) + if(items[j].slot != SLOT_EQUIPMENT::UNDEFINED) + slot = items[j].slot; + // We can't get a perfect match (can't know if it's a right/left jewel for example), but it's good enough + else + { + + //jewels + const CItemSheet* sheet = items[j].pCS->asItemSheet(); + if(!sheet) + { + nlinfo("Could not get as itemSheet, strange"); + } + + else if (sheet->hasSlot(SLOTTYPE::HEADDRESS)) slot = SLOT_EQUIPMENT::HEADDRESS; + else if (sheet->hasSlot(SLOTTYPE::NECKLACE)) slot = SLOT_EQUIPMENT::NECKLACE; + else if (sheet->hasSlot(SLOTTYPE::FINGERS)) slot = SLOT_EQUIPMENT::FINGERL; + else if (sheet->hasSlot(SLOTTYPE::ANKLE)) slot = SLOT_EQUIPMENT::ANKLEL; + else if (sheet->hasSlot(SLOTTYPE::WRIST)) slot = SLOT_EQUIPMENT::WRISTL; + else if (sheet->hasSlot(SLOTTYPE::EARS)) slot = SLOT_EQUIPMENT::EARL; + //Armor + //Helmet + else if (sheet->hasSlot(SLOTTYPE::HEAD)) slot = SLOT_EQUIPMENT::HEAD; + //Gloves + else if (sheet->hasSlot(SLOTTYPE::HANDS)) slot = SLOT_EQUIPMENT::HANDS; + //Sleeves + else if (sheet->hasSlot(SLOTTYPE::ARMS)) slot = SLOT_EQUIPMENT::ARMS; + //Vest + else if (sheet->hasSlot(SLOTTYPE::CHEST)) slot = SLOT_EQUIPMENT::CHEST; + //Boots + else if (sheet->hasSlot(SLOTTYPE::FEET)) slot = SLOT_EQUIPMENT::FEET; + // pants + else if (sheet->hasSlot(SLOTTYPE::LEGS)) slot = SLOT_EQUIPMENT::LEGS; + else slot = SLOT_EQUIPMENT::UNDEFINED; + } + out.addItem(items[j].pCS->getItemCreateTime(), items[j].pCS->getItemSerial(), slot); + } + } + return out; } void CItemGroupManager::fakeInvalidActions(NLMISC::TGameCycle time) @@ -502,8 +615,7 @@ bool CItemGroupManager::createGroup(std::string name, bool removeUnequiped) if(!pCS) continue; if(pCS->isSheetValid()) { - NLMISC::CSheetId sheet(pCS->getSheetId()); - group.addItem(sheet.toString(), pCS->getQuality(), pCS->getItemWeight(), pCS->getItemColor(), slot); + group.addItem(pCS->getItemCreateTime(), pCS->getItemSerial(), slot); } else if(removeUnequiped) { diff --git a/code/ryzom/client/src/item_group_manager.h b/code/ryzom/client/src/item_group_manager.h index c74985f70..dae9d0e11 100644 --- a/code/ryzom/client/src/item_group_manager.h +++ b/code/ryzom/client/src/item_group_manager.h @@ -28,7 +28,7 @@ public: CDBCtrlSheet* pCS; INVENTORIES::TInventory origin; uint32 indexInBag; - SLOT_EQUIPMENT::TSlotEquipment slot; // Used only for dagger (right/left hand slot) + SLOT_EQUIPMENT::TSlotEquipment slot; // Used to differentiate right/left hands, and for clarity in the xml file CInventoryItem(CDBCtrlSheet *pCS, INVENTORIES::TInventory origin, uint32 indexInBag, SLOT_EQUIPMENT::TSlotEquipment slot = SLOT_EQUIPMENT::UNDEFINED) : pCS(pCS), origin(origin), indexInBag(indexInBag), slot(slot) {} @@ -37,17 +37,24 @@ public: class CItemGroup { public: struct CItem { + SLOT_EQUIPMENT::TSlotEquipment slot; // Used only for dagger (right/left hand slot) + sint32 createTime; + sint32 serial; + // Old variables, present for compatibility reasons std::string sheetName; uint16 quality; uint32 weight; uint8 color; - SLOT_EQUIPMENT::TSlotEquipment slot; // Used only for dagger (right/left hand slot) uint32 minPrice; uint32 maxPrice; bool usePrice; - CItem(std::string sheetName = "", uint16 quality = 0, uint32 weight = 0, uint8 color = 0, SLOT_EQUIPMENT::TSlotEquipment slot = SLOT_EQUIPMENT::UNDEFINED, uint32 minPrice = 0, uint32 maxPrice = std::numeric_limits::max(), bool usePrice = false) : - sheetName(sheetName), quality(quality), weight(weight), color(color), slot(slot), minPrice(minPrice), maxPrice(maxPrice), usePrice(usePrice) {} - + CItem(sint32 createTime, sint32 serial, SLOT_EQUIPMENT::TSlotEquipment slot = SLOT_EQUIPMENT::UNDEFINED) : + createTime(createTime), serial(serial), slot(slot) {} + //Old constructor, present for compatibility reasons + CItem(std::string sheetName = "", uint16 quality = 0, uint32 weight = 0, uint8 color = 0, sint32 createTime = 0, sint32 serial = 0, SLOT_EQUIPMENT::TSlotEquipment slot = SLOT_EQUIPMENT::UNDEFINED, uint32 minPrice = 0, uint32 maxPrice = std::numeric_limits::max(), bool usePrice = false) : + sheetName(sheetName), quality(quality), weight(weight), color(color), createTime(createTime), serial(serial), slot(slot), minPrice(minPrice), maxPrice(maxPrice), usePrice(usePrice) {} + //present for compatibility reasons + bool useCreateTime() const { return createTime != 0 && serial != 0;} }; public: @@ -56,12 +63,14 @@ public: // return true if any item in the group match the parameter ; slot is UNDEFINED unless the item has been found in the group bool contains(CDBCtrlSheet *other); bool contains(CDBCtrlSheet* other, SLOT_EQUIPMENT::TSlotEquipment &slot); - void addItem(std::string sheetName, uint16 quality, uint32 weight, uint8 color, SLOT_EQUIPMENT::TSlotEquipment slot); + void addItem(sint32 createTime, sint32 serial, SLOT_EQUIPMENT::TSlotEquipment slot); void addRemove(std::string slotName); void addRemove(SLOT_EQUIPMENT::TSlotEquipment slot); void writeTo(xmlNodePtr node); void readFrom(xmlNodePtr node); + // return true if no item inside + bool empty() const { return Items.size() == 0;} std::string name; std::vector Items; std::vector removeBeforeEquip; @@ -107,6 +116,11 @@ private: NLMISC::TGameCycle _EndInvalidAction; NLMISC::TGameCycle _StartInvalidAction; + //Used to migrate old groups ; keep for compatibility purpose + bool migrateGroups(); + //Return a new group who uses create time and serial (param group isn't modified) + CItemGroup migrateGroup(CItemGroup group); + bool _MigrationDone; }; #endif // RY_ITEM_GROUP_MANAGER_H