add: item groups refactor draft

- Created CEquipItem and CHotbarItem, inheriting CItem, to differentiate item type
- Overloaded methods for EquipItems (using TSlotEquipment slot) and HotbarItems (using uint16 slot)
- Separated Items array into EquipItems and HotbarItems
- New xml props <hotbar_item> and <hotbar_remove>, children of <group>

TODO:
- Revisit contains() method
- Implement hotbar compatibility to matchingItems() method
10-use-item-shortcut-client
Ben 3 years ago
parent d6d0417419
commit 5ad6cffb21

@ -46,14 +46,43 @@ CItemGroup::CItemGroup()
bool CItemGroup::contains(CDBCtrlSheet *other) bool CItemGroup::contains(CDBCtrlSheet *other)
{ {
SLOT_EQUIPMENT::TSlotEquipment slot = SLOT_EQUIPMENT::UNDEFINED; SLOT_EQUIPMENT::TSlotEquipment slot = SLOT_EQUIPMENT::UNDEFINED;
return contains(other, slot); return contains(other, slot) || contains(other, -1);
} }
// TODO: review redundancy of slot parameter
bool CItemGroup::contains(CDBCtrlSheet *other, SLOT_EQUIPMENT::TSlotEquipment &slot) bool CItemGroup::contains(CDBCtrlSheet *other, SLOT_EQUIPMENT::TSlotEquipment &slot)
{ {
slot = SLOT_EQUIPMENT::UNDEFINED; slot = SLOT_EQUIPMENT::UNDEFINED;
for(int i=0;i<Items.size();i++) for(int i=0;i<EquipItems.size();i++)
{
CItem item = EquipItems[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());
if (sheet.toString() == item.sheetName && other->getQuality() == item.quality &&
other->getItemWeight() == item.weight && other->getItemColor() == item.color &&
(!item.usePrice || (other->getItemPrice() >= item.minPrice && other->getItemPrice() <= item.maxPrice))
)
{
slot = item.slot;
return true;
}
}
return false;
}
// TODO: review redundancy of slot parameter
bool CItemGroup::contains(CDBCtrlSheet *other, uint16 &slot)
{
slot = -1;
for(int i=0;i<HotbarItems.size();i++)
{ {
CItem item = Items[i]; CItem item = HotbarItems[i];
if(item.useCreateTime() && item.createTime == other->getItemCreateTime() && item.serial == other->getItemSerial()) if(item.useCreateTime() && item.createTime == other->getItemCreateTime() && item.serial == other->getItemSerial())
{ {
slot = item.slot; slot = item.slot;
@ -79,19 +108,25 @@ void CItemGroup::addItem(sint32 createTime, sint32 serial, SLOT_EQUIPMENT::TSlot
//Don't add an item if it already exists, this could cause issue //Don't add an item if it already exists, this could cause issue
// It's happening either if we are creating a group with a 2 hands items (and the item is found both in handR and handL) // It's happening either if we are creating a group with a 2 hands items (and the item is found both in handR and handL)
// Or if an user incorrectly edit his group file // Or if an user incorrectly edit his group file
for(int i=0; i<Items.size(); i++) for(int i=0; i<EquipItems.size(); i++)
{ {
if( Items[i].createTime == createTime && Items[i].serial == serial) if( EquipItems[i].createTime == createTime && EquipItems[i].serial == serial)
{ {
nldebug("Not adding duplicate item, createTime: %d, serial: %d", createTime, serial); nldebug("Not adding duplicate item, createTime: %d, serial: %d", createTime, serial);
//In this case, we are adding the duplicate item for a 2 hands item //In this case, we are adding the duplicate item for a 2 hands item
//If it's saved as a left hand item, save it as a right hand item instead (so we have only 1 correct item) //If it's saved as a left hand item, save it as a right hand item instead (so we have only 1 correct item)
if(Items[i].slot == SLOT_EQUIPMENT::HANDL && slot == SLOT_EQUIPMENT::HANDR) if(EquipItems[i].slot == SLOT_EQUIPMENT::HANDL && slot == SLOT_EQUIPMENT::HANDR)
Items[i].slot = SLOT_EQUIPMENT::HANDR; EquipItems[i].slot = SLOT_EQUIPMENT::HANDR;
return; return;
} }
} }
Items.push_back(CItem(createTime, serial, slot)); EquipItems.push_back(CEquipItem(createTime, serial, slot));
}
// used for hotbar
void CItemGroup::addItem(sint32 createTime, sint32 serial, uint16 slot)
{
HotbarItems.push_back(CHotbarItem(createTime, serial, slot));
} }
void CItemGroup::addRemove(std::string slotName) void CItemGroup::addRemove(std::string slotName)
@ -106,13 +141,19 @@ void CItemGroup::addRemove(SLOT_EQUIPMENT::TSlotEquipment slot)
removeBeforeEquip.push_back(slot); removeBeforeEquip.push_back(slot);
} }
// used for hotbar
void CItemGroup::addRemove(uint16 slot)
{
removeHotbar.push_back(slot);
}
void CItemGroup::writeTo(xmlNodePtr node) void CItemGroup::writeTo(xmlNodePtr node)
{ {
xmlNodePtr groupNode = xmlNewChild (node, NULL, (const xmlChar*)"group", NULL ); xmlNodePtr groupNode = xmlNewChild (node, NULL, (const xmlChar*)"group", NULL );
xmlSetProp(groupNode, (const xmlChar*)"name", (const xmlChar*)name.c_str()); xmlSetProp(groupNode, (const xmlChar*)"name", (const xmlChar*)name.c_str());
for(int i=0;i<Items.size();i++) for(int i=0;i<EquipItems.size();i++)
{ {
CItem item = Items[i]; CItem item = EquipItems[i];
xmlNodePtr itemNode = xmlNewChild(groupNode, NULL, (const xmlChar*)"item", NULL); xmlNodePtr itemNode = xmlNewChild(groupNode, NULL, (const xmlChar*)"item", NULL);
if(item.useCreateTime()) if(item.useCreateTime())
{ {
@ -133,11 +174,37 @@ void CItemGroup::writeTo(xmlNodePtr node)
//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<HotbarItems.size();i++)
{
CItem item = HotbarItems[i];
xmlNodePtr itemNode = xmlNewChild(groupNode, NULL, (const xmlChar*)"hotbar_item", NULL);
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());
}
xmlSetProp(itemNode, (const xmlChar*)"slot", (const xmlChar*)NLMISC::toString(item.slot).c_str());
}
for(int i=0;i<removeBeforeEquip.size();i++) for(int i=0;i<removeBeforeEquip.size();i++)
{ {
xmlNodePtr removeNode = xmlNewChild(groupNode, NULL, (const xmlChar*)"remove", NULL); xmlNodePtr removeNode = xmlNewChild(groupNode, NULL, (const xmlChar*)"remove", NULL);
xmlSetProp(removeNode, (const xmlChar*)"slot", (xmlChar*)SLOT_EQUIPMENT::toString(removeBeforeEquip[i]).c_str()); xmlSetProp(removeNode, (const xmlChar*)"slot", (xmlChar*)SLOT_EQUIPMENT::toString(removeBeforeEquip[i]).c_str());
} }
for(int i=0;i<removeHotbar.size();i++)
{
xmlNodePtr removeNode = xmlNewChild(groupNode, NULL, (const xmlChar*)"hotbar_remove", NULL);
xmlSetProp(removeNode, (const xmlChar*)"slot", (xmlChar*)NLMISC::toString(removeHotbar[i]).c_str());
}
} }
@ -152,8 +219,7 @@ void CItemGroup::readFrom(xmlNodePtr node)
{ {
if (strcmp((char*)curNode->name, "item") == 0) if (strcmp((char*)curNode->name, "item") == 0)
{ {
CEquipItem item;
CItem item;
ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"createTime"); ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"createTime");
if (ptrName) NLMISC::fromString((const char*)ptrName, item.createTime); if (ptrName) NLMISC::fromString((const char*)ptrName, item.createTime);
ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"serial"); ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"serial");
@ -183,7 +249,40 @@ void CItemGroup::readFrom(xmlNodePtr node)
// Old load : keep for compatibility / migration reasons // Old load : keep for compatibility / migration reasons
else else
{ {
Items.push_back(item); EquipItems.push_back(item);
}
}
if (strcmp((char*)curNode->name, "hotbar_item") == 0)
{
CHotbarItem 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");
if (ptrName) NLMISC::fromString((const char*)ptrName, item.slot);
// Old read, keep for compatibility reasons
ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"sheetName");
if (ptrName) NLMISC::fromString((const char*)ptrName, item.sheetName);
ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"quality");
if (ptrName) NLMISC::fromString((const char*)ptrName, item.quality);
ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"weight");
if (ptrName) NLMISC::fromString((const char*)ptrName, item.weight);
ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"color");
if (ptrName) NLMISC::fromString((const char*)ptrName, item.color);
ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"minPrice");
if (ptrName) NLMISC::fromString((const char*)ptrName, item.minPrice);
ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"maxPrice");
if (ptrName) NLMISC::fromString((const char*)ptrName, item.maxPrice);
item.usePrice = (item.minPrice != 0 || item.maxPrice != std::numeric_limits<uint32>::max());
if(item.createTime != 0)
{
addItem(item.createTime, item.serial, item.slot);
}
// Old load : keep for compatibility / migration reasons
else
{
HotbarItems.push_back(item);
} }
} }
if (strcmp((char*)curNode->name, "remove") == 0) if (strcmp((char*)curNode->name, "remove") == 0)
@ -193,6 +292,13 @@ void CItemGroup::readFrom(xmlNodePtr node)
if (ptrName) NLMISC::fromString((const char*)ptrName, slot); if (ptrName) NLMISC::fromString((const char*)ptrName, slot);
addRemove(slot); addRemove(slot);
} }
if (strcmp((char*)curNode->name, "hotbar_remove") == 0)
{
uint16 slot;
ptrName = (char*) xmlGetProp(curNode, (xmlChar*)"slot");
if (ptrName) NLMISC::fromString((const char*)ptrName, slot);
addRemove(slot);
}
curNode = curNode->next; curNode = curNode->next;
} }
@ -381,7 +487,7 @@ bool CItemGroupManager::migrateGroups()
{ {
CItemGroup group = _Groups[i]; CItemGroup group = _Groups[i];
//Migrate the group only if there is items inside, and the first one hasn't been migrated //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(); bool needMigration = group.EquipItems.size() > 0 && !group.EquipItems[0].useCreateTime();
if(!needMigration) if(!needMigration)
{ {
newGroups.push_back(group); newGroups.push_back(group);
@ -555,6 +661,13 @@ bool CItemGroupManager::equipGroup(std::string name, bool pullBefore)
dbPath = "LOCAL:INVENTORY:EQUIP:" + NLMISC::toString((uint32)slot); dbPath = "LOCAL:INVENTORY:EQUIP:" + NLMISC::toString((uint32)slot);
CInventoryManager::getInstance()->unequip(dbPath); CInventoryManager::getInstance()->unequip(dbPath);
} }
// unequip hotbar
for(int i=0; i < group->removeHotbar.size(); i++)
{
uint16 slot = group->removeHotbar[i];
std::string dbPath = "LOCAL:INVENTORY:HOTBAR:" + NLMISC::toString(slot);
CInventoryManager::getInstance()->unequip(dbPath);
}
uint32 maxEquipTime = 0; uint32 maxEquipTime = 0;
@ -669,6 +782,19 @@ bool CItemGroupManager::createGroup(std::string name, bool removeUnequiped)
group.addRemove(slot); group.addRemove(slot);
} }
} }
for (i = 0; i < MAX_HOTBARINV_ENTRIES; ++i)
{
pCS = CInventoryManager::getInstance()->getHotbarSheet(i);
if(!pCS) continue;
if(pCS->isSheetValid())
{
group.addItem(pCS->getItemCreateTime(), pCS->getItemSerial(), (uint16) i);
}
else if(removeUnequiped)
{
group.addRemove(i);
}
}
_Groups.push_back(group); _Groups.push_back(group);
return true; return true;
@ -701,7 +827,7 @@ void CItemGroupManager::listGroup()
//Use utf-8 string because group name can contain accentued characters (and stuff like that) //Use utf-8 string because group name can contain accentued characters (and stuff like that)
string nameUC = group.name; string nameUC = group.name;
NLMISC::strFindReplace(msg, "%name", nameUC); NLMISC::strFindReplace(msg, "%name", nameUC);
NLMISC::strFindReplace(msg, "%size", NLMISC::toString(group.Items.size())); NLMISC::strFindReplace(msg, "%size", NLMISC::toString(group.EquipItems.size() + group.HotbarItems.size()));
pIM->displaySystemInfo(msg); pIM->displaySystemInfo(msg);
} }
} }
@ -779,12 +905,22 @@ bool CItemGroupManager::isItemReallyEquipped(CDBCtrlSheet* item)
{ {
return true; return true;
} }
}
for (uint32 i = 0; i < MAX_HOTBARINV_ENTRIES; ++i)
{
pCS = CInventoryManager::getInstance()->getHotbarSheet(i);
if(!pCS) continue;
if((pCS->getInventoryIndex() == item->getInventoryIndex())
&& (pCS->getIndexInDB() == item->getIndexInDB()))
{
return true;
}
} }
return false; return false;
} }
// TODO: review this function
std::vector<CInventoryItem> CItemGroupManager::matchingItems(CItemGroup *group, INVENTORIES::TInventory inventory) std::vector<CInventoryItem> CItemGroupManager::matchingItems(CItemGroup *group, INVENTORIES::TInventory inventory)
{ {
//Not very clean, but no choice, it's ugly time //Not very clean, but no choice, it's ugly time

@ -37,25 +37,40 @@ 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 createTime; sint32 serial;
sint32 serial; // Old variables, present for compatibility reasons
// Old variables, present for compatibility reasons std::string sheetName;
std::string sheetName; uint16 quality;
uint16 quality; uint32 weight;
uint32 weight; uint8 color;
uint8 color; uint32 minPrice;
uint32 minPrice; uint32 maxPrice;
uint32 maxPrice; bool usePrice;
bool usePrice; CItem(sint32 createTime, sint32 serial) :
CItem(sint32 createTime, sint32 serial, SLOT_EQUIPMENT::TSlotEquipment slot = SLOT_EQUIPMENT::UNDEFINED) : createTime(createTime), serial(serial), slot(slot) {}
createTime(createTime), serial(serial), slot(slot) {} //Old constructor, present for compatibility reasons
//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, uint32 minPrice = 0, uint32 maxPrice = std::numeric_limits<uint32>::max(), bool usePrice = false) :
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) {}
sheetName(sheetName), quality(quality), weight(weight), color(color), createTime(createTime), serial(serial), slot(slot), minPrice(minPrice), maxPrice(maxPrice), usePrice(usePrice) {} //present for compatibility reasons
//present for compatibility reasons bool useCreateTime() const { return createTime != 0 && serial != 0;}
bool useCreateTime() const { return createTime != 0 && serial != 0;} };
};
struct CEquipItem : CItem {
SLOT_EQUIPMENT::TSlotEquipment slot; // Used only for dagger (right/left hand slot)
CEquipItem(sint32 createTime, sint32 serial, SLOT_EQUIPMENT::TSlotEquipment slot = SLOT_EQUIPMENT::UNDEFINED) :
CItem(createTime, serial), slot(slot) {}
CEquipItem(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) :
CItem(sheetName, quality, weight, color, createTime, slot, minPrice, maxPrice, usePrice), slot(slot) {}
};
struct CHotbarItem : CItem {
SLOT_EQUIPMENT::TSlotEquipment slot; // Used only for dagger (right/left hand slot)
CHotbarItem(sint32 createTime, sint32 serial, uint16 slot) :
CItem(createTime, serial), slot(slot) {}
CHotbarItem(std::string sheetName = "", uint16 quality = 0, uint32 weight = 0, uint8 color = 0, sint32 createTime = 0, sint32 serial = 0, uint16 slot, uint32 minPrice = 0, uint32 maxPrice = std::numeric_limits<uint32>::max(), bool usePrice = false) :
CItem(sheetName, quality, weight, color, createTime, slot, minPrice, maxPrice, usePrice), slot(slot) {}
};
public: public:
CItemGroup(); CItemGroup();
@ -63,17 +78,22 @@ 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);
bool contains(CDBCtrlSheet* other, uint16 &slot);
void addItem(sint32 createTime, sint32 serial, SLOT_EQUIPMENT::TSlotEquipment slot); void addItem(sint32 createTime, sint32 serial, SLOT_EQUIPMENT::TSlotEquipment slot);
void addItem(sint32 createTime, sint32 serial, uint16 slot);
void addRemove(std::string slotName); void addRemove(std::string slotName);
void addRemove(SLOT_EQUIPMENT::TSlotEquipment slot); void addRemove(SLOT_EQUIPMENT::TSlotEquipment slot);
void addRemove(uint16 slot);
void writeTo(xmlNodePtr node); void writeTo(xmlNodePtr node);
void readFrom(xmlNodePtr node); void readFrom(xmlNodePtr node);
// return true if no item inside // return true if no item inside
bool empty() const { return Items.size() == 0;} bool empty() const { return EquipItems.size() == 0 && HotbarItems.size() == 0;}
std::string name; std::string name;
std::vector<CItem> Items; std::vector<CEquipItem> EquipItems;
std::vector<CHotbarItem> HotbarItems;
std::vector<SLOT_EQUIPMENT::TSlotEquipment> removeBeforeEquip; std::vector<SLOT_EQUIPMENT::TSlotEquipment> removeBeforeEquip;
std::vector<uint16> removeHotbar;
}; };
class CItemGroupManager { class CItemGroupManager {

Loading…
Cancel
Save