Merged in Glorf/ryzomcore/item_group (pull request #148)

Use CREATE_TIME and SERIAL to identify items in item groups

--HG--
branch : develop
This commit is contained in:
Meelis Mägi 2017-04-07 19:59:09 +00:00
commit 59cd6afdb5
8 changed files with 305 additions and 36 deletions

View file

@ -37,6 +37,10 @@
type="I10" /> type="I10" />
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I10" /> type="I10" />
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />
<leaf name="LOCKED" <leaf name="LOCKED"
@ -79,6 +83,10 @@
type="I10" /> type="I10" />
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I10" /> type="I10" />
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />
<leaf name="LOCKED" <leaf name="LOCKED"
@ -130,6 +138,10 @@
type="I10" /> type="I10" />
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I10" /> type="I10" />
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />
<!-- No LOCKED state --> <!-- No LOCKED state -->
@ -168,6 +180,10 @@
type="I10" /> type="I10" />
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I10" /> type="I10" />
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />
<leaf name="WEIGHT" <leaf name="WEIGHT"
@ -223,6 +239,10 @@
type="I10" /> type="I10" />
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I10" /> type="I10" />
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />
<leaf name="LOCKED" <leaf name="LOCKED"
@ -278,6 +298,10 @@
type="I10" /> type="I10" />
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I10" /> type="I10" />
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />
<!-- <leaf name="LOCKED" type="I10"/> No longer needed --> <!-- <leaf name="LOCKED" type="I10"/> No longer needed -->
@ -309,6 +333,10 @@
type="I10" /> type="I10" />
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I10" /> type="I10" />
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />
<!-- <leaf name="LOCKED" type="I10"/> No longer needed --> <!-- <leaf name="LOCKED" type="I10"/> No longer needed -->
@ -352,6 +380,10 @@
type="I10" /> type="I10" />
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I10" /> type="I10" />
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<!-- No LOCKED state --> <!-- No LOCKED state -->
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />

View file

@ -4046,7 +4046,6 @@ void CDBCtrlSheet::setItemPrice(sint32 price)
node->setValue32(price); node->setValue32(price);
} }
// *************************************************************************** // ***************************************************************************
sint32 CDBCtrlSheet::getItemResaleFlag() const sint32 CDBCtrlSheet::getItemResaleFlag() const
{ {
@ -4071,6 +4070,54 @@ void CDBCtrlSheet::setItemResaleFlag(sint32 rf)
node->setValue32(rf); node->setValue32(rf);
} }
// ***************************************************************************
sint32 CDBCtrlSheet::getItemCreateTime() const
{
CCDBNodeLeaf *node = getItemCreateTimePtr();
if (!node) return 0;
return node->getValue32();
}
// ***************************************************************************
CCDBNodeLeaf *CDBCtrlSheet::getItemCreateTimePtr() const
{
CCDBNodeBranch *root = getRootBranch();
if (!root) return NULL;
return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("CREATE_TIME"), false));
}
// ***************************************************************************
void CDBCtrlSheet::setItemCreateTime(sint32 ct)
{
CCDBNodeLeaf *node = getItemCreateTimePtr();
if (!node) return;
node->setValue32(ct);
}
// ***************************************************************************
sint32 CDBCtrlSheet::getItemSerial() const
{
CCDBNodeLeaf *node = getItemSerialPtr();
if (!node) return 0;
return node->getValue32();
}
// ***************************************************************************
CCDBNodeLeaf *CDBCtrlSheet::getItemSerialPtr() const
{
CCDBNodeBranch *root = getRootBranch();
if (!root) return NULL;
return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("SERIAL"), false));
}
// ***************************************************************************
void CDBCtrlSheet::setItemSerial(sint32 rf)
{
CCDBNodeLeaf *node = getItemSerialPtr();
if (!node) return;
node->setValue32(rf);
}
// *************************************************************************** // ***************************************************************************
bool CDBCtrlSheet::getLockedByOwner() const bool CDBCtrlSheet::getLockedByOwner() const
{ {

View file

@ -514,6 +514,18 @@ public:
// set item RESALE_FLAG // set item RESALE_FLAG
void setItemResaleFlag(sint32 rf); void setItemResaleFlag(sint32 rf);
//get item CREATE_TIME. 0 if no DB
sint32 getItemCreateTime() const;
NLMISC::CCDBNodeLeaf *getItemCreateTimePtr() const;
// set item CREATE_TIME
void setItemCreateTime(sint32 ct);
//get item SERIAL. 0 if no DB
sint32 getItemSerial() const;
NLMISC::CCDBNodeLeaf *getItemSerialPtr() const;
// set item CREATE_TIME
void setItemSerial(sint32 serial);
// get item locked by owner // get item locked by owner
bool getLockedByOwner() const; bool getLockedByOwner() const;

View file

@ -51,6 +51,12 @@ bool CItemGroup::contains(CDBCtrlSheet *other, SLOT_EQUIPMENT::TSlotEquipment &s
for(int i=0;i<Items.size();i++) for(int i=0;i<Items.size();i++)
{ {
CItem item = Items[i]; CItem item = Items[i];
if(item.useCreateTime() && item.createTime == other->getItemCreateTime() && item.serial == other->getItemSerial())
{
slot = item.slot;
return true;
}
// Present for compatibility reasons
NLMISC::CSheetId sheet = NLMISC::CSheetId(other->getSheetId()); NLMISC::CSheetId sheet = NLMISC::CSheetId(other->getSheetId());
if (sheet.toString() == item.sheetName && other->getQuality() == item.quality && if (sheet.toString() == item.sheetName && other->getQuality() == item.quality &&
other->getItemWeight() == item.weight && other->getItemColor() == item.color && other->getItemWeight() == item.weight && other->getItemColor() == item.color &&
@ -65,9 +71,9 @@ bool CItemGroup::contains(CDBCtrlSheet *other, SLOT_EQUIPMENT::TSlotEquipment &s
return false; 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) void CItemGroup::addRemove(std::string slotName)
@ -90,15 +96,24 @@ void CItemGroup::writeTo(xmlNodePtr node)
{ {
CItem item = Items[i]; CItem item = Items[i];
xmlNodePtr itemNode = xmlNewChild(groupNode, NULL, (const xmlChar*)"item", NULL); xmlNodePtr itemNode = xmlNewChild(groupNode, NULL, (const xmlChar*)"item", NULL);
xmlSetProp (itemNode, (const xmlChar*)"sheetName", (const xmlChar*)item.sheetName.c_str()); if(item.useCreateTime())
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*)"createTime", (const xmlChar*)NLMISC::toString(item.createTime).c_str());
xmlSetProp (itemNode, (const xmlChar*)"color", (const xmlChar*)NLMISC::toString(item.color).c_str()); xmlSetProp (itemNode, (const xmlChar*)"serial", (const xmlChar*)NLMISC::toString(item.serial).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()); // 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 // We need to save slot only if it's useful for clarity
if(item.slot == SLOT_EQUIPMENT::HANDL || item.slot == SLOT_EQUIPMENT::HANDR) //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()); xmlSetProp(itemNode, (const xmlChar*)"slot", (const xmlChar*)SLOT_EQUIPMENT::toString(item.slot).c_str());
} }
for(int i=0;i<removeBeforeEquip.size();i++) for(int i=0;i<removeBeforeEquip.size();i++)
{ {
@ -121,6 +136,15 @@ void CItemGroup::readFrom(xmlNodePtr node)
{ {
CItem item; CItem item;
ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"createTime");
if (ptrName) NLMISC::fromString((const char*)ptrName, item.createTime);
ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"serial");
if (ptrName) NLMISC::fromString((const char*)ptrName, item.serial);
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 read, keep for compatibility reasons
ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"sheetName"); ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"sheetName");
if (ptrName) NLMISC::fromString((const char*)ptrName, item.sheetName); if (ptrName) NLMISC::fromString((const char*)ptrName, item.sheetName);
ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"quality"); ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"quality");
@ -134,13 +158,8 @@ void CItemGroup::readFrom(xmlNodePtr node)
ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"maxPrice"); ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"maxPrice");
if (ptrName) NLMISC::fromString((const char*)ptrName, item.maxPrice); if (ptrName) NLMISC::fromString((const char*)ptrName, item.maxPrice);
item.usePrice = (item.minPrice != 0 || item.maxPrice != std::numeric_limits<uint32>::max()); item.usePrice = (item.minPrice != 0 || item.maxPrice != std::numeric_limits<uint32>::max());
ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"slot");
std::string slot; Items.push_back(item);
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);
} }
if (strcmp((char*)curNode->name, "remove") == 0) if (strcmp((char*)curNode->name, "remove") == 0)
{ {
@ -159,10 +178,12 @@ CItemGroupManager::CItemGroupManager()
{ {
_EndInvalidAction = 0; _EndInvalidAction = 0;
_StartInvalidAction = 0; _StartInvalidAction = 0;
_MigrationDone = false;
} }
void CItemGroupManager::init() void CItemGroupManager::init()
{ {
_MigrationDone = false;
loadGroups(); loadGroups();
linkInterface(); linkInterface();
} }
@ -300,6 +321,98 @@ void CItemGroupManager::update()
_EndInvalidAction = 0; _EndInvalidAction = 0;
validActions(); 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<CItemGroup> 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<CInventoryItem> 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) void CItemGroupManager::fakeInvalidActions(NLMISC::TGameCycle time)
@ -417,7 +530,6 @@ bool CItemGroupManager::equipGroup(std::string name, bool pullBefore)
{ITEM_TYPE::BRACELET, false}, {ITEM_TYPE::BRACELET, false},
{ITEM_TYPE::EARING, false}, {ITEM_TYPE::EARING, false},
{ITEM_TYPE::RING, false}, {ITEM_TYPE::RING, false},
{ITEM_TYPE::DAGGER, false},
}; };
std::vector<CInventoryItem> duals; std::vector<CInventoryItem> duals;
std::vector<CInventoryItem> items = matchingItems(group, INVENTORIES::TInventory::bag); std::vector<CInventoryItem> items = matchingItems(group, INVENTORIES::TInventory::bag);
@ -425,9 +537,10 @@ bool CItemGroupManager::equipGroup(std::string name, bool pullBefore)
{ {
CInventoryItem item = items[i]; CInventoryItem item = items[i];
ITEM_TYPE::TItemType itemType = item.pCS->asItemSheet()->ItemType; ITEM_TYPE::TItemType itemType = item.pCS->asItemSheet()->ItemType;
// Special case for dagger (and all other items that can be equipped both right AND left hand, currently it's only dagger) // We'll equip items in left hand later (the right hand will be normally equipped)
// We don't equip the one intended for left hand right away (it will be done in duals items later), let right hand be normally equipped // This way, if we switch from 2 hands to 2 * 1 hands, both hands will be equipped correctly (first right, which will remove the 2 hands, then left)
if(itemType == ITEM_TYPE::DAGGER && item.slot == SLOT_EQUIPMENT::HANDL) // If we don't, we might try to equip the left hand first, which will do nothing because we have a 2 hands equipped
if(item.slot == SLOT_EQUIPMENT::HANDL)
{ {
duals.push_back(item); duals.push_back(item);
continue; continue;
@ -465,6 +578,8 @@ bool CItemGroupManager::equipGroup(std::string name, bool pullBefore)
case ITEM_TYPE::RING: case ITEM_TYPE::RING:
dstPath += ":EQUIP:" + NLMISC::toString((int)SLOT_EQUIPMENT::FINGERR);;break; dstPath += ":EQUIP:" + NLMISC::toString((int)SLOT_EQUIPMENT::FINGERR);;break;
case ITEM_TYPE::DAGGER: case ITEM_TYPE::DAGGER:
case ITEM_TYPE::BUCKLER:
case ITEM_TYPE::SHIELD:
dstPath += ":HAND:1"; break; dstPath += ":HAND:1"; break;
default: default:
break; break;
@ -502,8 +617,7 @@ bool CItemGroupManager::createGroup(std::string name, bool removeUnequiped)
if(!pCS) continue; if(!pCS) continue;
if(pCS->isSheetValid()) if(pCS->isSheetValid())
{ {
NLMISC::CSheetId sheet(pCS->getSheetId()); group.addItem(pCS->getItemCreateTime(), pCS->getItemSerial(), slot);
group.addItem(sheet.toString(), pCS->getQuality(), pCS->getItemWeight(), pCS->getItemColor(), slot);
} }
else if(removeUnequiped) else if(removeUnequiped)
{ {

View file

@ -28,7 +28,7 @@ public:
CDBCtrlSheet* pCS; CDBCtrlSheet* pCS;
INVENTORIES::TInventory origin; INVENTORIES::TInventory origin;
uint32 indexInBag; 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) : CInventoryItem(CDBCtrlSheet *pCS, INVENTORIES::TInventory origin, uint32 indexInBag, SLOT_EQUIPMENT::TSlotEquipment slot = SLOT_EQUIPMENT::UNDEFINED) :
pCS(pCS), origin(origin), indexInBag(indexInBag), slot(slot) {} pCS(pCS), origin(origin), indexInBag(indexInBag), slot(slot) {}
@ -37,17 +37,24 @@ public:
class CItemGroup { class CItemGroup {
public: public:
struct CItem { 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; std::string sheetName;
uint16 quality; uint16 quality;
uint32 weight; uint32 weight;
uint8 color; uint8 color;
SLOT_EQUIPMENT::TSlotEquipment slot; // Used only for dagger (right/left hand slot)
uint32 minPrice; uint32 minPrice;
uint32 maxPrice; uint32 maxPrice;
bool usePrice; 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<uint32>::max(), bool usePrice = false) : CItem(sint32 createTime, sint32 serial, SLOT_EQUIPMENT::TSlotEquipment slot = SLOT_EQUIPMENT::UNDEFINED) :
sheetName(sheetName), quality(quality), weight(weight), color(color), slot(slot), minPrice(minPrice), maxPrice(maxPrice), usePrice(usePrice) {} 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<uint32>::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: 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 // 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);
bool contains(CDBCtrlSheet* other, SLOT_EQUIPMENT::TSlotEquipment &slot); 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(std::string slotName);
void addRemove(SLOT_EQUIPMENT::TSlotEquipment slot); void addRemove(SLOT_EQUIPMENT::TSlotEquipment slot);
void writeTo(xmlNodePtr node); void writeTo(xmlNodePtr node);
void readFrom(xmlNodePtr node); void readFrom(xmlNodePtr node);
// return true if no item inside
bool empty() const { return Items.size() == 0;}
std::string name; std::string name;
std::vector<CItem> Items; std::vector<CItem> Items;
std::vector<SLOT_EQUIPMENT::TSlotEquipment> removeBeforeEquip; std::vector<SLOT_EQUIPMENT::TSlotEquipment> removeBeforeEquip;
@ -107,6 +116,11 @@ private:
NLMISC::TGameCycle _EndInvalidAction; NLMISC::TGameCycle _EndInvalidAction;
NLMISC::TGameCycle _StartInvalidAction; 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 #endif // RY_ITEM_GROUP_MANAGER_H

View file

@ -334,6 +334,8 @@
<leaf name="SHEET" type="I32"/> <leaf name="SHEET" type="I32"/>
<leaf name="QUALITY" type="I10"/> <leaf name="QUALITY" type="I10"/>
<leaf name="QUANTITY" type="I10"/> <leaf name="QUANTITY" type="I10"/>
<leaf name="CREATE_TIME" type="I32" />
<leaf name="SERIAL" type="I32" />
<leaf name="USER_COLOR" type="I3"/> <leaf name="USER_COLOR" type="I3"/>
<leaf name="LOCKED" type="I10"/> <leaf name="LOCKED" type="I10"/>
<leaf name="WEIGHT" type="I16"/> <leaf name="WEIGHT" type="I16"/>
@ -375,6 +377,10 @@
type="I10" /> type="I10" />
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I10" /> type="I10" />
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />
<!-- <leaf name="LOCKED" type="I10"/> No longer needed --> <!-- <leaf name="LOCKED" type="I10"/> No longer needed -->
@ -407,6 +413,10 @@
type="I10" /> type="I10" />
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I10" /> type="I10" />
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />
<!-- <leaf name="LOCKED" type="I10"/> No longer needed --> <!-- <leaf name="LOCKED" type="I10"/> No longer needed -->
@ -457,6 +467,10 @@
type="I10" /> type="I10" />
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I10" /> type="I10" />
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />
<leaf name="LOCKED" <leaf name="LOCKED"
@ -502,6 +516,10 @@
type="I10" /> type="I10" />
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I10" /> type="I10" />
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />
<leaf name="LOCKED" <leaf name="LOCKED"
@ -555,6 +573,10 @@
<!-- for forage progress, max QL409 x10 --> <!-- for forage progress, max QL409 x10 -->
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I12" /> type="I12" />
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<!-- for forage progress, max x409 x10 --> <!-- for forage progress, max x409 x10 -->
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />
@ -596,6 +618,10 @@
type="I10" /> type="I10" />
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I10" /> type="I10" />
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />
<leaf name="WEIGHT" <leaf name="WEIGHT"
@ -653,6 +679,10 @@
type="I10" /> type="I10" />
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I10" /> type="I10" />
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />
<leaf name="LOCKED" <leaf name="LOCKED"
@ -860,6 +890,10 @@
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I10" /> type="I10" />
<!-- No LOCKED state --> <!-- No LOCKED state -->
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />
<leaf name="WEIGHT" <leaf name="WEIGHT"
@ -1133,6 +1167,10 @@
type="I10" /> type="I10" />
<leaf name="QUANTITY" <leaf name="QUANTITY"
type="I10" /> type="I10" />
<leaf name="CREATE_TIME"
type="I32" />
<leaf name="SERIAL"
type="I32" />
<leaf name="USER_COLOR" <leaf name="USER_COLOR"
type="I3" /> type="I3" />
<leaf name="LOCKED" <leaf name="LOCKED"

View file

@ -98,7 +98,7 @@ namespace INVENTORIES
"", // player_room "", // player_room
"" // unknown "" // unknown
}; };
// //
const char *CInventoryCategoryForCharacter::InventoryStr [CInventoryCategoryForCharacter::NbInventoryIds] = const char *CInventoryCategoryForCharacter::InventoryStr [CInventoryCategoryForCharacter::NbInventoryIds] =
@ -122,7 +122,7 @@ namespace INVENTORIES
const char *InfoVersionStr = "INFO_VERSION"; const char *InfoVersionStr = "INFO_VERSION";
const char *CItemSlot::ItemPropStr [NbItemPropId] = const char *CItemSlot::ItemPropStr [NbItemPropId] =
{ "SHEET", "QUALITY", "QUANTITY", "USER_COLOR", "LOCKED", "WEIGHT", "NAMEID", "ENCHANT", "RM_CLASS_TYPE", "RM_FABER_STAT_TYPE", "PRICE", "RESALE_FLAG", "PREREQUISIT_VALID", "WORNED" }; { "SHEET", "QUALITY", "QUANTITY", "USER_COLOR", "CREATE_TIME", "SERIAL", "LOCKED", "WEIGHT", "NAMEID", "ENCHANT", "RM_CLASS_TYPE", "RM_FABER_STAT_TYPE", "PRICE", "RESALE_FLAG", "PREREQUISIT_VALID", "WORNED" };
const uint CItemSlot::DataBitSize [NbItemPropId] = const uint CItemSlot::DataBitSize [NbItemPropId] =
{ 32, 10, 10, 3, 10, 16, 32, 10, 3, 5, 32, 2, 1, 1 }; { 32, 10, 10, 3, 32, 32, 10, 16, 32, 10, 3, 5, 32, 2, 1, 1 };
} }

View file

@ -112,6 +112,17 @@ namespace INVENTORIES
return _RawId < other._RawId; return _RawId < other._RawId;
} }
uint32 getCreateTime() const
{
return _CreateTime;
}
uint32 getSerialNumber() const
{
return _SerialNumber;
}
private: private:
union union
{ {
@ -255,6 +266,8 @@ namespace INVENTORIES
Quality, Quality,
Quantity, Quantity,
UserColor, UserColor,
CreateTime,
Serial,
Locked, Locked,
Weight, Weight,
NameId, NameId,
@ -354,8 +367,8 @@ namespace INVENTORIES
bms.serial( _SlotIndex, CInventoryCategoryTemplate::SlotBitSize ); bms.serial( _SlotIndex, CInventoryCategoryTemplate::SlotBitSize );
uint i; uint i;
// SHEET, QUALITY, QUANTITY and USER_COLOR never require compression // SHEET, QUALITY, QUANTITY, USER_COLOR, CREATE_TIME and SERIAL never require compression
for (i = 0; i < 4; ++i) for (i = 0; i < 6; ++i)
bms.serial((uint32&)_ItemProp[i], DataBitSize[i]); bms.serial((uint32&)_ItemProp[i], DataBitSize[i]);
// For all other the compression is simple the first bit indicates if the value is zero // For all other the compression is simple the first bit indicates if the value is zero
@ -417,7 +430,6 @@ private:
TItemPropId ItemPropId; TItemPropId ItemPropId;
uint32 ItemPropIdUint32; uint32 ItemPropIdUint32;
}; };
sint32 ItemPropValue; sint32 ItemPropValue;
void serial( NLMISC::CBitMemStream& bms ) void serial( NLMISC::CBitMemStream& bms )