diff --git a/ryzom/client/src/interface_v3/action_handler_item.cpp b/ryzom/client/src/interface_v3/action_handler_item.cpp index f931f1d76..02f8d1633 100644 --- a/ryzom/client/src/interface_v3/action_handler_item.cpp +++ b/ryzom/client/src/interface_v3/action_handler_item.cpp @@ -1079,6 +1079,40 @@ class CCanDropToExchange : public IActionHandler }; REGISTER_ACTION_HANDLER (CCanDropToExchange, "can_drop_to_exchange"); +// ********************************************************************************************************** +class CCanDropToHotbar : public IActionHandler +{ + virtual void execute (CCtrlBase *pCaller, const string &Params) + { + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + nlinfo("hey"); + string src = getParam(Params, "src"); + CInterfaceElement *pElt = CWidgetManager::getInstance()->getElementFromId(src); + CDBCtrlSheet *pCSSrc = dynamic_cast(pElt); + CDBCtrlSheet *pCSDst = dynamic_cast(pCaller); + if (!pCSSrc || !pCSDst) return; + + // Exchange can only be done from bag to exchange inventories + uint32 srcInventory = pCSSrc->getSecondIndexInDB(); + if ( + (srcInventory == INVENTORIES::bag || + srcInventory == INVENTORIES::pet_animal1 || + srcInventory == INVENTORIES::pet_animal2 || + srcInventory == INVENTORIES::pet_animal3 || + srcInventory == INVENTORIES::pet_animal4 || + srcInventory == INVENTORIES::pet_animal5 || + srcInventory == INVENTORIES::pet_animal6 || + srcInventory == INVENTORIES::pet_animal7 || + srcInventory == INVENTORIES::player_room) + && getInventory().isInventoryAvailable((INVENTORIES::TInventory) pCSSrc->getSecondIndexInDB()) + && getInventory().isUsableItem(pCSSrc->getSheetId()) + ) + { + pCSDst->setCanDrop ( true ); + } + } +}; +REGISTER_ACTION_HANDLER (CCanDropToHotbar, "can_drop_to_hotbar"); // ********************************************************************************************************** @@ -2462,6 +2496,58 @@ class CHandlerRingXpCatalyserStopUse : public IActionHandler }; REGISTER_ACTION_HANDLER( CHandlerRingXpCatalyserStopUse, "ring_xp_catalyser_stop_use" ); +// *************************************************************************** +class CHandlerUseHotbarItem : public IActionHandler +{ + void execute(CCtrlBase * /* pCaller */, const std::string &sParams) + { + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + + pIM->displaySystemInfo("use item: " + getParam(sParams, "slot") + " " + sParams); + sint64 slot; + if (!CInterfaceExpr::evalAsInt(getParam(sParams, "slot"), slot)) + { + nlwarning(" Can't retrieve counter."); + return; + } + + if (slot > INVENTORIES::NbHotbarSlots) { + nlwarning(" Slot out of range."); + return; + } + + CDBCtrlSheet *pCS = getInventory().getHotbarSheet(slot); + if (!pCS) + { + nlwarning(" Can't retrieve sheet."); + return; + } + + const CItemSheet *pIS = pCS->asItemSheet(); + if (!pIS) + { + nlwarning(" Can't retrieve item."); + return; + } + + ITEMFAMILY::EItemFamily fam = pIS->Family; + + if (!getInventory().isUsableItem(pCS->getSheetId())) { + nlwarning(" Item is not usable."); + return; + } + + if (fam == ITEMFAMILY::ITEM_SAP_RECHARGE || fam == ITEMFAMILY::CRYSTALLIZED_SPELL) + { + sendToServerEnchantMessage((uint8)pCS->getInventoryIndex(), (uint16)pCS->getIndexInDB()); + } + else if (fam == ITEMFAMILY::CONSUMABLE || fam == ITEMFAMILY::XP_CATALYSER) + { + sendMsgUseItem(uint16(pCS->getIndexInDB())); + } + } +}; +REGISTER_ACTION_HANDLER( CHandlerUseHotbarItem, "use_hotbar_item" ); // *************************************************************************** // item groups diff --git a/ryzom/client/src/interface_v3/dbctrl_sheet.cpp b/ryzom/client/src/interface_v3/dbctrl_sheet.cpp index 0b8cda2ee..6f6b9e519 100644 --- a/ryzom/client/src/interface_v3/dbctrl_sheet.cpp +++ b/ryzom/client/src/interface_v3/dbctrl_sheet.cpp @@ -315,6 +315,7 @@ CCtrlSheetInfo::CCtrlSheetInfo() _ItemSlot= SLOTTYPE::UNDEFINED; _AutoGrayed= false; _HasTradeSlotType = false; + _IsHotbarSlot = false; _BrickOverable= false; _ReadQuantityFromSheet = false; _AHOnLeftClick = NULL; @@ -390,6 +391,10 @@ bool CCtrlSheetInfo::parseCtrlInfo(xmlNodePtr cur, CInterfaceGroup * /* parentGr prop = (char*) xmlGetProp( cur, (xmlChar*)"use_slot_type_db_entry" ); if (prop) _HasTradeSlotType= CInterfaceElement::convertBool(prop); + + prop = (char*) xmlGetProp( cur, (xmlChar*)"hotbar_slot" ); + if (prop) + _IsHotbarSlot= CInterfaceElement::convertBool(prop); // Read Action handlers CAHManager::getInstance()->parseAH(cur, "onclick_l", "params_l", _AHOnLeftClick, _AHLeftClickParams); @@ -3789,6 +3794,11 @@ bool CDBCtrlSheet::canDropItem(CDBCtrlSheet *src) const bf|= 1<getSheetId()) ) + { + return true; + } + // Look if one slot solution match. if( pIS->SlotBF & bf ) { diff --git a/ryzom/client/src/interface_v3/dbctrl_sheet.h b/ryzom/client/src/interface_v3/dbctrl_sheet.h index 2ccbdf00a..ec0104bcb 100644 --- a/ryzom/client/src/interface_v3/dbctrl_sheet.h +++ b/ryzom/client/src/interface_v3/dbctrl_sheet.h @@ -169,6 +169,7 @@ public: // and another in the source slot. Useful for items to buy that are in infinite quantity. bool _AutoGrayed : 1; // if true then gray the ctrlSheeet if: 1/ Items: Is the Item Locked. 2/ Bricks: is the brick Latent. bool _HasTradeSlotType : 1; // true is the SLOT_TYPE DB field should be taken in account + bool _IsHotbarSlot : 1; // true if the slot is part of the hotbar bool _BrickOverable : 1; // if Type is Brick, display like a button (because LeftClickable). @@ -273,6 +274,7 @@ public: uint32 getItemNameId() const { return (uint32)_NameId.getSInt32();} // New Stack Size sint32 getStackable() const { return (_Stackable>1) ? 999 : 1; } + bool isHotbarSlot() const { return _IsHotbarSlot; } // get non locked quantity (can be zero) sint32 getNonLockedQuantity() const; diff --git a/ryzom/client/src/interface_v3/inventory_manager.cpp b/ryzom/client/src/interface_v3/inventory_manager.cpp index 04ad896bc..ccf75c77c 100644 --- a/ryzom/client/src/interface_v3/inventory_manager.cpp +++ b/ryzom/client/src/interface_v3/inventory_manager.cpp @@ -74,6 +74,7 @@ CInventoryManager *CInventoryManager::_Instance = NULL; NLMISC_REGISTER_OBJECT(CViewBase, CDBGroupListSheetBag, std::string, "list_sheet_bag"); NLMISC_REGISTER_OBJECT(CViewBase, CDBGroupIconListBag, std::string, "list_icon_bag"); NLMISC_REGISTER_OBJECT(CViewBase, CDBGroupListSheetFilterCLMSlot, std::string, "list_sheet_filter_clm_slot"); +NLMISC_REGISTER_OBJECT(CViewBase, CDBGroupListSheetFilterHotbarSlot, std::string, "list_sheet_filter_hotbar_slot"); NLMISC_REGISTER_OBJECT(CViewBase, CDBGroupListSheetFilterExchangeable, std::string, "list_sheet_filter_exchangeable"); // *************************************************************************** @@ -323,6 +324,14 @@ CInventoryManager::CInventoryManager() UIEquip2[i] = NULL; } + for (i = 0; i < MAX_HOTBARINV_ENTRIES; ++i) + { + Hotbar[i] = ServerHotbar[i] = 0; + UIHotbar[i] = NULL; + UIHotbar2[i] = NULL; + UIHotbar3[i] = NULL; + } + for (i = 0; i < MAX_BAGINV_ENTRIES; i++) { BagItemEquipped[i]= false; @@ -390,6 +399,16 @@ CItemImage *CInventoryManager::getEquipItem(uint index) return NULL; } +// ************************************************************************************************* +CItemImage *CInventoryManager::getHotbarItem(uint index) +{ + nlassert(index < MAX_HOTBARINV_ENTRIES); + if (Hotbar[index] != 0) + return &Bag[Hotbar[index]]; + else + return NULL; +} + // ************************************************************************************************* CDBCtrlSheet *CInventoryManager::getHandSheet(uint index) { @@ -402,6 +421,11 @@ CDBCtrlSheet *CInventoryManager::getEquipSheet(uint index) return UIEquip[index]; } +// ************************************************************************************************* +CDBCtrlSheet *CInventoryManager::getHotbarSheet(uint index) +{ + return UIHotbar[index]; +} // ************************************************************************************************* CItemImage &CInventoryManager::getServerBagItem(uint index) @@ -480,6 +504,7 @@ void CInventoryManager::init() Money = NLGUI::CDBManager::getInstance()->getDbProp(LOCAL_INVENTORY ":MONEY"); initIndirection (LOCAL_INVENTORY ":HAND:", Hands, MAX_HANDINV_ENTRIES, true); initIndirection (LOCAL_INVENTORY ":EQUIP:", Equip, MAX_EQUIPINV_ENTRIES, true); + initIndirection (LOCAL_INVENTORY ":HOTBAR:", Hotbar, MAX_HOTBARINV_ENTRIES, true); // Init observers for auto equipment { for (uint i = 0; i < MAX_BAGINV_ENTRIES; ++i) @@ -527,6 +552,12 @@ void CInventoryManager::init() UIEquip[SLOT_EQUIPMENT::LEGS] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_ARMOR_LEGS)); UIEquip[SLOT_EQUIPMENT::HANDS] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_ARMOR_HANDS)); + UIHotbar[0] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_HOTBAR_1)); + UIHotbar[1] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_HOTBAR_2)); + UIHotbar[2] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_HOTBAR_3)); + UIHotbar[3] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_HOTBAR_4)); + UIHotbar[4] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_HOTBAR_5)); + UIEquip2[SLOT_EQUIPMENT::HEADDRESS] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_JEWL2_HEADDRESS)); UIEquip2[SLOT_EQUIPMENT::EARL] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_JEWL2_EARING_LEFT)); UIEquip2[SLOT_EQUIPMENT::EARR] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_JEWL2_EARING_RIGHT)); @@ -545,6 +576,17 @@ void CInventoryManager::init() UIEquip2[SLOT_EQUIPMENT::LEGS] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_ARMR2_LEGS)); UIEquip2[SLOT_EQUIPMENT::HANDS] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_ARMR2_HANDS)); + UIHotbar2[0] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_HOTBAR2_1)); + UIHotbar2[1] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_HOTBAR2_2)); + UIHotbar2[2] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_HOTBAR2_3)); + UIHotbar2[3] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_HOTBAR2_4)); + UIHotbar2[4] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_HOTBAR2_5)); + + UIHotbar3[0] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_HOTBAR3_1)); + UIHotbar3[1] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_HOTBAR3_2)); + UIHotbar3[2] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_HOTBAR3_3)); + UIHotbar3[3] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_HOTBAR3_4)); + UIHotbar3[4] = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(CTRL_HOTBAR3_5)); // Init ItemInfoObservers { @@ -671,6 +713,23 @@ std::string CInventoryManager::getDBIndexPath(CDBCtrlSheet *pCS) return string(LOCAL_INVENTORY) + ":EQUIP:" + toString(i); } } + + + for (i = 0; i < MAX_HOTBARINV_ENTRIES; ++i) + { + if (UIHotbar[i] == pCS) + { + return string(LOCAL_INVENTORY) + ":HOTBAR:" + toString(i); + } + if (UIHotbar2[i] == pCS) + { + return string(LOCAL_INVENTORY) + ":HOTBAR:" + toString(i); + } + if (UIHotbar3[i] == pCS) + { + return string(LOCAL_INVENTORY) + ":HOTBAR:" + toString(i); + } + } return ""; } @@ -758,6 +817,20 @@ bool CInventoryManager::isForageToolItem(uint32 sheetID) return result; } +// *************************************************************************** +bool CInventoryManager::isUsableItem(uint32 sheetID) +{ + bool result = false; + CEntitySheet *sheet= SheetMngr.get(CSheetId(sheetID)); + if(sheet && sheet->type()== CEntitySheet::ITEM) + { + CItemSheet *item= (CItemSheet*)sheet; + if( ITEMFAMILY::isUsable(item->Family) ) + result = true; + } + return result; +} + // *************************************************************************** uint32 CInventoryManager::getHandItemSheet( bool rightHand ) const { @@ -1176,7 +1249,7 @@ void CInventoryManager::CDBEquipObs::update(ICDBNode* node) { CInterfaceManager *pIM = CInterfaceManager::getInstance(); string sTmp = node->getFullName(); - string sIE, sIE2; // Interface Element + string sIE, sIE2, sIE3; // Interface Element CCDBNodeLeaf *pNL = dynamic_cast(node); if (pNL == NULL) return; if (strnicmp(sTmp.c_str(),"LOCAL:INVENTORY:HAND",20) == 0) @@ -1245,20 +1318,61 @@ void CInventoryManager::CDBEquipObs::update(ICDBNode* node) // update Equips. getInventory().Equip[index]= pNL->getValue16(); } + else if (strnicmp(sTmp.c_str(),"LOCAL:INVENTORY:HOTBAR",22) == 0) + { + // Coming from hand + sTmp = sTmp.substr(23,sTmp.size()); + sTmp = sTmp.substr(0,sTmp.rfind(':')); + sint index; + fromString(sTmp, index); + switch (index) { + case 0: + sIE = CTRL_HOTBAR_1; + sIE2 = CTRL_HOTBAR2_1; + sIE3 = CTRL_HOTBAR3_1; + break; + case 1: + sIE = CTRL_HOTBAR_2; + sIE2 = CTRL_HOTBAR2_2; + sIE3 = CTRL_HOTBAR3_2; + break; + case 2: + sIE = CTRL_HOTBAR_3; + sIE2 = CTRL_HOTBAR2_3; + sIE3 = CTRL_HOTBAR3_3; + break; + case 3: + sIE = CTRL_HOTBAR_4; + sIE2 = CTRL_HOTBAR2_4; + sIE3 = CTRL_HOTBAR3_4; + break; + case 4: + sIE = CTRL_HOTBAR_5; + sIE2 = CTRL_HOTBAR2_5; + sIE3 = CTRL_HOTBAR3_5; + break; + } + // update Hotbar. + getInventory().Hotbar[index]= pNL->getValue16(); + } else return; // Set database for wearing the right item CDBCtrlSheet *pCS = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(sIE)); CDBCtrlSheet *pCS2 = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(sIE2)); + CDBCtrlSheet *pCS3 = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(sIE3)); // Remove Last reference and update database sint16 oldVal = pNL->getOldValue16(); sint16 newVal = pNL->getValue16(); - if (oldVal != 0) - getInventory().unwearBagItem (oldVal-1); + if (sIE != CTRL_HOTBAR_1 && sIE != CTRL_HOTBAR_2 && sIE != CTRL_HOTBAR_3 && sIE != CTRL_HOTBAR_4 && sIE != CTRL_HOTBAR_5) + { + if (oldVal != 0) + getInventory().unwearBagItem (oldVal-1); - if (newVal != 0) - getInventory().wearBagItem (newVal-1); + if (newVal != 0) + getInventory().wearBagItem (newVal-1); + } // Update Display if (newVal == 0) @@ -1268,12 +1382,14 @@ void CInventoryManager::CDBEquipObs::update(ICDBNode* node) { if (pCS != NULL) pCS->setSheet(""); if (pCS2 != NULL) pCS2->setSheet(""); + if (pCS3 != NULL) pCS3->setSheet(""); } } else { if (pCS != NULL) pCS->setSheet(LOCAL_INVENTORY ":BAG:"+ toString(newVal-1)); if (pCS2 != NULL) pCS2->setSheet(LOCAL_INVENTORY ":BAG:"+ toString(newVal-1)); + if (pCS3 != NULL) pCS3->setSheet(LOCAL_INVENTORY ":BAG:"+ toString(newVal-1)); } // Hands management @@ -1405,6 +1521,7 @@ void CInventoryManager::CDBEquipObs::update(ICDBNode* node) { if (pCS != NULL) pCS->setSheet(""); if (pCS2 != NULL) pCS2->setSheet(""); + if (pCS3 != NULL) pCS3->setSheet(""); } } } @@ -2608,6 +2725,42 @@ bool CDBGroupListSheetFilterCLMSlot::CSheetChildFilter::isSheetValid(CDBGroupLis return false; } +// *************************************************************************** +// CDBGroupListSheetFilterHotbarSlot +// *************************************************************************** + +// *************************************************************************** +bool CDBGroupListSheetFilterHotbarSlot::CSheetChildFilter::isSheetValid(CDBGroupListSheet *pFather) +{ + if (CSheetChild::isSheetValid(pFather)) + { + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + CDBCtrlSheet *clmCtrl = dynamic_cast(CWidgetManager::getInstance()->getCtrlLaunchingModal()); + if (!clmCtrl || !Ctrl) return false; + if (clmCtrl->getInventoryIndex() == INVENTORIES::exchange && + Ctrl->getInventoryIndex() == INVENTORIES::exchange) + { + return false; + } + if ((clmCtrl->getType() == CCtrlSheetInfo::SheetType_Item) && + (Ctrl->getType() == CCtrlSheetInfo::SheetType_Item) ) + { + // Ok if we can put in the slot Ctrl in clmCtrl + if ( clmCtrl->canDropItem(Ctrl)) + { + string sTmp = Ctrl->getSheet(); + // Look if the source is locked + sTmp = sTmp.substr(sTmp.rfind(':')+1,sTmp.size()); + sint32 nTmp; + fromString(sTmp, nTmp); + if (!getInventory().isBagItemWeared(nTmp) && getInventory().isUsableItem(Ctrl->getSheetId()) && Ctrl->getLockedByOwner() == 0) + return true; + } + } + } + return false; +} + // *************************************************************************** // CDBGroupListSheetFilterExchangeable // *************************************************************************** @@ -3121,10 +3274,11 @@ class CHandlerInvCannotDrop : public IActionHandler // Is the dragged sheet comes from a slot if (!getInventory().isDraggingFromTextList()) { - // Unequip CDBCtrlSheet *pCSDst = dynamic_cast(pCaller); - string invPath = getInventory().getDBIndexPath(pCSDst); - getInventory().unequip(invPath); + if (!pCSDst->isHotbarSlot()) { + string invPath = getInventory().getDBIndexPath(pCSDst); + getInventory().unequip(invPath); + } } getInventory().endDrag(); } @@ -3132,6 +3286,207 @@ class CHandlerInvCannotDrop : public IActionHandler REGISTER_ACTION_HANDLER( CHandlerInvCannotDrop, "inv_cannot_drop" ); +// *************************************************************************** +class CHandlerHotbarDropTo : public IActionHandler +{ + virtual void execute (CCtrlBase *pCaller, const string &Params) + { + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + + // Check that we have drag'n'drop from inventory (list or slot) + // Or if we have launched the choose_bag modal + // To prevent other things to happens + string src = getParam(Params, "src"); + CInterfaceElement *pElt = CWidgetManager::getInstance()->getElementFromId(src); + CDBCtrlSheet *pCSSrc = dynamic_cast(pElt); + CDBCtrlSheet *pCSDst = dynamic_cast(pCaller); + CAHManager::getInstance()->runActionHandler("swap_item", pCSDst, "src="+toString(pCSSrc->getId())); + getInventory().endDrag(); + // if (!getInventory().isDragging()) + // { + // CInterfaceGroup *pIG = CWidgetManager::getInstance()->getModalWindow(); + // if (pIG == NULL) return; + // if (pIG->getId() != "ui:interface:bag_choose") return; + // getInventory().beginDrag(NULL, CInventoryManager::TextList); + + // // Special case for choose in bag dialog + // string src = getParam(Params, "src"); + // CInterfaceElement *pElt = CWidgetManager::getInstance()->getElementFromId(src); + // CDBCtrlSheet *pCSSrc = dynamic_cast(pElt); + // CDBCtrlSheet *pCSDst = dynamic_cast(pCaller); + + // string invPath = getInventory().getDBIndexPath(pCSSrc); + // string bagPath = pCSDst->getSheet(); + + // if (bagPath == "UI:EMPTY") + // CAHManager::getInstance()->runActionHandler("swap_item", pCSDst, "src="+toString(pCSSrc->getId())); + // else + // getInventory().equip (bagPath, invPath); + + // getInventory().endDrag(); + // return; + // } + + // string src = getParam(Params, "src"); + // CInterfaceElement *pElt = CWidgetManager::getInstance()->getElementFromId(src); + // CDBCtrlSheet *pCSSrc = dynamic_cast(pElt); + // CDBCtrlSheet *pCSDst = dynamic_cast(pCaller); + // if (pCSSrc == NULL) return; + + // // Is the dragged sheet comes from an inventory list + // if (getInventory().isDraggingFromTextList() || getInventory().isDraggingFromIconList()) + // { + // // If the destination is an equipment slot ? + // if (pCSDst != NULL) + // { + // string invPath = getInventory().getDBIndexPath(pCSDst); // Get the index in the equipment + // if (!invPath.empty()) + // { + // // Drop to the slot ie write the database with the index of the slot + // string bagPath = pCSSrc->getSheet(); // Get the database branch of the dragged sheet + + // if (pCSSrc && pCSSrc->getType() == CCtrlSheetInfo::SheetType_Item) + // if (pCSDst && pCSDst->getType() == CCtrlSheetInfo::SheetType_Item) + // { + // // If the destination slot match with the type of incoming item + // if (pCSDst->canDropItem(pCSSrc)) + // { + // // So directly equip + // getInventory().equip(bagPath, invPath); + // } + // else + // { + // // Else try to auto equip the player with the incoming item + // const string sTmp = bagPath.substr(bagPath.rfind(':')+1,bagPath.size()); + // sint index; + // fromString(sTmp, index); + // if (!getInventory().autoEquip(index, false)) + // getInventory().autoEquip(index, true); + // } + // } + // getInventory().endDrag(); + // return; + // } + // } + + // // If the destination is a list sheet + // IListSheetBase *pListDst = dynamic_cast(pCaller); + // if ((pListDst == NULL) && (pCSDst != NULL)) + // pListDst = IListSheetBase::getListContaining(pCSDst); + // IListSheetBase *pListSrc = IListSheetBase::getListContaining(pCSSrc); + // if ((pListDst != NULL) && (pListSrc != NULL)) + // { + // // If the source list and destination list are the same + // if (pListDst == pListSrc) + // { + // // no op + // getInventory().endDrag(); + // return; + // } + // else // Source list and destination list are not the same + // { + // // Move the item to the destination list using the procedure move_to_xxx + // CDBGroupListSheetBag *pListDstText = dynamic_cast(pListDst); + // CDBGroupIconListBag *pListDstIcon = dynamic_cast(pListDst); + + // if (((pListDstText != NULL) && (pListDstText->getInvType() == CInventoryManager::InvBag)) || + // ((pListDstIcon != NULL) && (pListDstIcon->getInvType() == CInventoryManager::InvBag))) + // { + // CAHManager::getInstance()->runActionHandler("proc", pCSSrc, "move_to_bag"); + // } + // else if (((pListDstText != NULL) && ((pListDstText->getInvType() == CInventoryManager::InvPA0) || + // (pListDstText->getInvType() == CInventoryManager::InvPA1) || + // (pListDstText->getInvType() == CInventoryManager::InvPA2) || + // (pListDstText->getInvType() == CInventoryManager::InvPA3) || + // (pListDstText->getInvType() == CInventoryManager::InvPA4) || + // (pListDstText->getInvType() == CInventoryManager::InvPA5) || + // (pListDstText->getInvType() == CInventoryManager::InvPA6) + // )) || + // ((pListDstIcon != NULL) && ((pListDstIcon->getInvType() == CInventoryManager::InvPA0) || + // (pListDstIcon->getInvType() == CInventoryManager::InvPA1) || + // (pListDstIcon->getInvType() == CInventoryManager::InvPA2) || + // (pListDstIcon->getInvType() == CInventoryManager::InvPA3) || + // (pListDstIcon->getInvType() == CInventoryManager::InvPA4) || + // (pListDstIcon->getInvType() == CInventoryManager::InvPA5) || + // (pListDstIcon->getInvType() == CInventoryManager::InvPA6) + // ))) + // { + // string sTmp; + // if (pListDstText != NULL) sTmp = toString("%d",pListDstText->getInvType()-CInventoryManager::InvPA0); + // if (pListDstIcon != NULL) sTmp = toString("%d",pListDstIcon->getInvType()-CInventoryManager::InvPA0); + // nlinfo("ici :%s", sTmp.c_str()); + // CAHManager::getInstance()->runActionHandler("proc", pCSSrc, "move_to_pa|"+sTmp); + // } + // else if (((pListDstText != NULL) && (pListDstText->getInvType() == CInventoryManager::InvGuild)) || + // ((pListDstIcon != NULL) && (pListDstIcon->getInvType() == CInventoryManager::InvGuild))) + // { + // CAHManager::getInstance()->runActionHandler("proc", pCSSrc, "move_to_guild"); + // } + // else if (((pListDstText != NULL) && (pListDstText->getInvType() == CInventoryManager::InvRoom)) || + // ((pListDstIcon != NULL) && (pListDstIcon->getInvType() == CInventoryManager::InvRoom))) + // { + // CAHManager::getInstance()->runActionHandler("proc", pCSSrc, "move_to_room"); + // } + // } + // } + // } + + // // Is the dragged sheet comes from another slot + // if (pCSDst != NULL) + // if (getInventory().isDraggingFromSlot()) + // { + // CAHManager::getInstance()->runActionHandler("swap_item", pCSDst, "src="+toString(pCSSrc->getId())); + // } + + // CAHManager::getInstance()->runActionHandler("inv_cannot_drop", pCSSrc); + } +}; +REGISTER_ACTION_HANDLER( CHandlerHotbarDropTo, "hotbar_drop" ); + +// ********************************************************************************************************** +class CHotbarLeftClickOnSlotHandler : public IActionHandler +{ + virtual void execute (CCtrlBase *pCaller, const string &/* Params */) + { + CDBCtrlSheet *sheet = dynamic_cast(pCaller); + if (!sheet) return; + if (sheet->getSheetId() == 0) + { + // is there's no item that is not worn, can't choose any item) + bool isThereObjectNotWorn = false; + for(uint k = 0; k < MAX_BAGINV_ENTRIES; ++k) + { + uint32 sheetid = getInventory().getBagItem(k).getSheetID(); + if (sheetid != 0) + { + if (!getInventory().isBagItemWeared(k)) + { + CEntitySheet *pES = SheetMngr.get(CSheetId(sheetid)); + if (pES && pES->type()== CEntitySheet::ITEM) + { + CItemSheet *pIS = (CItemSheet*)pES; + if (getInventory().isUsableItem(sheetid)) + { + isThereObjectNotWorn = true; + break; + } + } + } + } + } + + if (!isThereObjectNotWorn) + { + // every object are worn, so there's no use to display an empty list -> no-op + return; + } + } + CInterfaceManager *im = CInterfaceManager::getInstance(); + CWidgetManager::getInstance()->pushModalWindow(pCaller, "ui:interface:hotbar_choose"); + } +}; +REGISTER_ACTION_HANDLER(CHotbarLeftClickOnSlotHandler, "hotbar_left_click_on_slot"); + // *************************************************************************** class CHandlerInvAutoEquip : public IActionHandler { diff --git a/ryzom/client/src/interface_v3/inventory_manager.h b/ryzom/client/src/interface_v3/inventory_manager.h index d5bd763f1..1de2a674b 100644 --- a/ryzom/client/src/interface_v3/inventory_manager.h +++ b/ryzom/client/src/interface_v3/inventory_manager.h @@ -41,6 +41,7 @@ const uint MAX_TEMPINV_ENTRIES = INVENTORIES::NbTempInvSlots; const uint MAX_BAGINV_ENTRIES = INVENTORIES::NbBagSlots; const uint MAX_HANDINV_ENTRIES = 2; const uint MAX_EQUIPINV_ENTRIES = 19; +const uint MAX_HOTBARINV_ENTRIES = INVENTORIES::NbHotbarSlots; const uint MAX_ANIMALINV_ENTRIES = INVENTORIES::NbPackerSlots; const uint MAX_GUILDINV_ENTRIES = INVENTORIES::NbGuildSlots; const uint MAX_ROOMINV_ENTRIES = INVENTORIES::NbRoomSlots; @@ -193,10 +194,14 @@ public: CItemImage *getHandItem(uint index); // get equip item (local inventory) CItemImage *getEquipItem(uint index); + // get hotbar item (local inventory) + CItemImage *getHotbarItem(uint index); // get hand item (local inventory) CDBCtrlSheet *getHandSheet(uint index); // get equip item (local inventory) CDBCtrlSheet *getEquipSheet(uint index); + // get hotbar item (local inventory) + CDBCtrlSheet *getHotbarSheet(uint index); // get/set money uint64 getMoney() const; void setMoney(uint64 value); @@ -250,6 +255,8 @@ public: bool isSword(uint32 sheetID); // Check if an item is a forage tool bool isForageToolItem(uint32 sheetID); + // Check if an item is usable + bool isUsableItem(uint32 sheetID); // Get the Hand item sheet uint32 getRightHandItemSheet() const { return getHandItemSheet(true); } uint32 getLeftHandItemSheet() const { return getHandItemSheet(false); } @@ -336,6 +343,10 @@ private: sint32 Equip[MAX_EQUIPINV_ENTRIES]; CDBCtrlSheet *UIEquip[MAX_EQUIPINV_ENTRIES]; CDBCtrlSheet *UIEquip2[MAX_EQUIPINV_ENTRIES]; + sint32 Hotbar[MAX_HOTBARINV_ENTRIES]; + CDBCtrlSheet *UIHotbar[MAX_HOTBARINV_ENTRIES]; + CDBCtrlSheet *UIHotbar2[MAX_HOTBARINV_ENTRIES]; + CDBCtrlSheet *UIHotbar3[MAX_HOTBARINV_ENTRIES]; NLMISC::CCDBNodeLeaf *Money; CItemImage PAInv[MAX_INVENTORY_ANIMAL][MAX_ANIMALINV_ENTRIES]; // SERVER INVENTORY @@ -343,6 +354,7 @@ private: CItemImage ServerTempInv[MAX_TEMPINV_ENTRIES]; sint32 ServerHands[MAX_HANDINV_ENTRIES]; sint32 ServerEquip[MAX_EQUIPINV_ENTRIES]; + sint32 ServerHotbar[MAX_EQUIPINV_ENTRIES]; NLMISC::CCDBNodeLeaf *ServerMoney; CItemImage ServerPAInv[MAX_INVENTORY_ANIMAL][MAX_ANIMALINV_ENTRIES]; // Drag'n'Drop @@ -745,6 +757,25 @@ public: }; }; +// *************************************************************************** +/** + * Special list for filtering items which are usable + */ +class CDBGroupListSheetFilterHotbarSlot : public CDBGroupListSheet +{ +public: + CDBGroupListSheetFilterHotbarSlot (const TCtorParam ¶m) + : CDBGroupListSheet(param) + {} + + virtual CSheetChild *createSheetChild() { return new CSheetChildFilter; } + + // A child node + struct CSheetChildFilter : public CDBGroupListSheet::CSheetChild + { + virtual bool isSheetValid(CDBGroupListSheet *pFather); + }; +}; // *************************************************************************** /** @@ -861,6 +892,12 @@ private: #define CTRL_ARMOR_ARMS "ui:interface:inv_equip:content:equip:armors:arms" #define CTRL_ARMOR_HANDS "ui:interface:inv_equip:content:equip:armors:hands" +#define CTRL_HOTBAR_1 "ui:interface:inv_equip:content:equip:hotbar_c:hotbar:hotbar1" +#define CTRL_HOTBAR_2 "ui:interface:inv_equip:content:equip:hotbar_c:hotbar:hotbar2" +#define CTRL_HOTBAR_3 "ui:interface:inv_equip:content:equip:hotbar_c:hotbar:hotbar3" +#define CTRL_HOTBAR_4 "ui:interface:inv_equip:content:equip:hotbar_c:hotbar:hotbar4" +#define CTRL_HOTBAR_5 "ui:interface:inv_equip:content:equip:hotbar_c:hotbar:hotbar5" + #define CTRL_JEWL2_EARING_LEFT "ui:interface:inventory:content:equip:jewelry:earing_l" #define CTRL_JEWL2_BRACELET_LEFT "ui:interface:inventory:content:equip:jewelry:bracelet_l" #define CTRL_JEWL2_RING_LEFT "ui:interface:inventory:content:equip:jewelry:ring_l" @@ -879,6 +916,18 @@ private: #define CTRL_ARMR2_ARMS "ui:interface:inventory:content:equip:armors:arms" #define CTRL_ARMR2_HANDS "ui:interface:inventory:content:equip:armors:hands" +#define CTRL_HOTBAR2_1 "ui:interface:inventory:content:equip:hotbar_c:hotbar:hotbar1" +#define CTRL_HOTBAR2_2 "ui:interface:inventory:content:equip:hotbar_c:hotbar:hotbar2" +#define CTRL_HOTBAR2_3 "ui:interface:inventory:content:equip:hotbar_c:hotbar:hotbar3" +#define CTRL_HOTBAR2_4 "ui:interface:inventory:content:equip:hotbar_c:hotbar:hotbar4" +#define CTRL_HOTBAR2_5 "ui:interface:inventory:content:equip:hotbar_c:hotbar:hotbar5" + +#define CTRL_HOTBAR3_1 "ui:interface:inv_hotbar:content:hot:hotbar:hotbar1" +#define CTRL_HOTBAR3_2 "ui:interface:inv_hotbar:content:hot:hotbar:hotbar2" +#define CTRL_HOTBAR3_3 "ui:interface:inv_hotbar:content:hot:hotbar:hotbar3" +#define CTRL_HOTBAR3_4 "ui:interface:inv_hotbar:content:hot:hotbar:hotbar4" +#define CTRL_HOTBAR3_5 "ui:interface:inv_hotbar:content:hot:hotbar:hotbar5" + #endif // RY_INVENTORY_MANAGER_H /* End of inventory_manager.h */ diff --git a/ryzom/common/src/game_share/inventories.cpp b/ryzom/common/src/game_share/inventories.cpp index d6b4b5ba9..f4ee24915 100644 --- a/ryzom/common/src/game_share/inventories.cpp +++ b/ryzom/common/src/game_share/inventories.cpp @@ -49,6 +49,7 @@ namespace INVENTORIES NL_STRING_CONVERSION_TABLE_ENTRY(reward_sharing) NL_STRING_CONVERSION_TABLE_ENTRY(guild) NL_STRING_CONVERSION_TABLE_ENTRY(player_room) + NL_STRING_CONVERSION_TABLE_ENTRY(hotbar) NL_END_STRING_CONVERSION_TABLE(TInventory, InventoryToString, UNDEFINED) @@ -108,6 +109,7 @@ namespace INVENTORIES // "", // exchange_proposition "", // guild "", // player_room + "HOTBAR", // hotbar "" // unknown }; diff --git a/ryzom/common/src/game_share/inventories.h b/ryzom/common/src/game_share/inventories.h index f99dd5331..076038950 100644 --- a/ryzom/common/src/game_share/inventories.h +++ b/ryzom/common/src/game_share/inventories.h @@ -178,6 +178,7 @@ namespace INVENTORIES reward_sharing, // 15 fake inventory, not in database.xml. Used by the item info protocol only guild, // 16 (warning: number stored in guild saved file) player_room, // 17 + hotbar, // 18 NUM_ALL_INVENTORY // warning: distinct from NUM_INVENTORY }; @@ -262,6 +263,7 @@ namespace INVENTORIES const uint NbRoomSlots = 1000; const uint NbGuildSlots = 1000; const uint NbTempInvSlots = 16; + const uint NbHotbarSlots = 5; enum TItemPropId { diff --git a/ryzom/common/src/game_share/item_family.cpp b/ryzom/common/src/game_share/item_family.cpp index 695225b11..d8ee8a25e 100644 --- a/ryzom/common/src/game_share/item_family.cpp +++ b/ryzom/common/src/game_share/item_family.cpp @@ -124,6 +124,16 @@ namespace ITEMFAMILY } + bool isUsable( EItemFamily fam ) + { + return + fam == ITEM_SAP_RECHARGE || + fam == CRYSTALLIZED_SPELL || + fam == CONSUMABLE || + fam == XP_CATALYSER; + + } + /** * returns true if items of this family are destroyed when they are completely worned out */ diff --git a/ryzom/common/src/game_share/item_family.h b/ryzom/common/src/game_share/item_family.h index 3237ad7c8..ec9d25e97 100644 --- a/ryzom/common/src/game_share/item_family.h +++ b/ryzom/common/src/game_share/item_family.h @@ -98,6 +98,8 @@ namespace ITEMFAMILY bool isResellable( EItemFamily fam ); /// return true if this family of item can display a custom text bool isTextCustomizable( EItemFamily fam ); + /// return true if this family of item can use item (consume, execute, open, etc) + bool isUsable( EItemFamily fam ); /// is craftable }; // ITEMFAMILY