From 6abed18eb9508f702e916c6d0880df71cdb7e1c2 Mon Sep 17 00:00:00 2001 From: Kinglykrab Date: Thu, 20 Oct 2016 21:10:07 -0400 Subject: [PATCH 1/2] Added augment support for NPC AddItem() and quest::addloot in Perl/Lua. This will allow you to add items to NPCs with scripts that already have augments in them. --- zone/loottables.cpp | 18 +++++++++--------- zone/lua_npc.cpp | 36 ++++++++++++++++++++++++++++++++++++ zone/lua_npc.h | 6 ++++++ zone/npc.h | 4 ++-- zone/perl_npc.cpp | 26 ++++++++++++++++++++++---- zone/questmgr.cpp | 4 ++-- zone/questmgr.h | 2 +- 7 files changed, 78 insertions(+), 18 deletions(-) diff --git a/zone/loottables.cpp b/zone/loottables.cpp index 4dae50960..03f1590b1 100644 --- a/zone/loottables.cpp +++ b/zone/loottables.cpp @@ -221,7 +221,7 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml } //if itemlist is null, just send wear changes -void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange) { +void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6) { if(item2 == nullptr) return; @@ -245,12 +245,12 @@ void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 ch item->item_id = item2->ID; item->charges = charges; - item->aug_1 = 0; - item->aug_2 = 0; - item->aug_3 = 0; - item->aug_4 = 0; - item->aug_5 = 0; - item->aug_6 = 0; + item->aug_1 = aug1; + item->aug_2 = aug2; + item->aug_3 = aug3; + item->aug_4 = aug4; + item->aug_5 = aug5; + item->aug_6 = aug6; item->attuned = 0; item->min_level = minlevel; item->max_level = maxlevel; @@ -420,12 +420,12 @@ void NPC::AddItem(const EQEmu::ItemData* item, uint16 charges, bool equipitem) { AddLootDrop(item, &itemlist, charges, 1, 255, equipitem, equipitem); } -void NPC::AddItem(uint32 itemid, uint16 charges, bool equipitem) { +void NPC::AddItem(uint32 itemid, uint16 charges, bool equipitem, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6) { //slot isnt needed, its determined from the item. const EQEmu::ItemData * i = database.GetItem(itemid); if(i == nullptr) return; - AddLootDrop(i, &itemlist, charges, 1, 255, equipitem, equipitem); + AddLootDrop(i, &itemlist, charges, 1, 255, equipitem, equipitem, aug1, aug2, aug3, aug4, aug5, aug6); } void NPC::AddLootTable() { diff --git a/zone/lua_npc.cpp b/zone/lua_npc.cpp index 6d6c69a62..9ed705496 100644 --- a/zone/lua_npc.cpp +++ b/zone/lua_npc.cpp @@ -27,6 +27,36 @@ void Lua_NPC::AddItem(int item_id, int charges, bool equip) { self->AddItem(item_id, charges, equip); } +void Lua_NPC::AddItem(int item_id, int charges, bool equip, int aug1) { + Lua_Safe_Call_Void(); + self->AddItem(item_id, charges, equip, aug1); +} + +void Lua_NPC::AddItem(int item_id, int charges, bool equip, int aug1, int aug2) { + Lua_Safe_Call_Void(); + self->AddItem(item_id, charges, equip, aug1, aug2); +} + +void Lua_NPC::AddItem(int item_id, int charges, bool equip, int aug1, int aug2, int aug3) { + Lua_Safe_Call_Void(); + self->AddItem(item_id, charges, equip, aug1, aug2, aug3); +} + +void Lua_NPC::AddItem(int item_id, int charges, bool equip, int aug1, int aug2, int aug3, int aug4) { + Lua_Safe_Call_Void(); + self->AddItem(item_id, charges, equip, aug1, aug2, aug3, aug4); +} + +void Lua_NPC::AddItem(int item_id, int charges, bool equip, int aug1, int aug2, int aug3, int aug4, int aug5) { + Lua_Safe_Call_Void(); + self->AddItem(item_id, charges, equip, aug1, aug2, aug3, aug4, aug5); +} + +void Lua_NPC::AddItem(int item_id, int charges, bool equip, int aug1, int aug2, int aug3, int aug4, int aug5, int aug6) { + Lua_Safe_Call_Void(); + self->AddItem(item_id, charges, equip, aug1, aug2, aug3, aug4, aug5, aug6); +} + void Lua_NPC::AddLootTable() { Lua_Safe_Call_Void(); self->AddLootTable(); @@ -475,6 +505,12 @@ luabind::scope lua_register_npc() { .def("CheckNPCFactionAlly", (int(Lua_NPC::*)(int))&Lua_NPC::CheckNPCFactionAlly) .def("AddItem", (void(Lua_NPC::*)(int,int))&Lua_NPC::AddItem) .def("AddItem", (void(Lua_NPC::*)(int,int,bool))&Lua_NPC::AddItem) + .def("AddItem", (void(Lua_NPC::*)(int,int,bool,int))&Lua_NPC::AddItem) + .def("AddItem", (void(Lua_NPC::*)(int,int,bool,int,int))&Lua_NPC::AddItem) + .def("AddItem", (void(Lua_NPC::*)(int,int,bool,int,int,int))&Lua_NPC::AddItem) + .def("AddItem", (void(Lua_NPC::*)(int,int,bool,int,int,int,int))&Lua_NPC::AddItem) + .def("AddItem", (void(Lua_NPC::*)(int,int,bool,int,int,int,int,int))&Lua_NPC::AddItem) + .def("AddItem", (void(Lua_NPC::*)(int,int,bool,int,int,int,int,int,int))&Lua_NPC::AddItem) .def("AddLootTable", (void(Lua_NPC::*)(void))&Lua_NPC::AddLootTable) .def("AddLootTable", (void(Lua_NPC::*)(int))&Lua_NPC::AddLootTable) .def("RemoveItem", (void(Lua_NPC::*)(int))&Lua_NPC::RemoveItem) diff --git a/zone/lua_npc.h b/zone/lua_npc.h index f5bb4719d..e355c3e4d 100644 --- a/zone/lua_npc.h +++ b/zone/lua_npc.h @@ -31,6 +31,12 @@ public: int CheckNPCFactionAlly(int faction); void AddItem(int item_id, int charges); void AddItem(int item_id, int charges, bool equip); + void AddItem(int item_id, int charges, bool equip, int aug1); + void AddItem(int item_id, int charges, bool equip, int aug1, int aug2); + void AddItem(int item_id, int charges, bool equip, int aug1, int aug2, int aug3); + void AddItem(int item_id, int charges, bool equip, int aug1, int aug2, int aug3, int aug4); + void AddItem(int item_id, int charges, bool equip, int aug1, int aug2, int aug3, int aug4, int aug5); + void AddItem(int item_id, int charges, bool equip, int aug1, int aug2, int aug3, int aug4, int aug5, int aug6); void AddLootTable(); void AddLootTable(int id); void RemoveItem(int item_id); diff --git a/zone/npc.h b/zone/npc.h index ba9e93843..4b81d45a6 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -179,7 +179,7 @@ public: virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho); void AddItem(const EQEmu::ItemData* item, uint16 charges, bool equipitem = true); - void AddItem(uint32 itemid, uint16 charges, bool equipitem = true); + void AddItem(uint32 itemid, uint16 charges, bool equipitem = true, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0); void AddLootTable(); void AddLootTable(uint32 ldid); void DescribeAggro(Client *towho, Mob *mob, bool verbose); @@ -270,7 +270,7 @@ public: bool IsTaunting() const { return taunting; } void PickPocket(Client* thief); void StartSwarmTimer(uint32 duration) { swarm_timer.Start(duration); } - void AddLootDrop(const EQEmu::ItemData*dbitem, ItemList* itemlistconst, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange = false); + void AddLootDrop(const EQEmu::ItemData*dbitem, ItemList* itemlistconst, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange = false, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0); virtual void DoClassAttacks(Mob *target); void CheckSignal(); inline bool IsNotTargetableWithHotkey() const { return no_target_hotkey; } diff --git a/zone/perl_npc.cpp b/zone/perl_npc.cpp index 0c9cec797..64e71d82f 100644 --- a/zone/perl_npc.cpp +++ b/zone/perl_npc.cpp @@ -98,13 +98,19 @@ XS(XS_NPC_AddItem); /* prototype to pass -Wmissing-prototypes */ XS(XS_NPC_AddItem) { dXSARGS; - if (items < 2 || items > 4) - Perl_croak(aTHX_ "Usage: NPC::AddItem(THIS, itemid, charges = 0, equipitem = true)"); + if (items < 2 || items > 10) + Perl_croak(aTHX_ "Usage: NPC::AddItem(THIS, itemid, charges = 0, equipitem = true, aug1 = 0, aug2 = 0, aug3 = 0, aug4 = 0, aug5 = 0, aug6 = 0)"); { NPC * THIS; uint32 itemid = (uint32)SvUV(ST(1)); uint16 charges = 0; bool equipitem = true; + uint32 aug1 = 0; + uint32 aug2 = 0; + uint32 aug3 = 0; + uint32 aug4 = 0; + uint32 aug5 = 0; + uint32 aug6 = 0; if (sv_derived_from(ST(0), "NPC")) { IV tmp = SvIV((SV*)SvRV(ST(0))); @@ -119,8 +125,20 @@ XS(XS_NPC_AddItem) charges = (uint16)SvUV(ST(2)); if (items > 3) equipitem = (bool)SvTRUE(ST(3)); + if (items > 4) + aug1 = (uint32)SvUV(ST(4)); + if (items > 5) + aug2 = (uint32)SvUV(ST(5)); + if (items > 6) + aug3 = (uint32)SvUV(ST(6)); + if (items > 7) + aug4 = (uint32)SvUV(ST(7)); + if (items > 8) + aug5 = (uint32)SvUV(ST(8)); + if (items > 9) + aug6 = (uint32)SvUV(ST(9)); - THIS->AddItem(itemid, charges, equipitem); + THIS->AddItem(itemid, charges, equipitem, aug1, aug2, aug3, aug4, aug5, aug6); } XSRETURN_EMPTY; } @@ -2577,7 +2595,7 @@ XS(boot_NPC) newXSproto(strcpy(buf, "SignalNPC"), XS_NPC_SignalNPC, file, "$$"); newXSproto(strcpy(buf, "CheckNPCFactionAlly"), XS_NPC_CheckNPCFactionAlly, file, "$$"); - newXSproto(strcpy(buf, "AddItem"), XS_NPC_AddItem, file, "$$;$$"); + newXSproto(strcpy(buf, "AddItem"), XS_NPC_AddItem, file, "$$;$$$$$$$$"); newXSproto(strcpy(buf, "AddLootTable"), XS_NPC_AddLootTable, file, "$"); newXSproto(strcpy(buf, "RemoveItem"), XS_NPC_RemoveItem, file, "$$;$$"); newXSproto(strcpy(buf, "ClearItemList"), XS_NPC_ClearItemList, file, "$"); diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 1df7492c2..4668a1bbc 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -375,11 +375,11 @@ void QuestManager::selfcast(int spell_id) { initiator->SpellFinished(spell_id, initiator, EQEmu::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff); } -void QuestManager::addloot(int item_id, int charges, bool equipitem) { +void QuestManager::addloot(int item_id, int charges, bool equipitem, int aug1, int aug2, int aug3, int aug4, int aug5, int aug6) { QuestManagerCurrentQuestVars(); if(item_id != 0){ if(owner->IsNPC()) - owner->CastToNPC()->AddItem(item_id, charges, equipitem); + owner->CastToNPC()->AddItem(item_id, charges, equipitem, aug1, aug2, aug3, aug4, aug5, aug6); } } diff --git a/zone/questmgr.h b/zone/questmgr.h index 1bef4e1ee..a878de71e 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -70,7 +70,7 @@ public: void incstat(int stat, int value); void castspell(int spell_id, int target_id); void selfcast(int spell_id); - void addloot(int item_id, int charges = 0, bool equipitem = true); + void addloot(int item_id, int charges = 0, bool equipitem = true, int aug1 = 0, int aug2 = 0, int aug3 = 0, int aug4 = 0, int aug5 = 0, int aug6 = 0); void Zone(const char *zone_name); void settimer(const char *timer_name, int seconds); void settimerMS(const char *timer_name, int milliseconds); From 95064947b6832b353d754240447dc8c2d0744aee Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Fri, 21 Oct 2016 20:48:18 -0400 Subject: [PATCH 2/2] Hack to fix long recast bard songs --- zone/spells.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/zone/spells.cpp b/zone/spells.cpp index 649fa99c9..4c01e1340 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -985,17 +985,23 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo if(GetClass() == BARD) // bard's can move when casting any spell... { if (IsBardSong(spell_id)) { - if(spells[spell_id].buffduration == 0xFFFF || spells[spell_id].recast_time != 0) { - Log.Out(Logs::Detail, Logs::Spells, "Bard song %d not applying bard logic because duration or recast is wrong: dur=%d, recast=%d", spells[spell_id].buffduration, spells[spell_id].recast_time); + if(spells[spell_id].buffduration == 0xFFFF) { + Log.Out(Logs::Detail, Logs::Spells, "Bard song %d not applying bard logic because duration. dur=%d, recast=%d", spells[spell_id].buffduration); } else { - bardsong = spell_id; - bardsong_slot = slot; - //NOTE: theres a lot more target types than this to think about... - if (spell_target == nullptr || (spells[spell_id].targettype != ST_Target && spells[spell_id].targettype != ST_AETarget)) - bardsong_target_id = GetID(); - else - bardsong_target_id = spell_target->GetID(); - bardsong_timer.Start(6000); + // So long recast bard songs need special bard logic, although the effects don't repulse like other songs + // This is basically a hack to get that effect + // You can hold down the long recast spells, but you only get the effects once + // TODO fuck bards. + if (spells[spell_id].recast_time == 0) { + bardsong = spell_id; + bardsong_slot = slot; + //NOTE: theres a lot more target types than this to think about... + if (spell_target == nullptr || (spells[spell_id].targettype != ST_Target && spells[spell_id].targettype != ST_AETarget)) + bardsong_target_id = GetID(); + else + bardsong_target_id = spell_target->GetID(); + bardsong_timer.Start(6000); + } Log.Out(Logs::Detail, Logs::Spells, "Bard song %d started: slot %d, target id %d", bardsong, bardsong_slot, bardsong_target_id); bard_song_mode = true; }