diff --git a/common/spdat.cpp b/common/spdat.cpp index 1a0014e46..3acac1c8b 100644 --- a/common/spdat.cpp +++ b/common/spdat.cpp @@ -2325,3 +2325,108 @@ bool IsCastNotStandingSpell(uint16 spell_id) { */ return spells[spell_id].cast_not_standing; } + +bool IsAegolismSpell(uint16 spell_id) { + + if (!IsValidSpell(spell_id)) { + return 0; + } + + bool has_max_hp = false; + bool has_current_hp = false; + bool has_ac = false; + + for (int i = 0; i < EFFECT_COUNT; ++i) { + + if (i == 0 && spells[spell_id].effect_id[i] != SE_StackingCommand_Block) { + return 0; + } + + if (i == 1 && spells[spell_id].effect_id[i] == SE_TotalHP) { + has_max_hp = true; + } + + if (i == 2 && spells[spell_id].effect_id[i] == SE_CurrentHPOnce) { + has_current_hp = true; + } + + if (i == 3 && spells[spell_id].effect_id[i] == SE_ArmorClass) { + has_ac = true; + } + + if (i == 4 && spells[spell_id].effect_id[i] != SE_StackingCommand_Overwrite) { + return 0; + } + } + + if (has_max_hp && has_current_hp && has_ac) { + return 1; + } + return 0; +} + + +bool AegolismStackingIsSymbolSpell(uint16 spell_id) { + + /* + This is hardcoded to be specific to the type of HP buffs that are removed if a mob has an Aegolism buff. + */ + + if (!IsValidSpell(spell_id)) { + return 0; + } + + bool has_max_hp = false; + bool has_current_hp = false; + + for (int i = 0; i < EFFECT_COUNT; ++i) { + + if ((i < 2 && spells[spell_id].effect_id[i] != SE_CHA) || + i > 3 && spells[spell_id].effect_id[i] != SE_Blank) { + return 0;; + } + + if (i == 2 && spells[spell_id].effect_id[i] == SE_TotalHP) { + has_max_hp = true; + } + + if (i == 3 && spells[spell_id].effect_id[i] == SE_CurrentHPOnce) { + has_current_hp = true; + } + } + + if (has_max_hp && has_current_hp) { + return 1; + } + + return 0; +} + +bool AegolismStackingIsArmorClassSpell(uint16 spell_id) { + /* + This is hardcoded to be specific to the type of AC buffs that are removed if a mob has an Aegolism buff. + */ + if (!IsValidSpell(spell_id)) { + return 0; + } + + bool has_ac = false; + + for (int i = 0; i < EFFECT_COUNT; ++i) { + + if ((i < 3 && spells[spell_id].effect_id[i] != SE_CHA) || + i > 3 && spells[spell_id].effect_id[i] != SE_Blank) { + return 0; + } + + if (i == 3 && spells[spell_id].effect_id[i] == SE_ArmorClass) { + has_ac = true; + } + } + + if (has_ac) { + return 1; + } + + return 0; +} diff --git a/common/spdat.h b/common/spdat.h index 9508db9d5..d597c79fa 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -1625,5 +1625,8 @@ bool IsSpellUsableInThisZoneType(uint16 spell_id, uint8 zone_type); const char *GetSpellName(uint16 spell_id); int GetSpellStatValue(uint16 spell_id, const char* stat_identifier, uint8 slot = 0); bool IsCastRestrictedSpell(uint16 spell_id); +bool IsAegolismSpell(uint16 spell_id); +bool AegolismStackingIsSymbolSpell(uint16 spell_id); +bool AegolismStackingIsArmorClassSpell(uint16 spell_id); #endif diff --git a/zone/spells.cpp b/zone/spells.cpp index e9a523909..bde53f3ca 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -3743,6 +3743,18 @@ int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_overrid } } + //remove associated buffs for certain live spell lines + if (IsAegolismSpell(spell_id)) { + int buff_count = GetMaxBuffSlots(); + for (int slot = 0; slot < buff_count; slot++) { + if (IsValidSpell(buffs[slot].spellid)) { + if (AegolismStackingIsSymbolSpell(buffs[slot].spellid) || AegolismStackingIsArmorClassSpell(buffs[slot].spellid)) { + BuffFadeBySlot(slot); + } + } + } + } + buffs[emptyslot].spellid = spell_id; buffs[emptyslot].casterlevel = caster_level; if (caster && !caster->IsAura()) // maybe some other things we don't want to ...