From caae34ac5e4ee08459702ee8ef2cc3530302c465 Mon Sep 17 00:00:00 2001 From: regneq Date: Fri, 5 Apr 2024 18:01:48 -0700 Subject: [PATCH] fixed client lua summonitem. export npc:CanTalk to lua. added QuestSlot. Added a condition for questslot in summonitem function. --- common/emu_constants.h | 2 ++ common/patches/rof2_limits.h | 2 ++ common/patches/rof_limits.h | 2 ++ common/patches/sod_limits.h | 2 ++ common/patches/sof_limits.h | 2 ++ common/patches/titanium_limits.h | 2 ++ common/patches/uf_limits.h | 2 ++ zone/attack.cpp | 3 +++ zone/inventory.cpp | 30 +++++++++++++++++++++++++++++- zone/lua_client.cpp | 18 ++++++++++++------ zone/lua_client.h | 5 +++-- zone/lua_npc.cpp | 7 +++++++ zone/lua_npc.h | 1 + zone/trading.cpp | 13 +++++++++++++ 14 files changed, 82 insertions(+), 9 deletions(-) diff --git a/common/emu_constants.h b/common/emu_constants.h index 5f7caeb71..90ed67b97 100644 --- a/common/emu_constants.h +++ b/common/emu_constants.h @@ -89,6 +89,8 @@ namespace EQ using RoF2::invslot::SLOT_INVALID; using RoF2::invslot::SLOT_BEGIN; + using RoF2::invslot::SLOT_QUEST; + using Titanium::invslot::SLOT_TRADESKILL_EXPERIMENT_COMBINE; const int16 SLOT_AUGMENT_GENERIC_RETURN = 1001; // clients don't appear to use this method... (internal inventory return value) diff --git a/common/patches/rof2_limits.h b/common/patches/rof2_limits.h index fa5f551d1..908913e6b 100644 --- a/common/patches/rof2_limits.h +++ b/common/patches/rof2_limits.h @@ -165,6 +165,8 @@ namespace RoF2 const int16 SLOT_INVALID = IINVALID; const int16 SLOT_BEGIN = INULL; + const int16 SLOT_QUEST = 9999; + const int16 POSSESSIONS_BEGIN = slotCharm; const int16 POSSESSIONS_END = slotCursor; const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1; diff --git a/common/patches/rof_limits.h b/common/patches/rof_limits.h index 4df54d1c2..ec7506009 100644 --- a/common/patches/rof_limits.h +++ b/common/patches/rof_limits.h @@ -162,6 +162,8 @@ namespace RoF const int16 SLOT_INVALID = IINVALID; const int16 SLOT_BEGIN = INULL; + const int16 SLOT_QUEST = 9999; + const int16 POSSESSIONS_BEGIN = slotCharm; const int16 POSSESSIONS_END = slotCursor; const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1; diff --git a/common/patches/sod_limits.h b/common/patches/sod_limits.h index 46d8293fe..1c46f715e 100644 --- a/common/patches/sod_limits.h +++ b/common/patches/sod_limits.h @@ -152,6 +152,8 @@ namespace SoD const int16 SLOT_TRADESKILL_EXPERIMENT_COMBINE = 1000; + const int16 SLOT_QUEST = 9999; + const int16 POSSESSIONS_BEGIN = slotCharm; const int16 POSSESSIONS_END = slotCursor; const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1; diff --git a/common/patches/sof_limits.h b/common/patches/sof_limits.h index 063644e18..fa4a06307 100644 --- a/common/patches/sof_limits.h +++ b/common/patches/sof_limits.h @@ -152,6 +152,8 @@ namespace SoF const int16 SLOT_TRADESKILL_EXPERIMENT_COMBINE = 1000; + const int16 SLOT_QUEST = 9999; + const int16 POSSESSIONS_BEGIN = slotCharm; const int16 POSSESSIONS_END = slotCursor; const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1; diff --git a/common/patches/titanium_limits.h b/common/patches/titanium_limits.h index 09d3d99ca..76867c89d 100644 --- a/common/patches/titanium_limits.h +++ b/common/patches/titanium_limits.h @@ -151,6 +151,8 @@ namespace Titanium const int16 SLOT_TRADESKILL_EXPERIMENT_COMBINE = 1000; + const int16 SLOT_QUEST = 9999; + const int16 POSSESSIONS_BEGIN = slotCharm; const int16 POSSESSIONS_END = slotCursor; const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1; diff --git a/common/patches/uf_limits.h b/common/patches/uf_limits.h index 978699ed2..d6edfc95e 100644 --- a/common/patches/uf_limits.h +++ b/common/patches/uf_limits.h @@ -152,6 +152,8 @@ namespace UF const int16 SLOT_TRADESKILL_EXPERIMENT_COMBINE = 1000; + const int16 SLOT_QUEST = 9999; + const int16 POSSESSIONS_BEGIN = slotCharm; const int16 POSSESSIONS_END = slotCursor; const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1; diff --git a/zone/attack.cpp b/zone/attack.cpp index 238b1d5bd..3fdb209c5 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -2816,6 +2816,9 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy entity_list.RemoveFromAutoXTargets(this); + // Here we create the corpse. + DeleteInvalidQuestLoot(); + corpse = new Corpse( this, &m_loot_items, diff --git a/zone/inventory.cpp b/zone/inventory.cpp index c1f74f140..f41173318 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -601,7 +601,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, inst->SetOrnamentHeroModel(ornament_hero_model); // check to see if item is usable in requested slot - if (enforce_usable && (to_slot >= EQ::invslot::EQUIPMENT_BEGIN && to_slot <= EQ::invslot::EQUIPMENT_END)) { + if (enforce_usable && to_slot != EQ::invslot::SLOT_QUEST && (to_slot >= EQ::invslot::EQUIPMENT_BEGIN && to_slot <= EQ::invslot::EQUIPMENT_END)) { uint32 slottest = to_slot; if(!(slots & ((uint32)1 << slottest))) { Message( @@ -648,6 +648,34 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, RecordPlayerEventLog(PlayerEvent::ITEM_CREATION, e); } + //We're coming from a quest method. + if (to_slot == EQ::invslot::SLOT_QUEST) { + bool stacking = TryStacking(inst); + if (stacking) { + safe_delete(inst); + return true; + } + else { + bool bag = false; + if (inst->IsClassBag()) { + bag = true; + } + to_slot = m_inv.FindFreeSlot(bag, true, item->Size); + + //make sure we are not completely full... + if (to_slot == EQ::invslot::slotCursor || to_slot == INVALID_INDEX) { + if (inst->GetItem()->NoDrop == 0) { + //If it's no drop, force it to the cursor. This carries the risk of deletion if the player already has this item on their cursor + // or if the cursor queue is full. But in this situation, we have little other recourse. + PushItemOnCursor(*inst); + LogInventory("{} has a full inventory and {} is a no drop item. Forcing to cursor", GetName(), inst->GetItem()->Name); + safe_delete(inst); + } + } + + } + } + // put item into inventory if (to_slot == EQ::invslot::slotCursor) { diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index a4268f44c..cae803493 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -955,14 +955,19 @@ void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5); } -void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, bool attuned) { +void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6) { Lua_Safe_Call_Void(); - self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, 0, attuned); + self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, aug6); } -void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, bool attuned, int to_slot) { +void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, bool attuned) { Lua_Safe_Call_Void(); - self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, 0, attuned, to_slot); + self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, aug6, 0, attuned); +} + +void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, bool attuned, int to_slot) { + Lua_Safe_Call_Void(); + self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, aug6, 0, attuned, to_slot); } void Lua_Client::SetStats(int type, int value) { @@ -3863,8 +3868,9 @@ luabind::scope lua_register_client() { .def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32))&Lua_Client::SummonItem) .def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32))&Lua_Client::SummonItem) .def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32))&Lua_Client::SummonItem) - .def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,bool))&Lua_Client::SummonItem) - .def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,bool,int))&Lua_Client::SummonItem) + .def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,uint32))&Lua_Client::SummonItem) + .def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,uint32,bool))&Lua_Client::SummonItem) + .def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,uint32,bool,int))&Lua_Client::SummonItem) .def("SummonItemIntoInventory", (void(Lua_Client::*)(luabind::adl::object))&Lua_Client::SummonItemIntoInventory) .def("TGB", (bool(Lua_Client::*)(void))&Lua_Client::TGB) .def("TakeMoneyFromPP", (bool(Lua_Client::*)(uint64))&Lua_Client::TakeMoneyFromPP) diff --git a/zone/lua_client.h b/zone/lua_client.h index 89d4be016..8a19fa34d 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -251,9 +251,10 @@ public: void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3); void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4); void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5); - void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, + void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6); + void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, bool attuned); - void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, + void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, bool attuned, int to_slot); void SummonBaggedItems(uint32 bag_item_id, luabind::adl::object bag_items_table); void SetStats(int type, int value); diff --git a/zone/lua_npc.cpp b/zone/lua_npc.cpp index d3772674c..cd6d13e90 100644 --- a/zone/lua_npc.cpp +++ b/zone/lua_npc.cpp @@ -920,6 +920,12 @@ int Lua_NPC::QuestLootCount(int itemid) return self->CountQuestItem(itemid); } +bool Lua_NPC::CanTalk() +{ + Lua_Safe_Call_Bool(); + return self->CanTalk(); +} + luabind::scope lua_register_npc() { return luabind::class_("NPC") .def(luabind::constructor<>()) @@ -946,6 +952,7 @@ luabind::scope lua_register_npc() { .def("AddPetLoot", (void(Lua_NPC:: *)(int, int)) & Lua_NPC::AddPetLoot) .def("AssignWaypoints", (void(Lua_NPC::*)(int))&Lua_NPC::AssignWaypoints) .def("CalculateNewWaypoint", (void(Lua_NPC::*)(void))&Lua_NPC::CalculateNewWaypoint) + .def("CanTalk", (bool(Lua_NPC:: *)(void)) & Lua_NPC::CanTalk) .def("ChangeLastName", (void(Lua_NPC::*)(std::string))&Lua_NPC::ChangeLastName) .def("CheckNPCFactionAlly", (int(Lua_NPC::*)(int))&Lua_NPC::CheckNPCFactionAlly) .def("ClearItemList", (void(Lua_NPC::*)(void))&Lua_NPC::ClearLootItems) diff --git a/zone/lua_npc.h b/zone/lua_npc.h index 563b8f072..d59c4aa92 100644 --- a/zone/lua_npc.h +++ b/zone/lua_npc.h @@ -200,6 +200,7 @@ public: void DeleteQuestLoot(int itemid1, int itemid2, int itemid3, int itemid4); bool HasRequiredQuestLoot(int itemid1, int itemid2, int itemid3, int itemid4); int QuestLootCount(int itemid); + bool CanTalk(); }; #endif diff --git a/zone/trading.cpp b/zone/trading.cpp index 3ec9be522..b8887c5eb 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -837,6 +837,15 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st tradingWith->SayString(TRADE_BACK, GetCleanName()); PushItemOnCursor(*baginst, true); } + else if (bagitem->NoDrop != 0 && tradingWith->CastToNPC()->CountQuestItem(bagitem->ID) == 0) { + tradingWith->CastToNPC()->AddQuestLoot(bagitem->ID, baginst->GetCharges()); + LogTrading("Adding loot item {} (bag) to non-Quest NPC {}", bagitem->Name, tradingWith->CastToNPC()->GetName()); + } + // Destroy duplicate and nodrop items on charmed pets. + else if (bagitem->NoDrop != 0 && ((tradingWith->CastToNPC()->IsPet() && tradingWith->CastToNPC()->IsCharmed()) || (tradingWith->CastToNPC()->IsPet() && tradingWith->CastToNPC()->IsCharmed() && tradingWith->CastToNPC()->CountQuestItem(bagitem->ID) == 0))) { + tradingWith->CastToNPC()->AddPetLoot(bagitem->ID, baginst->GetCharges()); + } + } } } @@ -868,6 +877,10 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st tradingWith->SayString(TRADE_BACK, GetCleanName()); PushItemOnCursor(*inst, true); } + // Add items to loottable without equipping and mark as quest. + else if (GetGM() || (item->NoDrop != 0 && tradingWith->CastToNPC()->CountQuestItem(item->ID) == 0)) { + tradingWith->CastToNPC()->AddQuestLoot(item->ID, inst->GetCharges()); + } } }