diff --git a/code/ryzom/client/src/continent.cpp b/code/ryzom/client/src/continent.cpp index cf30aeaf6..c1e1177ad 100644 --- a/code/ryzom/client/src/continent.cpp +++ b/code/ryzom/client/src/continent.cpp @@ -1389,10 +1389,3 @@ void CContinent::releaseSky() CurrentSky.release(); } - -//========================================================================= -/*static*/ uint CContinent::getMaxNbUserLandMarks() -{ - uint nbBonusLandmarks = (uint)IngameDbMngr.getProp( "INTERFACES:NB_BONUS_LANDMARKS" ); - return STANDARD_NUM_USER_LANDMARKS + nbBonusLandmarks; -} diff --git a/code/ryzom/client/src/continent.h b/code/ryzom/client/src/continent.h index e925489bf..838054481 100644 --- a/code/ryzom/client/src/continent.h +++ b/code/ryzom/client/src/continent.h @@ -133,9 +133,6 @@ public: }; -const uint STANDARD_NUM_USER_LANDMARKS = 256; // not counting bonus landmarks - - /** * Class to manage the fog of war over a continent * \author Matthieu 'Trap' Besson diff --git a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp index 92e65ac9d..46fea9593 100644 --- a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp +++ b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp @@ -4046,7 +4046,6 @@ void CDBCtrlSheet::setItemPrice(sint32 price) node->setValue32(price); } - // *************************************************************************** sint32 CDBCtrlSheet::getItemResaleFlag() const { @@ -4071,6 +4070,54 @@ void CDBCtrlSheet::setItemResaleFlag(sint32 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(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(root->getNode(ICDBNode::CTextId("SERIAL"), false)); +} + +// *************************************************************************** +void CDBCtrlSheet::setItemSerial(sint32 rf) +{ + CCDBNodeLeaf *node = getItemSerialPtr(); + if (!node) return; + node->setValue32(rf); +} + // *************************************************************************** bool CDBCtrlSheet::getLockedByOwner() const { diff --git a/code/ryzom/client/src/interface_v3/dbctrl_sheet.h b/code/ryzom/client/src/interface_v3/dbctrl_sheet.h index 8c697d660..ad1bc49a9 100644 --- a/code/ryzom/client/src/interface_v3/dbctrl_sheet.h +++ b/code/ryzom/client/src/interface_v3/dbctrl_sheet.h @@ -514,6 +514,18 @@ public: // set item RESALE_FLAG 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 bool getLockedByOwner() const; diff --git a/code/ryzom/client/src/interface_v3/group_compas.cpp b/code/ryzom/client/src/interface_v3/group_compas.cpp index 55cfe895c..7c2b86984 100644 --- a/code/ryzom/client/src/interface_v3/group_compas.cpp +++ b/code/ryzom/client/src/interface_v3/group_compas.cpp @@ -851,14 +851,13 @@ void CGroupCompasMenu::setActive (bool state) { landMarkSubMenu->addSeparatorAtIndex(contLandMarkIndex++); } - // User landmarks - uint nbUserLandMarks = std::min( uint(currCont->UserLandMarks.size()), CContinent::getMaxNbUserLandMarks() ); + // User landmarks // Sort the landmarks std::vector sortedLandmarks(currCont->UserLandMarks); std::sort(sortedLandmarks.begin(), sortedLandmarks.end(), UserLandMarksSortPredicate); - for(k = 0; k < nbUserLandMarks; ++k) + for(k = 0; k < sortedLandmarks.size(); ++k) { if (sortedLandmarks[k].Type < CUserLandMark::UserLandMarkTypeCount) { diff --git a/code/ryzom/client/src/interface_v3/group_map.cpp b/code/ryzom/client/src/interface_v3/group_map.cpp index 2fa37ddb1..e38bb3d62 100644 --- a/code/ryzom/client/src/interface_v3/group_map.cpp +++ b/code/ryzom/client/src/interface_v3/group_map.cpp @@ -2391,9 +2391,8 @@ void CGroupMap::createContinentLandMarks() // Continent Landmarks createLMWidgets(_CurContinent->ContLandMarks); - uint nbUserLandMarks = std::min( uint(_CurContinent->UserLandMarks.size()), CContinent::getMaxNbUserLandMarks()); // User Landmarks - for(k = 0; k < nbUserLandMarks; ++k) + for(k = 0; k < _CurContinent->UserLandMarks.size(); ++k) { NLMISC::CVector2f mapPos; worldToMap(mapPos, _CurContinent->UserLandMarks[k].Pos); @@ -2431,8 +2430,7 @@ void CGroupMap::updateUserLandMarks() removeLandMarks(_UserLM); // Re create User Landmarks - uint nbUserLandMarks = std::min( uint(_CurContinent->UserLandMarks.size()), CContinent::getMaxNbUserLandMarks()); - for(k = 0; k < nbUserLandMarks; ++k) + for(k = 0; k < _CurContinent->UserLandMarks.size(); ++k) { NLMISC::CVector2f mapPos; worldToMap(mapPos, _CurContinent->UserLandMarks[k].Pos); @@ -3263,12 +3261,6 @@ void createUserLandMark(CCtrlBase * /* pCaller */, const string &/* params */) // pop the rename dialog LastClickedMap = dynamic_cast(CWidgetManager::getInstance()->getCtrlLaunchingModal()); if (LastClickedMap->isInDeathMode()) return; - if (LastClickedMap->getNumUserLandMarks() >= CContinent::getMaxNbUserLandMarks() ) - { - // too many landmark, can't create - im->displaySystemInfo(CI18N::get("uiNoMoreLandMarks"), "CHK"); - return; - } LastSelectedLandMark = NULL; popupLandMarkNameDialog(); } diff --git a/code/ryzom/client/src/item_group_manager.cpp b/code/ryzom/client/src/item_group_manager.cpp index 6584060ff..8c18a6e37 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) @@ -417,7 +530,6 @@ bool CItemGroupManager::equipGroup(std::string name, bool pullBefore) {ITEM_TYPE::BRACELET, false}, {ITEM_TYPE::EARING, false}, {ITEM_TYPE::RING, false}, - {ITEM_TYPE::DAGGER, false}, }; std::vector duals; std::vector items = matchingItems(group, INVENTORIES::TInventory::bag); @@ -425,9 +537,10 @@ bool CItemGroupManager::equipGroup(std::string name, bool pullBefore) { CInventoryItem item = items[i]; 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 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 - if(itemType == ITEM_TYPE::DAGGER && item.slot == SLOT_EQUIPMENT::HANDL) + // We'll equip items in left hand later (the right hand will 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 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); continue; @@ -465,6 +578,8 @@ bool CItemGroupManager::equipGroup(std::string name, bool pullBefore) case ITEM_TYPE::RING: dstPath += ":EQUIP:" + NLMISC::toString((int)SLOT_EQUIPMENT::FINGERR);;break; case ITEM_TYPE::DAGGER: + case ITEM_TYPE::BUCKLER: + case ITEM_TYPE::SHIELD: dstPath += ":HAND:1"; break; default: break; @@ -502,8 +617,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