diff options
Diffstat (limited to 'src/server/scripts')
9 files changed, 266 insertions, 138 deletions
diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index 2aa78964ffd..e556854c2ab 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -166,7 +166,11 @@ public: // fill the gameobject data and save to the db object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMgr().GetPhaseMaskForSpawn()); + // delete the old object and do a clean load from DB with a fresh new GameObject instance. + // this is required to avoid weird behavior and memory leaks + delete object; + object = new GameObject(); // this will generate a new guid if the object is in an instance if (!object->LoadGameObjectFromDB(guidLow, map)) { @@ -209,6 +213,13 @@ public: uint32 objectId = atoi(id); + if (!sObjectMgr->GetGameObjectTemplate(objectId)) + { + handler->PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST, objectId); + handler->SetSentErrorMessage(true); + return false; + } + player->SummonGameObject(objectId, x, y, z, ang, 0, 0, rot2, rot3, spawntm); return true; diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index 37e7177cbc6..e1821c69095 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -127,8 +127,8 @@ public: int32 gx = 32 - player->GetPositionX() / SIZE_OF_GRIDS; int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS; - handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gy, gx); - handler->PSendSysMessage("gridloc [%i, %i]", gx, gy); + handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gx, gy); + handler->PSendSysMessage("gridloc [%i, %i]", gy, gx); // calculate navmesh tile location dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId()); diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index 98b1f688867..b099a8e21de 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -476,7 +476,7 @@ public: return false; } - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -524,7 +524,7 @@ public: return false; } - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -569,7 +569,7 @@ public: return false; } - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -614,7 +614,7 @@ public: return false; } - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -659,7 +659,7 @@ public: return false; } - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp index 31c565e5be2..3541ad0f1a3 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp @@ -286,8 +286,8 @@ class npc_prince_taldaram_flame_sphere : public CreatureScript struct npc_prince_taldaram_flame_sphereAI : public ScriptedAI { - npc_prince_taldaram_flame_sphereAI(Creature* creature) : ScriptedAI(creature) - { + npc_prince_taldaram_flame_sphereAI(Creature* creature) : ScriptedAI(creature) + { _flameSphereTargetGUID = 0; } diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp index 1281d40fe5c..916f60bd78a 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp @@ -438,7 +438,7 @@ class npc_watcher_gashra : public CreatureScript _events.ScheduleEvent(EVENT_WEB_WRAP_GASHRA, 11000); _events.ScheduleEvent(EVENT_INFECTED_BITE_GASHRA, 4000); } - + void JustDied(Unit* /*killer*/) OVERRIDE { Creature* krikthir = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_KRIKTHIR_THE_GATEWATCHER)); @@ -511,7 +511,7 @@ class npc_watcher_narjil : public CreatureScript _events.ScheduleEvent(EVENT_INFECTED_BITE_NARJIL, 4000); _events.ScheduleEvent(EVENT_BINDING_WEBS, 17000); } - + void JustDied(Unit* /*killer*/) OVERRIDE { Creature* krikthir = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_KRIKTHIR_THE_GATEWATCHER)); @@ -600,7 +600,7 @@ class npc_watcher_silthik : public CreatureScript { if (!UpdateVictim()) return; - + _events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp index 2091b82e20c..762277ec4fa 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp @@ -70,15 +70,13 @@ enum Events EVENT_TRIGGER, EVENT_PHASE, - EVENT_MORTAL_WOUND, + EVENT_MORTAL_WOUND }; enum Spells { SPELL_FROST_BOLT = 28478, - H_SPELL_FROST_BOLT = 55802, SPELL_FROST_BOLT_AOE = 28479, - H_SPELL_FROST_BOLT_AOE = 55807, SPELL_SHADOW_FISURE = 27810, SPELL_VOID_BLAST = 27812, SPELL_MANA_DETONATION = 27819, @@ -122,7 +120,7 @@ enum Spells // Abomination spells SPELL_FRENZY = 28468, - SPELL_MORTAL_WOUND = 28467, + SPELL_MORTAL_WOUND = 28467 }; enum Creatures @@ -133,7 +131,7 @@ enum Creatures NPC_ICECROWN = 16441 // Guardians of Icecrown }; -const Position Pos[12] = +Position const Pos[12] = { {3783.272705f, -5062.697266f, 143.711203f, 3.617599f}, //LEFT_FAR {3730.291260f, -5027.239258f, 143.956909f, 4.461900f}, //LEFT_MIDDLE @@ -146,13 +144,13 @@ const Position Pos[12] = {3732.02f, -5028.53f, 143.92f, 4.49f}, //WINDOW_PORTAL02 {3687.571777f, -5126.831055f, 142.017807f, 0.604023f}, //RIGHT_FAR {3707.990733f, -5151.450195f, 142.032562f, 1.376855f}, //RIGHT_MIDDLE - {3782.76f, -5062.97f, 143.79f, 3.82f}, //WINDOW_PORTAL03 + {3782.76f, -5062.97f, 143.79f, 3.82f} //WINDOW_PORTAL03 }; //creatures in corners //Unstoppable Abominations #define MAX_ABOMINATIONS 21 -const Position PosAbominations[MAX_ABOMINATIONS] = +Position const PosAbominations[MAX_ABOMINATIONS] = { {3755.52f, -5155.22f, 143.480f, 2.0f}, {3744.35f, -5164.03f, 143.590f, 2.00f}, @@ -174,12 +172,12 @@ const Position PosAbominations[MAX_ABOMINATIONS] = {3669.74f, -5149.63f, 143.678f, 0.528643f}, {3695.53f, -5169.53f, 143.671f, 2.11908f}, {3701.98f, -5166.51f, 143.395f, 1.24257f}, - {3709.62f, -5169.15f, 143.576f, 5.97695f}, + {3709.62f, -5169.15f, 143.576f, 5.97695f} }; //Soldiers of the Frozen Wastes #define MAX_WASTES 49 -const Position PosWastes[MAX_WASTES] = +Position const PosWastes[MAX_WASTES] = { {3754.41f, -5147.24f, 143.204f, 2.0f}, {3754.68f, -5156.17f, 143.418f, 2.0f}, @@ -229,12 +227,12 @@ const Position PosWastes[MAX_WASTES] = {3708.53f, -5172.19f, 143.573f, 3.26575f}, {3712.49f, -5167.62f, 143.657f, 5.63295f}, {3704.89f, -5161.84f, 143.239f, 5.63295f}, - {3695.66f, -5164.63f, 143.674f, 1.54416f}, + {3695.66f, -5164.63f, 143.674f, 1.54416f} }; //Soul Weavers #define MAX_WEAVERS 7 -const Position PosWeavers[MAX_WEAVERS] = +Position const PosWeavers[MAX_WEAVERS] = { {3752.45f, -5168.35f, 143.562f, 1.6094f}, {3772.2f, -5070.04f, 143.329f, 1.93686f}, @@ -242,7 +240,7 @@ const Position PosWeavers[MAX_WEAVERS] = {3689.05f, -5055.7f, 143.172f, 6.09554f}, {3649.45f, -5093.17f, 143.299f, 2.51805f}, {3659.7f, -5144.49f, 143.363f, 4.08806f}, - {3704.71f, -5175.96f, 143.597f, 3.36549f}, + {3704.71f, -5175.96f, 143.597f, 3.36549f} }; // predicate function to select not charmed target @@ -278,9 +276,6 @@ public: std::map<uint64, float> chained; - uint64 PortalsGUID[4]; - uint64 KTTriggerGUID; - SummonList spawns; // adds spawn by the trigger. kept in separated list (i.e. not in summons) void ResetPlayerScale() @@ -299,36 +294,29 @@ public: { _Reset(); - PortalsGUID[0] = PortalsGUID[1] = PortalsGUID[2] = PortalsGUID[3] = 0; - KTTriggerGUID = 0; - me->setFaction(35); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE); ResetPlayerScale(); spawns.DespawnAll(); - FindGameObjects(); - instance->SetData(DATA_ABOMINATION_KILLED, 0); - if (GameObject* pKTTrigger = me->GetMap()->GetGameObject(KTTriggerGUID)) + if (GameObject* trigger = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_TRIGGER))) { - pKTTrigger->ResetDoorOrButton(); - pKTTrigger->SetPhaseMask(1, true); + trigger->ResetDoorOrButton(); + trigger->SetPhaseMask(1, true); } for (uint8 i = 0; i <= 3; ++i) { - if (GameObject* pPortal = me->GetMap()->GetGameObject(PortalsGUID[i])) - { - if (!((pPortal->getLootState() == GO_READY) || (pPortal->getLootState() == GO_NOT_READY))) - pPortal->ResetDoorOrButton(); - } + if (GameObject* portal = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_PORTAL01 + i))) + if (!((portal->getLootState() == GO_READY) || (portal->getLootState() == GO_NOT_READY))) + portal->ResetDoorOrButton(); } nGuardiansOfIcecrownCount = 0; - uiGuardiansOfIcecrownTimer = 5000; //5 seconds for summoning each Guardian of Icecrown in phase 3 + uiGuardiansOfIcecrownTimer = 5000; // 5 seconds for summoning each Guardian of Icecrown in phase 3 Phase = 0; nAbomination = 0; @@ -353,11 +341,10 @@ public: me->setFaction(uiFaction); _EnterCombat(); - FindGameObjects(); for (uint8 i = 0; i <= 3; ++i) { - if (GameObject* pPortal = me->GetMap()->GetGameObject(PortalsGUID[i])) - pPortal->ResetDoorOrButton(); + if (GameObject* portal = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_PORTAL01 + i))) + portal->ResetDoorOrButton(); } DoCast(me, SPELL_KELTHUZAD_CHANNEL, false); Talk(SAY_SUMMON_MINIONS); @@ -372,15 +359,6 @@ public: events.ScheduleEvent(EVENT_PHASE, 228000); } - void FindGameObjects() - { - PortalsGUID[0] = instance->GetData64(DATA_KELTHUZAD_PORTAL01); - PortalsGUID[1] = instance->GetData64(DATA_KELTHUZAD_PORTAL02); - PortalsGUID[2] = instance->GetData64(DATA_KELTHUZAD_PORTAL03); - PortalsGUID[3] = instance->GetData64(DATA_KELTHUZAD_PORTAL04); - KTTriggerGUID = instance->GetData64(DATA_KELTHUZAD_TRIGGER); - } - void UpdateAI(uint32 diff) OVERRIDE { if (!UpdateVictim()) @@ -419,8 +397,8 @@ public: events.PopEvent(); break; case EVENT_TRIGGER: - if (GameObject* pKTTrigger = me->GetMap()->GetGameObject(KTTriggerGUID)) - pKTTrigger->SetPhaseMask(2, true); + if (GameObject* trigger = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_TRIGGER))) + trigger->SetPhaseMask(2, true); events.PopEvent(); break; case EVENT_PHASE: @@ -461,11 +439,9 @@ public: for (uint8 i = 0; i <= 3; ++i) { - if (GameObject* pPortal = me->GetMap()->GetGameObject(PortalsGUID[i])) - { - if (pPortal->getLootState() == GO_READY) - pPortal->UseDoorOrButton(); - } + if (GameObject* portal = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_PORTAL01 + i))) + if (portal->getLootState() == GO_READY) + portal->UseDoorOrButton(); } } } @@ -474,8 +450,8 @@ public: if (uiGuardiansOfIcecrownTimer <= diff) { /// @todo Add missing text - if (Creature* pGuardian = DoSummon(NPC_ICECROWN, Pos[RAND(2, 5, 8, 11)])) - pGuardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2); + if (Creature* guardian = DoSummon(NPC_ICECROWN, Pos[RAND(2, 5, 8, 11)])) + guardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2); ++nGuardiansOfIcecrownCount; uiGuardiansOfIcecrownTimer = 5000; } @@ -490,11 +466,11 @@ public: switch (eventId) { case EVENT_BOLT: - DoCastVictim(RAID_MODE(SPELL_FROST_BOLT, H_SPELL_FROST_BOLT)); + DoCastVictim(SPELL_FROST_BOLT); events.RepeatEvent(urand(5000, 10000)); break; case EVENT_NOVA: - DoCastAOE(RAID_MODE(SPELL_FROST_BOLT_AOE, H_SPELL_FROST_BOLT_AOE)); + DoCastAOE(SPELL_FROST_BOLT_AOE); events.RepeatEvent(urand(15000, 30000)); break; case EVENT_CHAIN: @@ -666,7 +642,7 @@ public: if (!instance || instance->IsEncounterInProgress() || instance->GetBossState(BOSS_KELTHUZAD) == DONE) return false; - Creature* pKelthuzad = Unit::GetCreature(*player, instance->GetData64(DATA_KELTHUZAD)); + Creature* pKelthuzad = ObjectAccessor::GetCreature(*player, instance->GetData64(DATA_KELTHUZAD)); if (!pKelthuzad) return false; @@ -675,7 +651,7 @@ public: return false; pKelthuzadAI->AttackStart(player); - if (GameObject* trigger = instance->instance->GetGameObject(instance->GetData64(DATA_KELTHUZAD_TRIGGER))) + if (GameObject* trigger = ObjectAccessor::GetGameObject(*player, instance->GetData64(DATA_KELTHUZAD_TRIGGER))) { if (trigger->getLootState() == GO_READY) trigger->UseDoorOrButton(); diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp index cc37dde57dd..fe29f4e9f7c 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp @@ -18,28 +18,25 @@ /* ScriptData SDName: Boss_Ingvar_The_Plunderer SD%Complete: 95 -SDComment: Some Problems with Annhylde Movement, Blizzlike Timers (just shadow axe summon needs a new timer) -SDCategory: Udgarde Keep +SDComment: Blizzlike Timers (just shadow axe summon needs a new timer) +SDCategory: Utgarde Keep EndScriptData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" #include "utgarde_keep.h" enum Yells { - // Ingvar (Human) - SAY_AGGRO_1 = 0, - SAY_SLAY_1 = 1, - SAY_DEATH_1 = 2, - - // Ingvar (Undead) - SAY_AGGRO_2 = 3, - SAY_SLAY_2 = 4, - SAY_DEATH_2 = 5, + // Ingvar (Human/Undead) + SAY_AGGRO = 0, + SAY_SLAY = 1, + SAY_DEATH = 2, // Annhylde The Caller - YELL_RESURRECT = 0 + YELL_RESURRECT = 0 }; enum Events @@ -83,8 +80,10 @@ enum Spells SPELL_DARK_SMASH = 42723, SPELL_DREADFUL_ROAR = 42729, SPELL_WOE_STRIKE = 42730, + SPELL_WOE_STRIKE_EFFECT = 42739, SPELL_SHADOW_AXE_SUMMON = 42748, + SPELL_SHADOW_AXE_PERIODIC_DAMAGE = 42750, // Spells for Annhylde SPELL_SCOURG_RESURRECTION_HEAL = 42704, // Heal Max + DummyAura @@ -105,16 +104,14 @@ class boss_ingvar_the_plunderer : public CreatureScript struct boss_ingvar_the_plundererAI : public BossAI { - boss_ingvar_the_plundererAI(Creature* creature) : BossAI(creature, DATA_INGVAR) - { - _isUndead = false; - } + boss_ingvar_the_plundererAI(Creature* creature) : BossAI(creature, DATA_INGVAR) { } void Reset() OVERRIDE { - _isUndead = false; + if (me->GetEntry() != NPC_INGVAR) + me->UpdateEntry(NPC_INGVAR); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE); _Reset(); events.SetPhase(PHASE_HUMAN); @@ -132,12 +129,12 @@ class boss_ingvar_the_plunderer : public CreatureScript me->RemoveAllAuras(); DoCast(me, SPELL_INGVAR_FEIGN_DEATH, true); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE); events.SetPhase(PHASE_EVENT); events.ScheduleEvent(EVENT_SUMMON_BANSHEE, 3 * IN_MILLISECONDS, 0, PHASE_EVENT); - Talk(SAY_DEATH_1); + Talk(SAY_DEATH); } if (events.IsInPhase(PHASE_EVENT)) @@ -152,26 +149,22 @@ class boss_ingvar_the_plunderer : public CreatureScript void StartZombiePhase() { - _isUndead = true; me->RemoveAura(SPELL_INGVAR_FEIGN_DEATH); - DoCast(me, SPELL_INGVAR_TRANSFORM, true); /// @todo: should be death persistent + DoCast(me, SPELL_INGVAR_TRANSFORM, true); + me->UpdateEntry(NPC_INGVAR_UNDEAD); events.ScheduleEvent(EVENT_JUST_TRANSFORMED, 2 * IN_MILLISECONDS, 0, PHASE_EVENT); - - Talk(SAY_AGGRO_2); } void EnterCombat(Unit* /*who*/) OVERRIDE { _EnterCombat(); - - if (!_isUndead) - Talk(SAY_AGGRO_1); + Talk(SAY_AGGRO); } void JustDied(Unit* /*killer*/) OVERRIDE { _JustDied(); - Talk(SAY_DEATH_2); + Talk(SAY_DEATH); } void ScheduleSecondPhase() @@ -183,9 +176,10 @@ class boss_ingvar_the_plunderer : public CreatureScript events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD); } - void KilledUnit(Unit* /*victim*/) OVERRIDE + void KilledUnit(Unit* who) OVERRIDE { - Talk(_isUndead ? SAY_SLAY_1 : SAY_SLAY_2); + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); } void UpdateAI(uint32 diff) OVERRIDE @@ -220,7 +214,7 @@ class boss_ingvar_the_plunderer : public CreatureScript events.ScheduleEvent(EVENT_SMASH, urand(12, 16)*IN_MILLISECONDS, 0, PHASE_HUMAN); break; case EVENT_JUST_TRANSFORMED: - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE); DoZoneInCombat(); ScheduleSecondPhase(); return; @@ -241,20 +235,18 @@ class boss_ingvar_the_plunderer : public CreatureScript events.ScheduleEvent(EVENT_WOE_STRIKE, urand(10, 14)*IN_MILLISECONDS, 0, PHASE_UNDEAD); break; case EVENT_SHADOW_AXE: - if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 1)) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) DoCast(target, SPELL_SHADOW_AXE_SUMMON); - events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD); break; + default: + break; } } if (!events.IsInPhase(PHASE_EVENT)) DoMeleeAttackIfReady(); } - - private: - bool _isUndead; }; CreatureAI* GetAI(Creature* creature) const OVERRIDE @@ -279,12 +271,8 @@ class npc_annhylde_the_caller : public CreatureScript { _events.Reset(); - //! HACK: Creature's can't have MOVEMENTFLAG_FLYING - me->SetHover(true); - me->GetPosition(x, y, z); - DoTeleportTo(x+1, y, z+30); - me->GetMotionMaster()->MovePoint(1, x, y, z+15); + me->GetMotionMaster()->MovePoint(1, x, y, z - 15.0f); } void MovementInform(uint32 type, uint32 id) OVERRIDE @@ -339,7 +327,7 @@ class npc_annhylde_the_caller : public CreatureScript ingvar->AI()->DoAction(ACTION_START_PHASE_2); } - me->GetMotionMaster()->MovePoint(2, x+1, y, z+30); + me->GetMotionMaster()->MovePoint(2, x, y, z + 15.0f); break; default: break; @@ -359,52 +347,112 @@ class npc_annhylde_the_caller : public CreatureScript } }; -enum ShadowAxe -{ - SPELL_SHADOW_AXE_DAMAGE = 42750, - H_SPELL_SHADOW_AXE_DAMAGE = 59719, - POINT_TARGET = 28 -}; - class npc_ingvar_throw_dummy : public CreatureScript { -public: - npc_ingvar_throw_dummy() : CreatureScript("npc_ingvar_throw_dummy") { } + public: + npc_ingvar_throw_dummy() : CreatureScript("npc_ingvar_throw_dummy") { } - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new npc_ingvar_throw_dummyAI(creature); - } + struct npc_ingvar_throw_dummyAI : public ScriptedAI + { + npc_ingvar_throw_dummyAI(Creature* creature) : ScriptedAI(creature) { } + + void Reset() OVERRIDE + { + me->SetReactState(REACT_PASSIVE); + + if (Creature* target = me->FindNearestCreature(NPC_THROW_TARGET, 200.0f)) + { + float x, y, z; + target->GetPosition(x, y, z); + me->GetMotionMaster()->MoveCharge(x, y, z); + target->DespawnOrUnsummon(); + } + else + me->DespawnOrUnsummon(); + } + + void MovementInform(uint32 type, uint32 id) OVERRIDE + { + if (type == EFFECT_MOTION_TYPE && id == EVENT_CHARGE) + { + me->CastSpell(me, SPELL_SHADOW_AXE_PERIODIC_DAMAGE, true); + me->DespawnOrUnsummon(10000); + } + } + }; - struct npc_ingvar_throw_dummyAI : public ScriptedAI - { - npc_ingvar_throw_dummyAI(Creature* creature) : ScriptedAI(creature) + CreatureAI* GetAI(Creature* creature) const OVERRIDE { + return new npc_ingvar_throw_dummyAI(creature); } +}; + +// 42912 - Summon Banshee +class spell_ingvar_summon_banshee : public SpellScriptLoader +{ + public: + spell_ingvar_summon_banshee() : SpellScriptLoader("spell_ingvar_summon_banshee") { } - void Reset() OVERRIDE + class spell_ingvar_summon_banshee_SpellScript : public SpellScript { - if (Creature* target = me->FindNearestCreature(NPC_THROW_TARGET, 50.0f)) + PrepareSpellScript(spell_ingvar_summon_banshee_SpellScript); + + void SetDest(SpellDestination& dest) { - float x, y, z; - target->GetPosition(x, y, z); - me->GetMotionMaster()->MoveCharge(x, y, z, 42.0f, POINT_TARGET); - target->DisappearAndDie(); + dest.RelocateOffset({ 0.0f, 0.0f, 30.0f, 0.0f }); } - else - me->DisappearAndDie(); + + void Register() OVERRIDE + { + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_ingvar_summon_banshee_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER_BACK); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_ingvar_summon_banshee_SpellScript(); } +}; - void MovementInform(uint32 type, uint32 id) OVERRIDE +// 42730, 59735 - Woe Strike +class spell_ingvar_woe_strike : public SpellScriptLoader +{ + public: + spell_ingvar_woe_strike() : SpellScriptLoader("spell_ingvar_woe_strike") { } + + class spell_ingvar_woe_strike_AuraScript : public AuraScript { - if (type == EFFECT_MOTION_TYPE && id == POINT_TARGET) + PrepareAuraScript(spell_ingvar_woe_strike_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE + { + if (!sSpellMgr->GetSpellInfo(SPELL_WOE_STRIKE_EFFECT)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetHealInfo()->GetHeal(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + GetTarget()->CastSpell(eventInfo.GetActor(), SPELL_WOE_STRIKE_EFFECT, true, NULL, aurEff); + } + + void Register() OVERRIDE { - DoCast(me, SPELL_SHADOW_AXE_DAMAGE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); - me->DespawnOrUnsummon(10000); + DoCheckProc += AuraCheckProcFn(spell_ingvar_woe_strike_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_ingvar_woe_strike_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL); } + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_ingvar_woe_strike_AuraScript(); } - }; }; void AddSC_boss_ingvar_the_plunderer() @@ -412,4 +460,6 @@ void AddSC_boss_ingvar_the_plunderer() new boss_ingvar_the_plunderer(); new npc_annhylde_the_caller(); new npc_ingvar_throw_dummy(); + new spell_ingvar_summon_banshee(); + new spell_ingvar_woe_strike(); } diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index abb14a9cc5d..992f6fdbcfb 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -60,6 +60,8 @@ enum PaladinSpells SPELL_PALADIN_RIGHTEOUS_DEFENSE_TAUNT = 31790, SPELL_PALADIN_SANCTIFIED_RETRIBUTION_AURA = 63531, SPELL_PALADIN_SANCTIFIED_RETRIBUTION_R1 = 31869, + SPELL_PALADIN_SANCTIFIED_WRATH = 57318, + SPELL_PALADIN_SANCTIFIED_WRATH_TALENT_R1 = 53375, SPELL_PALADIN_SEAL_OF_RIGHTEOUSNESS = 25742, SPELL_PALADIN_SWIFT_RETRIBUTION_R1 = 53379 }; @@ -227,6 +229,52 @@ class spell_pal_aura_mastery_immune : public SpellScriptLoader } }; +// 31884 - Avenging Wrath +class spell_pal_avenging_wrath : public SpellScriptLoader +{ + public: + spell_pal_avenging_wrath() : SpellScriptLoader("spell_pal_avenging_wrath") { } + + class spell_pal_avenging_wrath_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pal_avenging_wrath_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE + { + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_SANCTIFIED_WRATH) + || !sSpellMgr->GetSpellInfo(SPELL_PALADIN_SANCTIFIED_WRATH_TALENT_R1)) + return false; + return true; + } + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + if (AuraEffect const* aurEff = target->GetAuraEffectOfRankedSpell(SPELL_PALADIN_SANCTIFIED_WRATH_TALENT_R1, EFFECT_2)) + { + int32 basepoints = aurEff->GetAmount(); + target->CastCustomSpell(target, SPELL_PALADIN_SANCTIFIED_WRATH, &basepoints, &basepoints, NULL, true, NULL, aurEff); + } + } + + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(SPELL_PALADIN_SANCTIFIED_WRATH); + } + + void Register() OVERRIDE + { + OnEffectApply += AuraEffectApplyFn(spell_pal_avenging_wrath_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_pal_avenging_wrath_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_pal_avenging_wrath_AuraScript(); + } +}; + // 53651 - Beacon of Light class spell_pal_beacon_of_light : public SpellScriptLoader { @@ -288,6 +336,7 @@ class spell_pal_beacon_of_light : public SpellScriptLoader } }; + // 37877 - Blessing of Faith class spell_pal_blessing_of_faith : public SpellScriptLoader { @@ -1149,6 +1198,7 @@ void AddSC_paladin_spell_scripts() //new spell_pal_ardent_defender(); new spell_pal_aura_mastery(); new spell_pal_aura_mastery_immune(); + new spell_pal_avenging_wrath(); new spell_pal_beacon_of_light(); new spell_pal_blessing_of_faith(); new spell_pal_divine_sacrifice(); diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index d1b32570795..b9fd07293cd 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -2276,6 +2276,46 @@ class spell_q13400_illidan_kill_master : public SpellScriptLoader } }; +enum RelicOfTheEarthenRing +{ + SPELL_TOTEM_OF_THE_EARTHEN_RING = 66747 +}; + +// 66744 - Make Player Destroy Totems +class spell_q14100_q14111_make_player_destroy_totems : public SpellScriptLoader +{ + public: + spell_q14100_q14111_make_player_destroy_totems() : SpellScriptLoader("spell_q14100_q14111_make_player_destroy_totems") { } + + class spell_q14100_q14111_make_player_destroy_totems_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q14100_q14111_make_player_destroy_totems_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE + { + if (!sSpellMgr->GetSpellInfo(SPELL_TOTEM_OF_THE_EARTHEN_RING)) + return false; + return true; + } + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + if (Player* player = GetHitPlayer()) + player->CastSpell(player, SPELL_TOTEM_OF_THE_EARTHEN_RING, TRIGGERED_FULL_MASK); // ignore reagent cost, consumed by quest + } + + void Register() OVERRIDE + { + OnEffectHitTarget += SpellEffectFn(spell_q14100_q14111_make_player_destroy_totems_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_q14100_q14111_make_player_destroy_totems_SpellScript(); + } +}; + void AddSC_quest_spell_scripts() { new spell_q55_sacred_cleansing(); @@ -2331,4 +2371,5 @@ void AddSC_quest_spell_scripts() new spell_q12919_gymers_grab(); new spell_q12919_gymers_throw(); new spell_q13400_illidan_kill_master(); + new spell_q14100_q14111_make_player_destroy_totems(); } |