diff --git a/changelog.txt b/changelog.txt index 0a22ccf8d..08527447b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 07/2/2014 == +Kayen: Implemented SE_Sanctuary - Places caster at bottom hate list, effect fades if caster cast spell on targets other than self. + == 06/25/2014 == Kayen: Updated SE_Hate (Renamed from SE_Hate2) to now properly work for instant +/- hate spells. diff --git a/common/spdat.h b/common/spdat.h index 75d351fc2..0c2cf4b1f 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -455,11 +455,11 @@ typedef enum { #define SE_MitigateDamageShield 305 // implemented - off hand attacks only (Shielding Resistance) //#define SE_ArmyOfTheDead 306 // *not implemented NecroAA - This ability calls up to five shades of nearby corpses back to life to serve the necromancer. The soulless abominations will mindlessly fight the target until called back to the afterlife some time later. The first rank summons up to three shades that serve for 60 seconds, and each additional rank adds one more possible shade and increases their duration by 15 seconds //#define SE_Appraisal 307 // *not implemented Rogue AA - This ability allows you to estimate the selling price of an item you are holding on your cursor. -#define SE_SuspendMinion 308 // not implemented as bonus +#define SE_SuspendMinion 308 // implemented #define SE_GateCastersBindpoint 309 // implemented - Gate to casters bind point #define SE_ReduceReuseTimer 310 // implemented #define SE_LimitCombatSkills 311 // implemented - Excludes focus from procs (except if proc is a memorizable spell) -//#define SE_Sanctuary 312 // *not implemented +#define SE_Sanctuary 312 // implemented - Places caster at bottom hate list, effect fades if cast cast spell on targets other than self. #define SE_ForageAdditionalItems 313 // implemented[AA] - chance to forage additional items #define SE_Invisibility2 314 // implemented - fixed duration invisible #define SE_InvisVsUndead2 315 // implemented - fixed duration ITU diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index a316c4b3b..0e521a6db 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -2856,6 +2856,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne newbon->PetMeleeMitigation += effect_value; break; + case SE_Sanctuary: + newbon->Sanctuary = true; + break; + //Special custom cases for loading effects on to NPC from 'npc_spels_effects' table if (IsAISpellEffect) { @@ -4330,6 +4334,10 @@ void Mob::NegateSpellsBonuses(uint16 spell_id) itembonuses.FinishingBlowLvl[1] = effect_value; break; + case SE_Sanctuary: + spellbonuses.Sanctuary = effect_value; + break; + } } } diff --git a/zone/common.h b/zone/common.h index 88600492e..0768a0835 100644 --- a/zone/common.h +++ b/zone/common.h @@ -372,6 +372,7 @@ struct StatBonuses { int16 DStacker[1]; // For buff stack blocking 0=Exists 1=Effect_value bool BerserkSPA; // berserk effect int16 Metabolism; // Food/drink consumption rates. + bool Sanctuary; // Sanctuary effect, lowers place on hate list until cast on others. // AAs int8 Packrat; //weight reduction for items, 1 point = 10% diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 090fb4b75..7bb227bd0 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -2732,6 +2732,22 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) break; } + case SE_Sanctuary: + { + std::list npc_list; + entity_list.GetNPCList(npc_list); + + for(std::list::iterator itr = npc_list.begin(); itr != npc_list.end(); ++itr) { + + NPC* npc = *itr; + + if (npc && npc->CheckAggro(this)) + npc->SetHate(caster, 1); + + } + break; + } + // Handled Elsewhere case SE_ImmuneFleeing: case SE_NegateSpellEffect: @@ -2960,6 +2976,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) case SE_Berserk: case SE_Vampirism: case SE_Metabolism: + case SE_FinishingBlow: + case SE_FinishingBlowLvl: + case SE_Assassinate: + case SE_AssassinateLevel: { break; } @@ -3604,6 +3624,22 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste break; } + case SE_Sanctuary: + { + std::list npc_list; + entity_list.GetNPCList(npc_list); + + for(std::list::iterator itr = npc_list.begin(); itr != npc_list.end(); ++itr) { + + NPC* npc = *itr; + + if (npc && npc->CheckAggro(this)) + npc->SetHate(caster, 1); + + } + break; + } + default: { // do we need to do anyting here? diff --git a/zone/spells.cpp b/zone/spells.cpp index 59dbb6625..6a87f2409 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -183,6 +183,9 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, CastToNPC()->AI_Event_SpellCastFinished(false, casting_spell_slot); return(false); } + //It appears that the Sanctuary effect is removed by a check on the client side (keep this however for redundancy) + if (spellbonuses.Sanctuary && (spells[spell_id].targettype != ST_Self && GetTarget() != this) || IsDetrimentalSpell(spell_id)) + BuffFadeByEffect(SE_Sanctuary); if(IsClient()){ int chance = CastToClient()->GetFocusEffect(focusFcMute, spell_id);