diff --git a/common/Item.cpp b/common/Item.cpp index a6241cc5c..62e4d3d91 100644 --- a/common/Item.cpp +++ b/common/Item.cpp @@ -1090,6 +1090,65 @@ void Inventory::dumpBagContents(ItemInst *inst, iter_inst *it) { } +int Inventory::GetSlotByItemInst(ItemInst *inst) { + if(!inst) + return -1; + + int i = GetSlotByItemInstCollection(m_worn, inst); + if(i != -1) { + return i; + } + + i = GetSlotByItemInstCollection(m_inv, inst); + if(i != -1) { + return i; + } + + i = GetSlotByItemInstCollection(m_bank, inst); + if(i != -1) { + return i; + } + + i = GetSlotByItemInstCollection(m_shbank, inst); + if(i != -1) { + return i; + } + + i = GetSlotByItemInstCollection(m_trade, inst); + if(i != -1) { + return i; + } + + auto iter = m_cursor.begin(); + while(iter != m_cursor.end()) { + if((*iter) == inst) { + return SLOT_CURSOR; + } + ++iter; + } + + return -1; +} + +int Inventory::GetSlotByItemInstCollection(const std::map &collection, ItemInst *inst) { + for(auto iter = collection.begin(); iter != collection.end(); ++iter) { + ItemInst *t_inst = iter->second; + if(t_inst == inst) { + return iter->first; + } + + if(t_inst && !t_inst->IsType(ItemClassContainer)) { + for(auto b_iter = t_inst->_begin(); b_iter != t_inst->_end(); ++b_iter) { + if(b_iter->second == inst) { + return Inventory::CalcSlotId(iter->first, b_iter->first); + } + } + } + } + + return -1; +} + void Inventory::dumpItemCollection(const std::map &collection) { iter_inst it; iter_contents itb; @@ -1097,7 +1156,6 @@ void Inventory::dumpItemCollection(const std::map &collection) for (it=collection.begin(); it!=collection.end(); it++) { inst = it->second; - it->first; if(!inst || !inst->GetItem()) continue; diff --git a/common/Item.h b/common/Item.h index 924e50aae..20627593e 100644 --- a/common/Item.h +++ b/common/Item.h @@ -196,6 +196,8 @@ public: // Test whether a given slot can support a container item static bool SupportsContainers(int16 slot_id); + int GetSlotByItemInst(ItemInst *inst); + void dumpEntireInventory(); void dumpWornItems(); void dumpInventory(); @@ -212,6 +214,7 @@ protected: // Protected Methods /////////////////////////////// + int GetSlotByItemInstCollection(const std::map &collection, ItemInst *inst); void dumpItemCollection(const std::map &collection); void dumpBagContents(ItemInst *inst, iter_inst *it); diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index c6105b621..556465862 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -2522,6 +2522,9 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) { uint16 oldexp = e_inst->GetExp(); parse->EventItem(EVENT_ITEM_ENTER_ZONE, this, e_inst, nullptr, "", 0); + if(i < 22 || i == 9999) { + parse->EventItem(EVENT_EQUIP_ITEM, this, e_inst, nullptr, "", i); + } if (e_inst->GetExp() != oldexp) { // if the scaling factor changed, rescale the item and update the client e_inst->ScaleItem(); @@ -2529,6 +2532,10 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) { update_slot = true; } } else { + if(i < 22 || i == 9999) { + parse->EventItem(EVENT_EQUIP_ITEM, this, inst, nullptr, "", i); + } + parse->EventItem(EVENT_ITEM_ENTER_ZONE, this, inst, nullptr, "", 0); } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 420ea4b2b..93084fa76 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -2048,7 +2048,6 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) ) ) { - //Message(13, "Error: the item effect can not be used at this time"); SendSpellBarEnable(spell_id); return; } @@ -2059,7 +2058,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) { ItemInst* p_inst = (ItemInst*)inst; - int i = parse->EventItem(EVENT_ITEM_CLICK, this, p_inst, nullptr, "", slot_id); + parse->EventItem(EVENT_ITEM_CLICK, this, p_inst, nullptr, "", slot_id); inst = m_inv[slot_id]; if(!inst) { @@ -6232,12 +6231,6 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) sizeof(AugmentItem_Struct), app->size); return; } - /*if (m_tradeskill_object == nullptr) { - Message(13, "Error: Server is not aware of the tradeskill container you are attempting to use"); - return; - }*/ - - //fixed this to work for non-world objects // Delegate to tradeskill object to perform combine AugmentItem_Struct* in_augment = (AugmentItem_Struct*)app->pBuffer; diff --git a/zone/embparser.cpp b/zone/embparser.cpp index d6aab2211..9b595d6b1 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -101,7 +101,13 @@ const char *QuestEventSubroutines[_LargestEventID] = { "EVENT_DROP_ITEM", "EVENT_DESTROY_ITEM", "EVENT_FEIGN_DEATH", - "EVENT_WEAPON_PROC" + "EVENT_WEAPON_PROC", + "EVENT_EQUIP_ITEM", + "EVENT_UNEQUIP_ITEM", + "EVENT_AUGMENT_ITEM", + "EVENT_UNAUGMENT_ITEM", + "EVENT_AUGMENT_INSERT", + "EVENT_AUGMENT_REMOVE" }; PerlembParser::PerlembParser() : perl(nullptr), event_queue_in_use_(false) { diff --git a/zone/event_codes.h b/zone/event_codes.h index 94bd94a4c..d916a9635 100644 --- a/zone/event_codes.h +++ b/zone/event_codes.h @@ -70,6 +70,12 @@ typedef enum { EVENT_DESTROY_ITEM, EVENT_FEIGN_DEATH, EVENT_WEAPON_PROC, + EVENT_EQUIP_ITEM, + EVENT_UNEQUIP_ITEM, + EVENT_AUGMENT_ITEM, + EVENT_UNAUGMENT_ITEM, + EVENT_AUGMENT_INSERT, + EVENT_AUGMENT_REMOVE, _LargestEventID } QuestEventID; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index f13525a96..5793e2ae9 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -676,6 +676,8 @@ bool Client::AutoPutLootInInventory(ItemInst& inst, bool try_worn, bool try_curs { SendWearChange(worn_slot_material); } + + parse->EventItem(EVENT_EQUIP_ITEM, this, &inst, nullptr, "", i); return true; } } @@ -1338,6 +1340,26 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { } if(!m_inv.SwapItem(src_slot_id, dst_slot_id)) { return false; } mlog(INVENTORY__SLOTS, "Moving entire item from slot %d to slot %d", src_slot_id, dst_slot_id); + + if(src_slot_id < 22 || src_slot_id == 9999) { + if(src_inst) { + parse->EventItem(EVENT_UNEQUIP_ITEM, this, src_inst, nullptr, "", src_slot_id); + } + + if(dst_inst) { + parse->EventItem(EVENT_EQUIP_ITEM, this, dst_inst, nullptr, "", src_slot_id); + } + } + + if(dst_slot_id < 22 || dst_slot_id == 9999) { + if(dst_inst) { + parse->EventItem(EVENT_UNEQUIP_ITEM, this, dst_inst, nullptr, "", dst_slot_id); + } + + if(src_inst) { + parse->EventItem(EVENT_EQUIP_ITEM, this, src_inst, nullptr, "", dst_slot_id); + } + } } int matslot = SlotConvert2(dst_slot_id); diff --git a/zone/lua_inventory.cpp b/zone/lua_inventory.cpp index d69c873d5..498835926 100644 --- a/zone/lua_inventory.cpp +++ b/zone/lua_inventory.cpp @@ -158,6 +158,10 @@ bool Lua_Inventory::SupportsContainers(int slot_id) { return self->SupportsContainers(slot_id); } +int Lua_Inventory::GetSlotByItemInst(Lua_ItemInst inst) { + Lua_Safe_Call_Int(); + return self->GetSlotByItemInst(inst); +} luabind::scope lua_register_inventory() { return luabind::class_("Inventory") @@ -189,7 +193,8 @@ luabind::scope lua_register_inventory() { .def("CalcSlotFromMaterial", (int(Lua_Inventory::*)(int))&Lua_Inventory::CalcSlotFromMaterial) .def("CalcMaterialFromSlot", (int(Lua_Inventory::*)(int))&Lua_Inventory::CalcMaterialFromSlot) .def("CanItemFitInContainer", (bool(Lua_Inventory::*)(Lua_Item,Lua_Item))&Lua_Inventory::CanItemFitInContainer) - .def("SupportsContainers", (bool(Lua_Inventory::*)(int))&Lua_Inventory::SupportsContainers); + .def("SupportsContainers", (bool(Lua_Inventory::*)(int))&Lua_Inventory::SupportsContainers) + .def("GetSlotByItemInst", (int(Lua_Inventory::*)(Lua_ItemInst))&Lua_Inventory::GetSlotByItemInst); } #endif diff --git a/zone/lua_inventory.h b/zone/lua_inventory.h index 6b8ccb2e1..5033d5e67 100644 --- a/zone/lua_inventory.h +++ b/zone/lua_inventory.h @@ -54,6 +54,7 @@ public: int CalcMaterialFromSlot(int equipslot); bool CanItemFitInContainer(Lua_Item item, Lua_Item container); bool SupportsContainers(int slot_id); + int GetSlotByItemInst(Lua_ItemInst inst); }; #endif diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 929dfedca..a670eeb3a 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -100,7 +100,13 @@ const char *LuaEvents[_LargestEventID] = { "event_drop_item", "event_destroy_item", "event_feign_death", - "event_weapon_proc" + "event_weapon_proc", + "event_equip_item", + "event_unequip_item", + "event_augment_item", + "event_unaugment_item", + "event_augment_insert", + "event_augment_remove" }; extern Zone *zone; @@ -176,6 +182,12 @@ LuaParser::LuaParser() { ItemArgumentDispatch[EVENT_TIMER] = handle_item_timer; ItemArgumentDispatch[EVENT_WEAPON_PROC] = handle_item_proc; ItemArgumentDispatch[EVENT_LOOT] = handle_item_loot; + ItemArgumentDispatch[EVENT_EQUIP_ITEM] = handle_item_equip; + ItemArgumentDispatch[EVENT_UNEQUIP_ITEM] = handle_item_equip; + ItemArgumentDispatch[EVENT_AUGMENT_ITEM] = handle_item_augment; + ItemArgumentDispatch[EVENT_UNAUGMENT_ITEM] = handle_item_augment; + ItemArgumentDispatch[EVENT_AUGMENT_INSERT] = handle_item_augment_reverse; + ItemArgumentDispatch[EVENT_AUGMENT_REMOVE] = handle_item_augment_reverse; SpellArgumentDispatch[EVENT_SPELL_EFFECT_CLIENT] = handle_spell_effect; SpellArgumentDispatch[EVENT_SPELL_BUFF_TIC_CLIENT] = handle_spell_tic; diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index 7e157e10b..5b6ee976d 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -493,6 +493,28 @@ void handle_item_loot(QuestInterface *parse, lua_State* L, Client* client, ItemI } } +void handle_item_equip(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, + std::vector *extra_pointers) { + lua_pushinteger(L, extra_data); + lua_setfield(L, -2, "slot_id"); +} + +void handle_item_augment(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, + std::vector *extra_pointers) { + Lua_ItemInst l_item(reinterpret_cast(extra_pointers->at(0))); + luabind::object l_item_o = luabind::object(L, l_item); + l_item_o.push(L); + lua_setfield(L, -2, "aug"); +} + +void handle_item_augment_reverse(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, + std::vector *extra_pointers) { + Lua_ItemInst l_item(reinterpret_cast(extra_pointers->at(0))); + luabind::object l_item_o = luabind::object(L, l_item); + l_item_o.push(L); + lua_setfield(L, -2, "item"); +} + void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, std::vector *extra_pointers) { } diff --git a/zone/lua_parser_events.h b/zone/lua_parser_events.h index ba6a6113d..058da6511 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -94,6 +94,12 @@ void handle_item_proc(QuestInterface *parse, lua_State* L, Client* client, ItemI std::vector *extra_pointers); void handle_item_loot(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, std::vector *extra_pointers); +void handle_item_equip(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, + std::vector *extra_pointers); +void handle_item_augment(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, + std::vector *extra_pointers); +void handle_item_augment_reverse(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, + std::vector *extra_pointers); void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, std::vector *extra_pointers); diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index 6eaa717ad..dc1a6172d 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -139,9 +139,21 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme // Adding augment if (in_augment->augment_slot == -1) { - if (((slot=tobe_auged->AvailableAugmentSlot(auged_with->GetAugmentType()))!=-1) && (tobe_auged->AvailableWearSlot(auged_with->GetItem()->Slots))) + if (((slot=tobe_auged->AvailableAugmentSlot(auged_with->GetAugmentType()))!=-1) && + (tobe_auged->AvailableWearSlot(auged_with->GetItem()->Slots))) { - tobe_auged->PutAugment(slot,*auged_with); + tobe_auged->PutAugment(slot, *auged_with); + + ItemInst *aug = tobe_auged->GetAugment(slot); + if(aug) { + std::vector args; + args.push_back(aug); + parse->EventItem(EVENT_AUGMENT_ITEM, user, tobe_auged, nullptr, "", slot, &args); + + args.assign(1, tobe_auged); + parse->EventItem(EVENT_AUGMENT_INSERT, user, aug, nullptr, "", slot, &args); + } + itemOneToPush = tobe_auged->Clone(); deleteItems = true; } @@ -152,6 +164,16 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme } else { + ItemInst *aug = tobe_auged->GetAugment(in_augment->augment_slot); + if(aug) { + std::vector args; + args.push_back(aug); + parse->EventItem(EVENT_UNAUGMENT_ITEM, user, tobe_auged, nullptr, "", slot, &args); + + args.assign(1, tobe_auged); + parse->EventItem(EVENT_AUGMENT_REMOVE, user, aug, nullptr, "", slot, &args); + } + ItemInst *old_aug=nullptr; const uint32 id=auged_with->GetID(); if (id==40408 || id==40409 || id==40410) @@ -163,6 +185,8 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme if (old_aug) itemTwoToPush = old_aug->Clone(); + + deleteItems = true; } @@ -197,11 +221,12 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme // Must push items after the items in inventory are deleted - necessary due to lore items... if (itemOneToPush) { - user->PushItemOnCursor(*itemOneToPush,true); + user->PushItemOnCursor(*itemOneToPush, true); } + if (itemTwoToPush) { - user->PushItemOnCursor(*itemTwoToPush,true); + user->PushItemOnCursor(*itemTwoToPush, true); } }