diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 491115d3c..0d73e7938 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -2761,9 +2761,8 @@ void NPC::ApplyAISpellEffects(StatBonuses* newbon) } // adds a spell to the list, taking into account priority and resorting list as needed. -void NPC::AddSpellEffectToNPCList(uint16 iSpellEffectID, int32 base_value, int32 limit, int32 max_value) +void NPC::AddSpellEffectToNPCList(uint16 iSpellEffectID, int32 base_value, int32 limit, int32 max_value, bool apply_bonus) { - if(!iSpellEffectID) return; @@ -2775,6 +2774,29 @@ void NPC::AddSpellEffectToNPCList(uint16 iSpellEffectID, int32 base_value, int32 t.limit = limit; t.max_value = max_value; AIspellsEffects.push_back(t); + + //we recalculate if applied from quest script. + if (apply_bonus) { + CalcBonuses(); + } +} + +void NPC::RemoveSpellEffectFromNPCList(uint16 iSpellEffectID, bool apply_bonus) +{ + auto iter = AIspellsEffects.begin(); + while (iter != AIspellsEffects.end()) + { + if ((*iter).spelleffectid == iSpellEffectID) + { + iter = AIspellsEffects.erase(iter); + continue; + } + ++iter; + } + + if (apply_bonus) { + CalcBonuses(); + } } bool IsSpellEffectInList(DBnpcspellseffects_Struct* spelleffect_list, uint16 iSpellEffectID, int32 base_value, int32 limit, int32 max_value) { diff --git a/zone/npc.h b/zone/npc.h index d3578f1d2..15d3c8ebc 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -449,8 +449,9 @@ public: uint32 GetAdventureTemplate() const { return adventure_template_id; } void AddSpellToNPCList(int16 iPriority, uint16 iSpellID, uint32 iType, int16 iManaCost, int32 iRecastDelay, int16 iResistAdjust, int8 min_hp, int8 max_hp); - void AddSpellEffectToNPCList(uint16 iSpellEffectID, int32 base_value, int32 limit, int32 max_value); + void AddSpellEffectToNPCList(uint16 iSpellEffectID, int32 base_value, int32 limit, int32 max_value, bool apply_bonus = false); void RemoveSpellFromNPCList(uint16 spell_id); + void RemoveSpellEffectFromNPCList(uint16 iSpellEffectID, bool apply_bonus = false); Timer *GetRefaceTimer() const { return reface_timer; } const uint32 GetAltCurrencyType() const { return NPCTypedata->alt_currency_type; } diff --git a/zone/perl_npc.cpp b/zone/perl_npc.cpp index 4bd19e4e4..a10acbbe8 100644 --- a/zone/perl_npc.cpp +++ b/zone/perl_npc.cpp @@ -1845,6 +1845,40 @@ XS(XS_NPC_GetLootList) { } } +XS(XS_NPC_AddAISpellEffect); /* prototype to pass -Wmissing-prototypes */ +XS(XS_NPC_AddAISpellEffect) { + dXSARGS; + if (items != 5) + Perl_croak(aTHX_ "Usage: NPC::AddAISpellEffect(THIS, spell_effect id, base_value, limit_value, max_value)"); // @categories Spells and Disciplines + { + NPC *THIS; + + int spell_effect_id = (int)SvIV(ST(1)); + int base_value = (int)SvIV(ST(2)); + int limit_value = (int)SvIV(ST(3)); + int max_value = (int)SvIV(ST(4)); + + VALIDATE_THIS_IS_NPC; + THIS->AddSpellEffectToNPCList(spell_effect_id, base_value, limit_value, max_value, true); + } + XSRETURN_EMPTY; +} + +XS(XS_NPC_RemoveAISpellEffect); /* prototype to pass -Wmissing-prototypes */ +XS(XS_NPC_RemoveAISpellEffect) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: NPC::RemoveAISpellEffect(THIS, int spelleffect_id)"); // @categories Spells and Disciplines + { + NPC *THIS; + int spell_effect_id = (int)SvIV(ST(1)); + VALIDATE_THIS_IS_NPC; + THIS->RemoveSpellEffectFromNPCList(spell_effect_id, true); + } + XSRETURN_EMPTY; +} + + #ifdef __cplusplus extern "C" #endif @@ -1864,6 +1898,7 @@ XS(boot_NPC) { XS_VERSION_BOOTCHECK; newXSproto(strcpy(buf, "AI_SetRoambox"), XS_NPC_AI_SetRoambox, file, "$$$$$$;$$"); newXSproto(strcpy(buf, "AddAISpell"), XS_NPC_AddSpellToNPCList, file, "$$$$$$$"); + newXSproto(strcpy(buf, "AddAISpellEffect"), XS_NPC_AddAISpellEffect, file, "$$$$$"); newXSproto(strcpy(buf, "AddCash"), XS_NPC_AddCash, file, "$$$$$"); newXSproto(strcpy(buf, "AddDefensiveProc"), XS_NPC_AddDefensiveProc, file, "$$$"); newXSproto(strcpy(buf, "AddItem"), XS_NPC_AddItem, file, "$$;$$$$$$$$"); @@ -1939,6 +1974,7 @@ XS(boot_NPC) { newXSproto(strcpy(buf, "PickPocket"), XS_NPC_PickPocket, file, "$$"); newXSproto(strcpy(buf, "RecalculateSkills"), XS_NPC_RecalculateSkills, file, "$"); newXSproto(strcpy(buf, "RemoveAISpell"), XS_NPC_RemoveSpellFromNPCList, file, "$$"); + newXSproto(strcpy(buf, "RemoveAISpellEffect"), XS_NPC_RemoveAISpellEffect, file, "$$"); newXSproto(strcpy(buf, "RemoveCash"), XS_NPC_RemoveCash, file, "$"); newXSproto(strcpy(buf, "RemoveDefensiveProc"), XS_NPC_RemoveDefensiveProc, file, "$$"); newXSproto(strcpy(buf, "RemoveFromHateList"), XS_NPC_RemoveFromHateList, file, "$$");