From a127c0e1a7612094c2bf8b2f5092f55aa96f0556 Mon Sep 17 00:00:00 2001 From: MitchesD Date: Sat, 18 Jan 2014 00:13:27 +0100 Subject: Scripts/Krikthir the Gatewatcher: converted to EventMap and small optimization --- .../AzjolNerub/boss_krikthir_the_gatewatcher.cpp | 761 ++++++++++++--------- 1 file changed, 435 insertions(+), 326 deletions(-) (limited to 'src/server/scripts/Northrend') 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 2fe619a5367..dd926acba28 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 @@ -26,30 +26,22 @@ enum Spells { SPELL_MIND_FLAY = 52586, - H_SPELL_MIND_FLAY = 59367, SPELL_CURSE_OF_FATIGUE = 52592, - H_SPELL_CURSE_OF_FATIGUE = 59368, SPELL_FRENZY = 28747, //maybe 53361 SPELL_SUMMON_SKITTERING_SWARMER = 52438, //AOE Effect 140, maybe 52439 SPELL_SUMMON_SKITTERING_SWARMER_1 = 52439, //Summon 3x 28735 - H_SPELL_ACID_SPLASH = 59363, SPELL_ACID_SPLASH = 52446, SPELL_CHARGE = 16979, //maybe is another spell SPELL_BACKSTAB = 52540, SPELL_SHADOW_BOLT = 52534, - H_SPELL_SHADOW_BOLT = 59357, SPELL_SHADOW_NOVA = 52535, - H_SPELL_SHADOW_NOVA = 59358, SPELL_STRIKE = 52532, SPELL_CLEAVE = 49806, SPELL_ENRAGE = 52470, SPELL_INFECTED_BITE = 52469, - H_SPELL_INFECTED_BITE = 59364, SPELL_WEB_WRAP = 52086, //the spell is not working properly SPELL_BLINDING_WEBS = 52524, - H_SPELL_BLINDING_WEBS = 59365, - SPELL_POSION_SPRAY = 52493, - H_SPELL_POSION_SPRAY = 59366 + SPELL_POSION_SPRAY = 52493 }; enum Mobs @@ -69,7 +61,7 @@ enum Yells SAY_SEND_GROUP = 5 }; -const Position SpawnPoint[] = +Position const SpawnPoint[] = { { 566.164f, 682.087f, 769.079f, 2.21657f }, { 529.042f, 706.941f, 777.298f, 1.0821f }, @@ -81,444 +73,561 @@ const Position SpawnPoint[] = { 552.625f, 706.408f, 777.177f, 3.4383f } }; +enum Events +{ + EVENT_SUMMON = 1, + EVENT_MIND_FLAY, + EVENT_CURSE_FATIGUE +}; + class boss_krik_thir : public CreatureScript { -public: - boss_krik_thir() : CreatureScript("boss_krik_thir") { } + public: + boss_krik_thir() : CreatureScript("boss_krik_thir") { } - struct boss_krik_thirAI : public ScriptedAI - { - boss_krik_thirAI(Creature* creature) : ScriptedAI(creature) + struct boss_krik_thirAI : public BossAI { - instance = creature->GetInstanceScript(); - } + boss_krik_thirAI(Creature* creature) : BossAI(creature, DATA_KRIKTHIR_THE_GATEWATCHER) { } - InstanceScript* instance; + void Reset() OVERRIDE + { + _Reset(); + } - uint32 uiMindFlayTimer; - uint32 uiCurseFatigueTimer; - uint32 uiSummonTimer; + void EnterCombat(Unit* /*who*/) OVERRIDE + { + Talk(SAY_AGGRO); + _EnterCombat(); + Summon(); - void Reset() OVERRIDE - { - uiMindFlayTimer = 15*IN_MILLISECONDS; - uiCurseFatigueTimer = 12*IN_MILLISECONDS; + events.ScheduleEvent(EVENT_SUMMON, 15000); + events.ScheduleEvent(EVENT_MIND_FLAY, 15000); + events.ScheduleEvent(EVENT_CURSE_FATIGUE, 12000); + } - instance->SetBossState(DATA_KRIKTHIR_THE_GATEWATCHER, NOT_STARTED); - } + void Summon() + { + for (uint8 i = 0; i < 8; i++) + { + me->SummonCreature(NPC_SKITTERING_SWARMER, SpawnPoint[i], TEMPSUMMON_TIMED_DESPAWN, 25000); + uint32 summon_entry = (i == 4 || i == 5 || i == 6) ? NPC_SKITTERING_INFECTIOR : NPC_SKITTERING_SWARMER; + me->SummonCreature(summon_entry, SpawnPoint[i], TEMPSUMMON_TIMED_DESPAWN, 25000); + } + } - void EnterCombat(Unit* /*who*/) OVERRIDE - { - Talk(SAY_AGGRO); - Summon(); - uiSummonTimer = 15*IN_MILLISECONDS; + void UpdateAI(uint32 diff) OVERRIDE + { + if (!UpdateVictim()) + return; - instance->SetBossState(DATA_KRIKTHIR_THE_GATEWATCHER, IN_PROGRESS); - } + events.Update(diff); - void Summon() - { - me->SummonCreature(NPC_SKITTERING_SWARMER, SpawnPoint[0], TEMPSUMMON_TIMED_DESPAWN, 25*IN_MILLISECONDS); - me->SummonCreature(NPC_SKITTERING_SWARMER, SpawnPoint[0], TEMPSUMMON_TIMED_DESPAWN, 25*IN_MILLISECONDS); - me->SummonCreature(NPC_SKITTERING_SWARMER, SpawnPoint[1], TEMPSUMMON_TIMED_DESPAWN, 25*IN_MILLISECONDS); - me->SummonCreature(NPC_SKITTERING_SWARMER, SpawnPoint[1], TEMPSUMMON_TIMED_DESPAWN, 25*IN_MILLISECONDS); - me->SummonCreature(NPC_SKITTERING_SWARMER, SpawnPoint[2], TEMPSUMMON_TIMED_DESPAWN, 25*IN_MILLISECONDS); - me->SummonCreature(NPC_SKITTERING_SWARMER, SpawnPoint[2], TEMPSUMMON_TIMED_DESPAWN, 25*IN_MILLISECONDS); - me->SummonCreature(NPC_SKITTERING_SWARMER, SpawnPoint[3], TEMPSUMMON_TIMED_DESPAWN, 25*IN_MILLISECONDS); - me->SummonCreature(NPC_SKITTERING_SWARMER, SpawnPoint[3], TEMPSUMMON_TIMED_DESPAWN, 25*IN_MILLISECONDS); - me->SummonCreature(NPC_SKITTERING_INFECTIOR, SpawnPoint[4], TEMPSUMMON_TIMED_DESPAWN, 25*IN_MILLISECONDS); - me->SummonCreature(NPC_SKITTERING_SWARMER, SpawnPoint[4], TEMPSUMMON_TIMED_DESPAWN, 25*IN_MILLISECONDS); - me->SummonCreature(NPC_SKITTERING_INFECTIOR, SpawnPoint[5], TEMPSUMMON_TIMED_DESPAWN, 25*IN_MILLISECONDS); - me->SummonCreature(NPC_SKITTERING_SWARMER, SpawnPoint[5], TEMPSUMMON_TIMED_DESPAWN, 25*IN_MILLISECONDS); - me->SummonCreature(NPC_SKITTERING_INFECTIOR, SpawnPoint[6], TEMPSUMMON_TIMED_DESPAWN, 25*IN_MILLISECONDS); - me->SummonCreature(NPC_SKITTERING_SWARMER, SpawnPoint[6], TEMPSUMMON_TIMED_DESPAWN, 25*IN_MILLISECONDS); - me->SummonCreature(NPC_SKITTERING_SWARMER, SpawnPoint[7], TEMPSUMMON_TIMED_DESPAWN, 25*IN_MILLISECONDS); - me->SummonCreature(NPC_SKITTERING_SWARMER, SpawnPoint[7], TEMPSUMMON_TIMED_DESPAWN, 25*IN_MILLISECONDS); - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void UpdateAI(uint32 diff) OVERRIDE - { - if (!UpdateVictim()) - return; + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SUMMON: + Summon(); + events.ScheduleEvent(EVENT_SUMMON, 15000); + break; + case EVENT_MIND_FLAY: + DoCastVictim(SPELL_MIND_FLAY); + events.ScheduleEvent(EVENT_MIND_FLAY, 15000); + break; + case EVENT_CURSE_FATIGUE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + DoCast(target, SPELL_CURSE_OF_FATIGUE); + events.ScheduleEvent(EVENT_CURSE_FATIGUE, 10000); + break; + default: + break; + } + } - if (uiSummonTimer <= diff) - { - Summon(); - uiSummonTimer = 15*IN_MILLISECONDS; - } else uiSummonTimer -= diff; + if (!me->HasAura(SPELL_FRENZY) && HealthBelowPct(10)) + DoCast(me, SPELL_FRENZY, true); - if (uiMindFlayTimer <= diff) - { - DoCastVictim(SPELL_MIND_FLAY); - uiMindFlayTimer = 15*IN_MILLISECONDS; - } else uiMindFlayTimer -= diff; + DoMeleeAttackIfReady(); + } - if (uiCurseFatigueTimer <= diff) + void JustDied(Unit* /*killer*/) OVERRIDE { - //WowWiki say "Curse of Fatigue-Kirk'thir will cast Curse of Fatigue on 2-3 targets periodically." - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_CURSE_OF_FATIGUE); - if (Unit* tankTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true)) - DoCast(tankTarget, SPELL_CURSE_OF_FATIGUE); - - uiCurseFatigueTimer = 10*IN_MILLISECONDS; - } else uiCurseFatigueTimer -= diff; - - if (!me->HasAura(SPELL_FRENZY) && HealthBelowPct(10)) - DoCast(me, SPELL_FRENZY, true); - - DoMeleeAttackIfReady(); - } - void JustDied(Unit* /*killer*/) OVERRIDE - { - Talk(SAY_DEATH); + Talk(SAY_DEATH); + _JustDied(); + } - instance->SetBossState(DATA_KRIKTHIR_THE_GATEWATCHER, DONE); - } + void KilledUnit(Unit* victim) OVERRIDE + { + if (victim->GetTypeId() != TYPEID_PLAYER) + return; - void KilledUnit(Unit* victim) OVERRIDE - { - if (victim->GetTypeId() != TYPEID_PLAYER) - return; + Talk(SAY_SLAY); + } - Talk(SAY_SLAY); - } + void JustSummoned(Creature* summoned) OVERRIDE + { + summoned->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); + } + }; - void JustSummoned(Creature* summoned) OVERRIDE + CreatureAI* GetAI(Creature* creature) const OVERRIDE { - summoned->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); + return GetAzjolNerubAI(creature); } - }; - - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return GetInstanceAI(creature); - } }; class npc_skittering_infector : public CreatureScript { -public: - npc_skittering_infector() : CreatureScript("npc_skittering_infector") { } + public: + npc_skittering_infector() : CreatureScript("npc_skittering_infector") { } - struct npc_skittering_infectorAI : public ScriptedAI - { - npc_skittering_infectorAI(Creature* creature) : ScriptedAI(creature) { } + struct npc_skittering_infectorAI : public ScriptedAI + { + npc_skittering_infectorAI(Creature* creature) : ScriptedAI(creature) { } - void JustDied(Unit* /*killer*/) OVERRIDE + void JustDied(Unit* /*killer*/) OVERRIDE + { + DoCastAOE(SPELL_ACID_SPLASH); + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE { - //The spell is not working propperly - DoCastVictim(SPELL_ACID_SPLASH, true); + return new npc_skittering_infectorAI(creature); } - }; +}; - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new npc_skittering_infectorAI(creature); - } +enum TrashEvents +{ + // Anubar Skrimisher + EVENT_ANUBAR_CHARGE, + EVENT_BACKSTAB, + + // Anubar Shadowcaster + EVENT_SHADOW_BOLT, + EVENT_SHADOW_NOVA, + + // Anubar Warrior + EVENT_STRIKE, + EVENT_CLEAVE, + + // Watcher Gashra + EVENT_WEB_WRAP_GASHRA, + EVENT_INFECTED_BITE_GASHRA, + + // Watcher Narjil + EVENT_WEB_WRAP_NARJIL, + EVENT_INFECTED_BITE_NARJIL, + EVENT_BINDING_WEBS, + + // Watcher Silthik + EVENT_WEB_WRAP_SILTHIK, + EVENT_INFECTED_BITE_SILTHIK, + EVENT_POISON_SPRAY }; class npc_anub_ar_skirmisher : public CreatureScript { -public: - npc_anub_ar_skirmisher() : CreatureScript("npc_anub_ar_skirmisher") { } - - struct npc_anub_ar_skirmisherAI : public ScriptedAI - { - npc_anub_ar_skirmisherAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 uiChargeTimer; - uint32 uiBackstabTimer; + public: + npc_anub_ar_skirmisher() : CreatureScript("npc_anub_ar_skirmisher") { } - void Reset() OVERRIDE + struct npc_anub_ar_skirmisherAI : public ScriptedAI { - uiChargeTimer = 11*IN_MILLISECONDS; - uiBackstabTimer = 7*IN_MILLISECONDS; - } + npc_anub_ar_skirmisherAI(Creature* creature) : ScriptedAI(creature) { } - void UpdateAI(uint32 diff) OVERRIDE - { - if (!UpdateVictim()) - return; + void Reset() OVERRIDE + { + events.Reset(); + } - if (uiChargeTimer <= diff) + void EnterCombat(Unit* /*who*/) OVERRIDE { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + events.ScheduleEvent(EVENT_ANUBAR_CHARGE, 11000); + events.ScheduleEvent(EVENT_BACKSTAB, 7000); + } + + void UpdateAI(uint32 diff) OVERRIDE + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) { - DoResetThreat(); - me->AddThreat(target, 1.0f); - DoCast(target, SPELL_CHARGE, true); + switch (eventId) + { + case EVENT_ANUBAR_CHARGE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + { + DoResetThreat(); + me->AddThreat(target, 1.0f); + DoCast(target, SPELL_CHARGE, true); + } + events.ScheduleEvent(EVENT_ANUBAR_CHARGE, 15000); + break; + case EVENT_BACKSTAB: + DoCastVictim(SPELL_BACKSTAB); + events.ScheduleEvent(EVENT_BACKSTAB, 12000); + break; + default: + break; + } } - uiChargeTimer = 15*IN_MILLISECONDS; - } else uiChargeTimer -= diff; - if (uiBackstabTimer <= diff) - { - DoCastVictim(SPELL_BACKSTAB); - uiBackstabTimer = 12*IN_MILLISECONDS; - } else uiBackstabTimer -= diff; + DoMeleeAttackIfReady(); + } - DoMeleeAttackIfReady(); + private: + EventMap events; + }; + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new npc_anub_ar_skirmisherAI(creature); } - }; - - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new npc_anub_ar_skirmisherAI(creature); - } }; class npc_anub_ar_shadowcaster : public CreatureScript { -public: - npc_anub_ar_shadowcaster() : CreatureScript("npc_anub_ar_shadowcaster") { } - - struct npc_anub_ar_shadowcasterAI : public ScriptedAI - { - npc_anub_ar_shadowcasterAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 uiShadowBoltTimer; - uint32 uiShadowNovaTimer; + public: + npc_anub_ar_shadowcaster() : CreatureScript("npc_anub_ar_shadowcaster") { } - void Reset() OVERRIDE + struct npc_anub_ar_shadowcasterAI : public ScriptedAI { - uiShadowBoltTimer = 6*IN_MILLISECONDS; - uiShadowNovaTimer = 15*IN_MILLISECONDS; - } + npc_anub_ar_shadowcasterAI(Creature* creature) : ScriptedAI(creature) { } - void UpdateAI(uint32 diff) OVERRIDE - { - if (!UpdateVictim()) - return; + void Reset() OVERRIDE + { + events.Reset(); + } - if (uiShadowBoltTimer <= diff) + void EnterCombat(Unit* /*who*/) OVERRIDE { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_SHADOW_BOLT, true); - uiShadowBoltTimer = 15*IN_MILLISECONDS; - } else uiShadowBoltTimer -= diff; + events.ScheduleEvent(EVENT_SHADOW_BOLT, 6000); + events.ScheduleEvent(EVENT_SHADOW_NOVA, 15000); + } - if (uiShadowNovaTimer <= diff) + void UpdateAI(uint32 diff) OVERRIDE { - DoCastVictim(SPELL_SHADOW_NOVA, true); - uiShadowNovaTimer = 17*IN_MILLISECONDS; - } else uiShadowNovaTimer -= diff; + if (!UpdateVictim()) + return; - DoMeleeAttackIfReady(); - } - }; + events.Update(diff); - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new npc_anub_ar_shadowcasterAI(creature); - } -}; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; -class npc_anub_ar_warrior : public CreatureScript -{ -public: - npc_anub_ar_warrior() : CreatureScript("npc_anub_ar_warrior") { } + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SHADOW_BOLT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + DoCast(target, SPELL_SHADOW_BOLT, true); + events.ScheduleEvent(EVENT_SHADOW_BOLT, 15000); + break; + case EVENT_SHADOW_NOVA: + DoCastVictim(SPELL_SHADOW_NOVA, true); + events.ScheduleEvent(EVENT_SHADOW_NOVA, 17000); + break; + default: + break; + } + } - struct npc_anub_ar_warriorAI : public ScriptedAI - { - npc_anub_ar_warriorAI(Creature* creature) : ScriptedAI(creature){ } + DoMeleeAttackIfReady(); + } - uint32 uiCleaveTimer; - uint32 uiStrikeTimer; + private: + EventMap events; + }; - void Reset() OVERRIDE + CreatureAI* GetAI(Creature* creature) const OVERRIDE { - uiCleaveTimer = 11*IN_MILLISECONDS; - uiStrikeTimer = 6*IN_MILLISECONDS; + return new npc_anub_ar_shadowcasterAI(creature); } +}; - void UpdateAI(uint32 diff) OVERRIDE +class npc_anub_ar_warrior : public CreatureScript +{ + public: + npc_anub_ar_warrior() : CreatureScript("npc_anub_ar_warrior") { } + + struct npc_anub_ar_warriorAI : public ScriptedAI { - if (!UpdateVictim()) - return; + npc_anub_ar_warriorAI(Creature* creature) : ScriptedAI(creature) { } - if (uiStrikeTimer <= diff) + void Reset() OVERRIDE { - DoCastVictim(SPELL_STRIKE, true); - uiStrikeTimer = 15*IN_MILLISECONDS; - } else uiStrikeTimer -= diff; + events.Reset(); + } - if (uiCleaveTimer <= diff) + void EnterCombat(Unit* /*who*/) OVERRIDE { - DoCastVictim(SPELL_CLEAVE, true); - uiCleaveTimer = 17*IN_MILLISECONDS; - } else uiCleaveTimer -= diff; + events.ScheduleEvent(EVENT_CLEAVE, 11000); + events.ScheduleEvent(EVENT_STRIKE, 6000); + } - DoMeleeAttackIfReady(); - } - }; + void UpdateAI(uint32 diff) OVERRIDE + { + if (!UpdateVictim()) + return; - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new npc_anub_ar_warriorAI(creature); - } -}; + events.Update(diff); -class npc_watcher_gashra : public CreatureScript -{ -public: - npc_watcher_gashra() : CreatureScript("npc_watcher_gashra") { } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - struct npc_watcher_gashraAI : public ScriptedAI - { - npc_watcher_gashraAI(Creature* creature) : ScriptedAI(creature) { } + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_CLEAVE: + DoCastVictim(SPELL_STRIKE, true); + events.ScheduleEvent(EVENT_CLEAVE, 15000); + break; + case EVENT_STRIKE: + DoCastVictim(SPELL_CLEAVE, true); + events.ScheduleEvent(EVENT_STRIKE, 17000); + break; + default: + break; + } + } - uint32 uiWebWrapTimer; - uint32 uiInfectedBiteTimer; + DoMeleeAttackIfReady(); + } - void Reset() OVERRIDE - { - uiWebWrapTimer = 11*IN_MILLISECONDS; - uiInfectedBiteTimer = 4*IN_MILLISECONDS; - } + private: + EventMap events; + }; - void EnterCombat(Unit* /*who*/) OVERRIDE + CreatureAI* GetAI(Creature* creature) const OVERRIDE { - DoCast(me, SPELL_ENRAGE, true); + return new npc_anub_ar_warriorAI(creature); } +}; + +class npc_watcher_gashra : public CreatureScript +{ + public: + npc_watcher_gashra() : CreatureScript("npc_watcher_gashra") { } - void UpdateAI(uint32 diff) OVERRIDE + struct npc_watcher_gashraAI : public ScriptedAI { - if (!UpdateVictim()) - return; + npc_watcher_gashraAI(Creature* creature) : ScriptedAI(creature) { } - if (uiWebWrapTimer <= diff) + void Reset() OVERRIDE { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_WEB_WRAP, true); - uiWebWrapTimer = 17*IN_MILLISECONDS; - } else uiWebWrapTimer -= diff; + events.Reset(); + } - if (uiInfectedBiteTimer <= diff) + void EnterCombat(Unit* /*who*/) OVERRIDE + { + DoCast(me, SPELL_ENRAGE, true); + events.ScheduleEvent(EVENT_WEB_WRAP_GASHRA, 11000); + events.ScheduleEvent(EVENT_INFECTED_BITE_GASHRA, 4000); + } + + void JustDied(Unit* /*killer*/) OVERRIDE { - DoCastVictim(SPELL_INFECTED_BITE, true); - uiInfectedBiteTimer = 15*IN_MILLISECONDS; - } else uiInfectedBiteTimer -= diff; + Creature* krikthir = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KRIKTHIR_THE_GATEWATCHER)); + if (krikthir && krikthir->IsAlive()) + krikthir->AI()->Talk(SAY_PREFIGHT); + } - DoMeleeAttackIfReady(); - } - }; + void UpdateAI(uint32 diff) OVERRIDE + { + if (!UpdateVictim()) + return; - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new npc_watcher_gashraAI(creature); - } -}; + events.Update(diff); -class npc_watcher_narjil : public CreatureScript -{ -public: - npc_watcher_narjil() : CreatureScript("npc_watcher_narjil") { } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - struct npc_watcher_narjilAI : public ScriptedAI - { - npc_watcher_narjilAI(Creature* creature) : ScriptedAI(creature) { } + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_WEB_WRAP_GASHRA: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + DoCast(target, SPELL_WEB_WRAP, true); + events.ScheduleEvent(EVENT_WEB_WRAP_GASHRA, 17000); + break; + case EVENT_INFECTED_BITE_GASHRA: + DoCastVictim(SPELL_INFECTED_BITE, true); + events.ScheduleEvent(EVENT_INFECTED_BITE_GASHRA, 15000); + break; + default: + break; + } + } - uint32 uiWebWrapTimer; - uint32 uiInfectedBiteTimer; - uint32 uiBindingWebsTimer; + DoMeleeAttackIfReady(); + } - void Reset() OVERRIDE + private: + EventMap events; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE { - uiWebWrapTimer = 11*IN_MILLISECONDS; - uiInfectedBiteTimer = 4*IN_MILLISECONDS; - uiBindingWebsTimer = 17*IN_MILLISECONDS; + return new npc_watcher_gashraAI(creature); } +}; - void UpdateAI(uint32 diff) OVERRIDE +class npc_watcher_narjil : public CreatureScript +{ + public: + npc_watcher_narjil() : CreatureScript("npc_watcher_narjil") { } + + struct npc_watcher_narjilAI : public ScriptedAI { - if (!UpdateVictim()) - return; + npc_watcher_narjilAI(Creature* creature) : ScriptedAI(creature) { } - if (uiWebWrapTimer <= diff) + void Reset() OVERRIDE { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_WEB_WRAP, true); - uiWebWrapTimer = 15*IN_MILLISECONDS; - } else uiWebWrapTimer -= diff; + events.Reset(); + } - if (uiInfectedBiteTimer <= diff) + void EnterCombat(Unit* /*who*/) OVERRIDE { - DoCastVictim(SPELL_INFECTED_BITE, true); - uiInfectedBiteTimer = 11*IN_MILLISECONDS; - } else uiInfectedBiteTimer -= diff; + events.ScheduleEvent(EVENT_WEB_WRAP_NARJIL, 11000); + 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)); + if (krikthir && krikthir->IsAlive()) + krikthir->AI()->Talk(SAY_PREFIGHT); + } - if (uiBindingWebsTimer <= diff) + void UpdateAI(uint32 diff) OVERRIDE { - DoCastVictim(SPELL_BLINDING_WEBS, true); - uiBindingWebsTimer = 17*IN_MILLISECONDS; - } else uiBindingWebsTimer -= diff; + if (!UpdateVictim()) + return; - DoMeleeAttackIfReady(); - } - }; + events.Update(diff); - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new npc_watcher_narjilAI(creature); - } -}; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; -class npc_watcher_silthik : public CreatureScript -{ -public: - npc_watcher_silthik() : CreatureScript("npc_watcher_silthik") { } + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_WEB_WRAP_NARJIL: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + DoCast(target, SPELL_WEB_WRAP, true); + events.ScheduleEvent(EVENT_WEB_WRAP_NARJIL, 15000); + break; + case EVENT_INFECTED_BITE_NARJIL: + DoCastVictim(SPELL_INFECTED_BITE, true); + events.ScheduleEvent(EVENT_INFECTED_BITE_NARJIL, 11000); + break; + case EVENT_BINDING_WEBS: + DoCastVictim(SPELL_BLINDING_WEBS, true); + events.ScheduleEvent(EVENT_BINDING_WEBS, 17000); + break; + default: + break; + } + } - struct npc_watcher_silthikAI : public ScriptedAI - { - npc_watcher_silthikAI(Creature* creature) : ScriptedAI(creature) { } + DoMeleeAttackIfReady(); + } - uint32 uiWebWrapTimer; - uint32 uiInfectedBiteTimer; - uint32 uiPoisonSprayTimer; + private: + EventMap events; + }; - void Reset() OVERRIDE + CreatureAI* GetAI(Creature* creature) const OVERRIDE { - uiWebWrapTimer = 11*IN_MILLISECONDS; - uiInfectedBiteTimer = 4*IN_MILLISECONDS; - uiPoisonSprayTimer = 15*IN_MILLISECONDS; + return new npc_watcher_narjilAI(creature); } +}; - void UpdateAI(uint32 diff) OVERRIDE +class npc_watcher_silthik : public CreatureScript +{ + public: + npc_watcher_silthik() : CreatureScript("npc_watcher_silthik") { } + + struct npc_watcher_silthikAI : public ScriptedAI { - if (!UpdateVictim()) - return; + npc_watcher_silthikAI(Creature* creature) : ScriptedAI(creature) { } - if (uiWebWrapTimer <= diff) + void Reset() OVERRIDE { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_WEB_WRAP, true); + events.Reset(); + } - uiWebWrapTimer = 15*IN_MILLISECONDS; - } else uiWebWrapTimer -= diff; + void EnterCombat(Unit* /*who*/) OVERRIDE + { + events.ScheduleEvent(EVENT_WEB_WRAP_SILTHIK, 11000); + events.ScheduleEvent(EVENT_INFECTED_BITE_SILTHIK, 4000); + events.ScheduleEvent(EVENT_POISON_SPRAY, 15000); + } - if (uiInfectedBiteTimer <= diff) + void JustDied(Unit* /*killer*/) OVERRIDE { - DoCastVictim(SPELL_INFECTED_BITE, true); - uiInfectedBiteTimer = 15*IN_MILLISECONDS; - } else uiInfectedBiteTimer -= diff; + Creature* krikthir = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KRIKTHIR_THE_GATEWATCHER)); + if (krikthir && krikthir->IsAlive()) + krikthir->AI()->Talk(SAY_PREFIGHT); + } - if (uiPoisonSprayTimer <= diff) + void UpdateAI(uint32 diff) OVERRIDE { - DoCastVictim(SPELL_POSION_SPRAY, true); - uiPoisonSprayTimer = 17*IN_MILLISECONDS; - } else uiPoisonSprayTimer -= diff; + if (!UpdateVictim()) + return; + + events.Update(diff); - DoMeleeAttackIfReady(); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - } - }; + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_WEB_WRAP_SILTHIK: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + DoCast(target, SPELL_WEB_WRAP, true); + events.ScheduleEvent(EVENT_WEB_WRAP_SILTHIK, 15000); + break; + case EVENT_INFECTED_BITE_SILTHIK: + DoCastVictim(SPELL_INFECTED_BITE, true); + events.ScheduleEvent(EVENT_INFECTED_BITE_SILTHIK, 11000); + break; + case EVENT_POISON_SPRAY: + DoCastVictim(SPELL_POSION_SPRAY, true); + events.ScheduleEvent(EVENT_POISON_SPRAY, 17000); + break; + default: + break; + } + } - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new npc_watcher_silthikAI(creature); - } + DoMeleeAttackIfReady(); + } + + private: + EventMap events; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new npc_watcher_silthikAI(creature); + } }; class achievement_watch_him_die : public AchievementCriteriaScript -- cgit v1.2.3 From 1d1aeda86ca69e78daf85c3c4b1b29509c374ad7 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Sun, 9 Feb 2014 19:01:56 +0100 Subject: Core: Fix build --- .../AzjolNerub/boss_krikthir_the_gatewatcher.cpp | 79 +++++++++++----------- 1 file changed, 41 insertions(+), 38 deletions(-) (limited to 'src/server/scripts/Northrend') 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 dd926acba28..d0e1103c5df 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 @@ -196,7 +196,7 @@ class npc_skittering_infector : public CreatureScript CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return new npc_skittering_infectorAI(creature); + return GetAzjolNerubAI(creature); } }; @@ -290,7 +290,7 @@ class npc_anub_ar_skirmisher : public CreatureScript CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return new npc_anub_ar_skirmisherAI(creature); + return GetAzjolNerubAI(creature); } }; @@ -351,7 +351,7 @@ class npc_anub_ar_shadowcaster : public CreatureScript CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return new npc_anub_ar_shadowcasterAI(creature); + return GetAzjolNerubAI(creature); } }; @@ -411,7 +411,7 @@ class npc_anub_ar_warrior : public CreatureScript CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return new npc_anub_ar_warriorAI(creature); + return GetAzjolNerubAI(creature); } }; @@ -426,19 +426,19 @@ class npc_watcher_gashra : public CreatureScript void Reset() OVERRIDE { - events.Reset(); + _events.Reset(); } void EnterCombat(Unit* /*who*/) OVERRIDE { DoCast(me, SPELL_ENRAGE, true); - events.ScheduleEvent(EVENT_WEB_WRAP_GASHRA, 11000); - events.ScheduleEvent(EVENT_INFECTED_BITE_GASHRA, 4000); + _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)); + Creature* krikthir = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_KRIKTHIR_THE_GATEWATCHER)); if (krikthir && krikthir->IsAlive()) krikthir->AI()->Talk(SAY_PREFIGHT); } @@ -448,23 +448,23 @@ class npc_watcher_gashra : public CreatureScript if (!UpdateVictim()) return; - events.Update(diff); + _events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_WEB_WRAP_GASHRA: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(target, SPELL_WEB_WRAP, true); - events.ScheduleEvent(EVENT_WEB_WRAP_GASHRA, 17000); + _events.ScheduleEvent(EVENT_WEB_WRAP_GASHRA, 17000); break; case EVENT_INFECTED_BITE_GASHRA: DoCastVictim(SPELL_INFECTED_BITE, true); - events.ScheduleEvent(EVENT_INFECTED_BITE_GASHRA, 15000); + _events.ScheduleEvent(EVENT_INFECTED_BITE_GASHRA, 15000); break; default: break; @@ -475,12 +475,13 @@ class npc_watcher_gashra : public CreatureScript } private: - EventMap events; + EventMap _events; + InstanceScript* _instance; }; CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return new npc_watcher_gashraAI(creature); + return GetAzjolNerubAI(creature); } }; @@ -495,19 +496,19 @@ class npc_watcher_narjil : public CreatureScript void Reset() OVERRIDE { - events.Reset(); + _events.Reset(); } void EnterCombat(Unit* /*who*/) OVERRIDE { - events.ScheduleEvent(EVENT_WEB_WRAP_NARJIL, 11000); - events.ScheduleEvent(EVENT_INFECTED_BITE_NARJIL, 4000); - events.ScheduleEvent(EVENT_BINDING_WEBS, 17000); + _events.ScheduleEvent(EVENT_WEB_WRAP_NARJIL, 11000); + _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)); + Creature* krikthir = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_KRIKTHIR_THE_GATEWATCHER)); if (krikthir && krikthir->IsAlive()) krikthir->AI()->Talk(SAY_PREFIGHT); } @@ -517,27 +518,27 @@ class npc_watcher_narjil : public CreatureScript if (!UpdateVictim()) return; - events.Update(diff); + _events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_WEB_WRAP_NARJIL: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(target, SPELL_WEB_WRAP, true); - events.ScheduleEvent(EVENT_WEB_WRAP_NARJIL, 15000); + _events.ScheduleEvent(EVENT_WEB_WRAP_NARJIL, 15000); break; case EVENT_INFECTED_BITE_NARJIL: DoCastVictim(SPELL_INFECTED_BITE, true); - events.ScheduleEvent(EVENT_INFECTED_BITE_NARJIL, 11000); + _events.ScheduleEvent(EVENT_INFECTED_BITE_NARJIL, 11000); break; case EVENT_BINDING_WEBS: DoCastVictim(SPELL_BLINDING_WEBS, true); - events.ScheduleEvent(EVENT_BINDING_WEBS, 17000); + _events.ScheduleEvent(EVENT_BINDING_WEBS, 17000); break; default: break; @@ -548,12 +549,13 @@ class npc_watcher_narjil : public CreatureScript } private: - EventMap events; + EventMap _events; + InstanceScript* _instance; }; CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return new npc_watcher_narjilAI(creature); + return GetAzjolNerubAI(creature); } }; @@ -568,19 +570,19 @@ class npc_watcher_silthik : public CreatureScript void Reset() OVERRIDE { - events.Reset(); + _events.Reset(); } void EnterCombat(Unit* /*who*/) OVERRIDE { - events.ScheduleEvent(EVENT_WEB_WRAP_SILTHIK, 11000); - events.ScheduleEvent(EVENT_INFECTED_BITE_SILTHIK, 4000); - events.ScheduleEvent(EVENT_POISON_SPRAY, 15000); + _events.ScheduleEvent(EVENT_WEB_WRAP_SILTHIK, 11000); + _events.ScheduleEvent(EVENT_INFECTED_BITE_SILTHIK, 4000); + _events.ScheduleEvent(EVENT_POISON_SPRAY, 15000); } void JustDied(Unit* /*killer*/) OVERRIDE { - Creature* krikthir = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KRIKTHIR_THE_GATEWATCHER)); + Creature* krikthir = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_KRIKTHIR_THE_GATEWATCHER)); if (krikthir && krikthir->IsAlive()) krikthir->AI()->Talk(SAY_PREFIGHT); } @@ -590,27 +592,27 @@ class npc_watcher_silthik : public CreatureScript if (!UpdateVictim()) return; - events.Update(diff); + _events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_WEB_WRAP_SILTHIK: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(target, SPELL_WEB_WRAP, true); - events.ScheduleEvent(EVENT_WEB_WRAP_SILTHIK, 15000); + _events.ScheduleEvent(EVENT_WEB_WRAP_SILTHIK, 15000); break; case EVENT_INFECTED_BITE_SILTHIK: DoCastVictim(SPELL_INFECTED_BITE, true); - events.ScheduleEvent(EVENT_INFECTED_BITE_SILTHIK, 11000); + _events.ScheduleEvent(EVENT_INFECTED_BITE_SILTHIK, 11000); break; case EVENT_POISON_SPRAY: DoCastVictim(SPELL_POSION_SPRAY, true); - events.ScheduleEvent(EVENT_POISON_SPRAY, 17000); + _events.ScheduleEvent(EVENT_POISON_SPRAY, 17000); break; default: break; @@ -621,12 +623,13 @@ class npc_watcher_silthik : public CreatureScript } private: - EventMap events; + EventMap _events; + InstanceScript* _instance; }; CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return new npc_watcher_silthikAI(creature); + return GetAzjolNerubAI(creature); } }; -- cgit v1.2.3 From a5a6799b4e46456decbac09622f0bef0ac1976bb Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Sun, 9 Feb 2014 19:15:17 +0100 Subject: Scripts: Added missing stuff in 1d1aeda86ca69e78daf85c3c4b1b29509c374ad7 --- .../AzjolNerub/boss_krikthir_the_gatewatcher.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/server/scripts/Northrend') 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 d0e1103c5df..19e6b55b5c5 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 @@ -422,7 +422,10 @@ class npc_watcher_gashra : public CreatureScript struct npc_watcher_gashraAI : public ScriptedAI { - npc_watcher_gashraAI(Creature* creature) : ScriptedAI(creature) { } + npc_watcher_gashraAI(Creature* creature) : ScriptedAI(creature) + { + _instance = creature->GetInstanceScript(); + } void Reset() OVERRIDE { @@ -492,7 +495,10 @@ class npc_watcher_narjil : public CreatureScript struct npc_watcher_narjilAI : public ScriptedAI { - npc_watcher_narjilAI(Creature* creature) : ScriptedAI(creature) { } + npc_watcher_narjilAI(Creature* creature) : ScriptedAI(creature) + { + _instance = creature->GetInstanceScript(); + } void Reset() OVERRIDE { @@ -566,7 +572,10 @@ class npc_watcher_silthik : public CreatureScript struct npc_watcher_silthikAI : public ScriptedAI { - npc_watcher_silthikAI(Creature* creature) : ScriptedAI(creature) { } + npc_watcher_silthikAI(Creature* creature) : ScriptedAI(creature) + { + _instance = creature->GetInstanceScript(); + } void Reset() OVERRIDE { -- cgit v1.2.3 From 50d99005a564cca7dfd9535f21a6b54b45146615 Mon Sep 17 00:00:00 2001 From: w1sht0l1v3 Date: Sun, 16 Feb 2014 02:27:44 +0200 Subject: Scripts/Ulduar: Fix Algalon the Observer outro phase(fixes kill credit and some achieves). --- src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/server/scripts/Northrend') diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index 9599700eccb..e2c6a72241e 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -652,7 +652,6 @@ class boss_algalon_the_observer : public CreatureScript break; case EVENT_OUTRO_2: _EnterEvadeMode(); - me->AddUnitState(UNIT_STATE_EVADE); me->GetMotionMaster()->MovePoint(POINT_ALGALON_OUTRO, AlgalonOutroPos); break; case EVENT_OUTRO_3: -- cgit v1.2.3 From ba28b16d2e6a12ae68b9fd3232c5a703652a6920 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sun, 9 Mar 2014 17:17:12 +0100 Subject: Scripts/TheStormPeaks: Possible crash fix Apply safe NULL checks added in 7d881a073961887d446d4430905f315b52928bb1 to similar code in same script --- src/server/scripts/Northrend/zone_storm_peaks.cpp | 29 ++++++++++++----------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'src/server/scripts/Northrend') diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp index 70de4d4758d..1c6ec703f0c 100644 --- a/src/server/scripts/Northrend/zone_storm_peaks.cpp +++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp @@ -290,22 +290,23 @@ public: events.ScheduleEvent(EVENT_CHECK_AREA, 5000); break; case EVENT_REACHED_HOME: - Unit* player = me->GetVehicleKit()->GetPassenger(0); - if (player && player->GetTypeId() == TYPEID_PLAYER) - { - // for each prisoner on drake, give credit - for (uint8 i = 1; i < 4; ++i) - if (Unit* prisoner = me->GetVehicleKit()->GetPassenger(i)) + if (Vehicle* vehicle = me->GetVehicleKit()) + if (Unit* player = vehicle->GetPassenger(0)) + if (player->GetTypeId() == TYPEID_PLAYER) { - if (prisoner->GetTypeId() != TYPEID_UNIT) - return; - prisoner->CastSpell(player, SPELL_KILL_CREDIT_PRISONER, true); - prisoner->CastSpell(prisoner, SPELL_SUMMON_LIBERATED, true); - prisoner->ExitVehicle(); + // for each prisoner on drake, give credit + for (uint8 i = 1; i < 4; ++i) + if (Unit* prisoner = me->GetVehicleKit()->GetPassenger(i)) + { + if (prisoner->GetTypeId() != TYPEID_UNIT) + return; + prisoner->CastSpell(player, SPELL_KILL_CREDIT_PRISONER, true); + prisoner->CastSpell(prisoner, SPELL_SUMMON_LIBERATED, true); + prisoner->ExitVehicle(); + } + me->CastSpell(me, SPELL_KILL_CREDIT_DRAKE, true); + player->ExitVehicle(); } - me->CastSpell(me, SPELL_KILL_CREDIT_DRAKE, true); - player->ExitVehicle(); - } break; } } -- cgit v1.2.3 From e30b471f8e0975530562cf3a1cf83bce07906b7b Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sat, 15 Mar 2014 20:04:59 +0100 Subject: Scripts/AhnKahet: Fix some uninitialized values Initialize all class fields in the constructor, even if they are set in Reset() and they shouldn't be accessed before Reset() is called. This fixes 2 Coverity reports. --- .../Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/server/scripts/Northrend') 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 efe439de440..31c565e5be2 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp @@ -88,6 +88,9 @@ class boss_prince_taldaram : public CreatureScript boss_prince_taldaramAI(Creature* creature) : BossAI(creature, DATA_PRINCE_TALDARAM) { me->SetDisableGravity(true); + _flameSphereTargetGUID = 0; + _embraceTargetGUID = 0; + _embraceTakenDamage = 0; } void Reset() OVERRIDE @@ -283,7 +286,10 @@ 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; + } void Reset() OVERRIDE { -- cgit v1.2.3 From a1aa4547b3229a6b8c62fd4f3ebc72bfe9c7d316 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sat, 15 Mar 2014 20:08:55 +0100 Subject: Scripts/Krikthir the Gatewatcher: Fix EVENT_ANUBAR_CHARGE event not being triggered Fix EVENT_ANUBAR_CHARGE not being triggered due to value 0 being set to the EVENT_ANUBAR_CHARGE enum, even if 0 is a special value for EventMap to specify no event was triggered. Issue added in a127c0e1a7612094c2bf8b2f5092f55aa96f0556 --- .../Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server/scripts/Northrend') 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 19e6b55b5c5..1281d40fe5c 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 @@ -203,7 +203,7 @@ class npc_skittering_infector : public CreatureScript enum TrashEvents { // Anubar Skrimisher - EVENT_ANUBAR_CHARGE, + EVENT_ANUBAR_CHARGE = 1, EVENT_BACKSTAB, // Anubar Shadowcaster -- cgit v1.2.3 From f26a028d9704ffbe0bfe080501adb0261a6fc0e7 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sun, 16 Mar 2014 14:18:33 +0100 Subject: Core/Misc: Fix some static analysis issues Fix some static analysis issues about uninitialized values. Most of them are false positives, always initialized before being accessed. --- src/server/game/Tickets/TicketMgr.cpp | 4 +++- src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp | 1 + src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp | 2 ++ .../TrialOfTheCrusader/boss_northrend_beasts.cpp | 2 ++ .../FrozenHalls/HallsOfReflection/halls_of_reflection.cpp | 5 ++++- src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp | 10 ++++++++-- src/server/scripts/Northrend/zone_dragonblight.cpp | 1 + src/server/scripts/Northrend/zone_storm_peaks.cpp | 4 ++++ src/server/scripts/Northrend/zone_zuldrak.cpp | 6 +++++- .../Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp | 6 +++++- src/server/scripts/Outland/zone_blades_edge_mountains.cpp | 1 + 11 files changed, 36 insertions(+), 6 deletions(-) (limited to 'src/server/scripts/Northrend') diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp index 43c9ba80e24..b9ecfffb8c3 100644 --- a/src/server/game/Tickets/TicketMgr.cpp +++ b/src/server/game/Tickets/TicketMgr.cpp @@ -36,7 +36,9 @@ GmTicket::GmTicket() : _id(0), _playerGuid(0), _posX(0), _posY(0), _posZ(0), _ma _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false), _needResponse(false), _needMoreHelp(false) { } -GmTicket::GmTicket(Player* player) : _createTime(time(NULL)), _lastModifiedTime(time(NULL)), _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false), _needResponse(false), _needMoreHelp(false) +GmTicket::GmTicket(Player* player) : _posX(0), _posY(0), _posZ(0), _mapId(0), _createTime(time(NULL)), _lastModifiedTime(time(NULL)), + _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false), + _needResponse(false), _needMoreHelp(false) { _id = sTicketMgr->GenerateTicketId(); _playerName = player->GetName(); diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp b/src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp index 830c3fed382..1e0d481249d 100644 --- a/src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp +++ b/src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp @@ -42,6 +42,7 @@ public: { boss_gluttonAI(Creature* creature) : BossAI(creature, DATA_GLUTTON) { + hp50 = false; hp15 = false; } diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp index b9605794074..f1d8e1b67e8 100644 --- a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp +++ b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp @@ -158,6 +158,8 @@ public: { instance = creature->GetInstanceScript(); eventInProgress = false; + channeling = false; + eventProgress = 0; spawnerCount = 0; } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp index ea166585bb3..4210ebfcad5 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp @@ -294,6 +294,8 @@ class npc_snobold_vassal : public CreatureScript { npc_snobold_vassalAI(Creature* creature) : ScriptedAI(creature) { + _targetGUID = 0; + _targetDied = false; _instance = creature->GetInstanceScript(); _instance->SetData(DATA_SNOBOLD_COUNT, INCREASE); } diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index 1f4713415ac..de14b930220 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -1180,7 +1180,10 @@ enum TrashEvents struct npc_gauntlet_trash : public ScriptedAI { - npc_gauntlet_trash(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } + npc_gauntlet_trash(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) + { + InternalWaveId = 0; + } void Reset() OVERRIDE { diff --git a/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp b/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp index dd1d35e639e..9a83c33890e 100644 --- a/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp +++ b/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp @@ -219,7 +219,10 @@ public: struct npc_slad_ran_constrictorAI : public ScriptedAI { - npc_slad_ran_constrictorAI(Creature* creature) : ScriptedAI(creature) { } + npc_slad_ran_constrictorAI(Creature* creature) : ScriptedAI(creature) + { + uiGripOfSladRanTimer = 1 * IN_MILLISECONDS; + } uint32 uiGripOfSladRanTimer; @@ -270,7 +273,10 @@ public: struct npc_slad_ran_viperAI : public ScriptedAI { - npc_slad_ran_viperAI(Creature* creature) : ScriptedAI(creature) { } + npc_slad_ran_viperAI(Creature* creature) : ScriptedAI(creature) + { + uiVenomousBiteTimer = 2 * IN_MILLISECONDS; + } uint32 uiVenomousBiteTimer; diff --git a/src/server/scripts/Northrend/zone_dragonblight.cpp b/src/server/scripts/Northrend/zone_dragonblight.cpp index 7487c3c8828..a9c46d19138 100644 --- a/src/server/scripts/Northrend/zone_dragonblight.cpp +++ b/src/server/scripts/Northrend/zone_dragonblight.cpp @@ -654,6 +654,7 @@ class npc_torturer_lecraft : public CreatureScript { npc_torturer_lecraftAI(Creature* creature) : ScriptedAI(creature) { + _textCounter = 1; _playerGUID = 0; } diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp index 1c6ec703f0c..84cf02cfe13 100644 --- a/src/server/scripts/Northrend/zone_storm_peaks.cpp +++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp @@ -454,6 +454,9 @@ public: { npc_brann_bronzebeard_keystoneAI(Creature* creature) : ScriptedAI(creature) { + memset(&objectGUID, 0, sizeof(objectGUID)); + playerGUID = 0; + voiceGUID = 0; objectCounter = 0; } @@ -640,6 +643,7 @@ public: { npc_king_jokkum_vehicleAI(Creature* creature) : VehicleAI(creature) { + playerGUID = 0; pathEnd = false; } diff --git a/src/server/scripts/Northrend/zone_zuldrak.cpp b/src/server/scripts/Northrend/zone_zuldrak.cpp index 8f5ae0f65ff..0f542b3aca7 100644 --- a/src/server/scripts/Northrend/zone_zuldrak.cpp +++ b/src/server/scripts/Northrend/zone_zuldrak.cpp @@ -453,7 +453,11 @@ public: struct npc_alchemist_finklesteinAI : public ScriptedAI { - npc_alchemist_finklesteinAI(Creature* creature) : ScriptedAI(creature) { } + npc_alchemist_finklesteinAI(Creature* creature) : ScriptedAI(creature) + { + _playerGUID = 0; + _getingredienttry = 0; + } void Reset() OVERRIDE { diff --git a/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp index 5266a7bd137..c9d452bfada 100644 --- a/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp +++ b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp @@ -61,7 +61,11 @@ public: struct npc_stolen_soulAI : public ScriptedAI { - npc_stolen_soulAI(Creature* creature) : ScriptedAI(creature) { } + npc_stolen_soulAI(Creature* creature) : ScriptedAI(creature) + { + myClass = CLASS_NONE; + Class_Timer = 1000; + } uint8 myClass; uint32 Class_Timer; diff --git a/src/server/scripts/Outland/zone_blades_edge_mountains.cpp b/src/server/scripts/Outland/zone_blades_edge_mountains.cpp index 3f1579c42b1..fdeaa1c2520 100644 --- a/src/server/scripts/Outland/zone_blades_edge_mountains.cpp +++ b/src/server/scripts/Outland/zone_blades_edge_mountains.cpp @@ -115,6 +115,7 @@ public: { npc_bloodmaul_bruteAI(Creature* creature) : ScriptedAI(creature) { + PlayerGUID = 0; hp30 = false; } -- cgit v1.2.3 From 4bcbcf53d885d38d515010b64874f634ffc2f824 Mon Sep 17 00:00:00 2001 From: Gacko Date: Wed, 19 Mar 2014 10:05:02 +0100 Subject: Core/Script: Logical fixes --- .../ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/server/scripts/Northrend') diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp index 9ae6f811e19..a24cd4db7c5 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp @@ -73,7 +73,7 @@ enum Enums //Whelps NPC_TWILIGHT_WHELP = 30890, - NPC_SHARTHARION_TWILIGHT_WHELP = 31214, + NPC_SARTHARION_TWILIGHT_WHELP = 31214, SPELL_FADE_ARMOR = 60708, // Reduces the armor of an enemy by 1500 for 15s //flame tsunami @@ -253,7 +253,7 @@ struct dummy_dragonAI : public ScriptedAI { case NPC_TENEBRON: { - if (!instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS) + if (instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS) { for (uint32 i = 0; i < 6; ++i) me->SummonCreature(NPC_TWILIGHT_EGG, TwilightEggs[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000); @@ -267,7 +267,7 @@ struct dummy_dragonAI : public ScriptedAI } case NPC_SHADRON: { - if (!instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS) + if (instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS) me->SummonCreature(NPC_ACOLYTE_OF_SHADRON, AcolyteofShadron, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 28000); else me->SummonCreature(NPC_ACOLYTE_OF_SHADRON, AcolyteofShadron2, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 28000); @@ -276,7 +276,7 @@ struct dummy_dragonAI : public ScriptedAI } case NPC_VESPERON: { - if (!instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS) + if (instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS) { if (Creature* acolyte = me->SummonCreature(NPC_ACOLYTE_OF_VESPERON, AcolyteofVesperon, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000)) { @@ -816,10 +816,10 @@ public: { me->RemoveAllAuras(); - if (!instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS) + if (instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS) me->SummonCreature(NPC_TWILIGHT_WHELP, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000); else - me->SummonCreature(NPC_SHARTHARION_TWILIGHT_WHELP, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000); + me->SummonCreature(NPC_SARTHARION_TWILIGHT_WHELP, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000); me->DealDamage(me, me->GetHealth()); } -- cgit v1.2.3 From 9e99db035f554c8f4954e025f599ef752c1f4e01 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Fri, 21 Mar 2014 22:47:58 +0100 Subject: Core/Misc: Fix some static analysis issues Add some asserts and additional NULL checks as sanity checks. --- src/server/game/DungeonFinding/LFGMgr.cpp | 1 + src/server/game/Entities/GameObject/GameObject.cpp | 1 + src/server/game/Entities/Object/Object.cpp | 2 + src/server/game/Entities/Player/Player.cpp | 5 +++ .../scripts/Northrend/Gundrak/boss_slad_ran.cpp | 5 ++- .../BlackTemple/boss_reliquary_of_souls.cpp | 48 ++++++++++++---------- src/server/scripts/Spells/spell_pet.cpp | 2 + src/server/scripts/Spells/spell_priest.cpp | 1 + src/server/scripts/Spells/spell_rogue.cpp | 1 + src/server/scripts/Spells/spell_warlock.cpp | 3 ++ src/server/scripts/Spells/spell_warrior.cpp | 1 + 11 files changed, 47 insertions(+), 23 deletions(-) (limited to 'src/server/scripts/Northrend') diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 822ae904ef1..8131be9fa45 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -968,6 +968,7 @@ void LFGMgr::MakeNewGroup(LfgProposal const& proposal) player->CastSpell(player, LFG_SPELL_DUNGEON_COOLDOWN, false); } + ASSERT(grp); grp->SetDungeonDifficulty(Difficulty(dungeon->difficulty)); uint64 gguid = grp->GetGUID(); SetDungeon(gguid, dungeon->Entry()); diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 82b4ff3c03d..80171edd715 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -1034,6 +1034,7 @@ void GameObject::TriggeringLinkedGameObject(uint32 trapEntry, Unit* target) if (!trapSpell) // checked at load already return; + ASSERT(GetOwner()); float range = float(target->GetSpellMaxRangeForTarget(GetOwner(), trapSpell)); // search nearest linked GO diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 7241087101d..944498d0fed 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -370,6 +370,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const { if (flags & UPDATEFLAG_POSITION) { + ASSERT(object); Transport* transport = object->GetTransport(); if (transport) @@ -459,6 +460,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const // 0x4 if (flags & UPDATEFLAG_HAS_TARGET) { + ASSERT(unit); if (Unit* victim = unit->GetVictim()) data->append(victim->GetPackGUID()); else diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 6775ef5042b..d96439748e0 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4205,6 +4205,7 @@ bool Player::Has310Flyer(bool checkAllSpells, uint32 excludeSpellId) break; // We can break because mount spells belong only to one skillline (at least 310 flyers do) spellInfo = sSpellMgr->GetSpellInfo(itr->first); + ASSERT(spellInfo); for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED && spellInfo->Effects[i].CalcValue() == 310) @@ -15743,6 +15744,7 @@ bool Player::SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg) // not allow have daily quest if daily quest from exclusive group already recently completed Quest const* Nquest = sObjectMgr->GetQuestTemplate(exclude_Id); + ASSERT(Nquest); if (!SatisfyQuestDay(Nquest, false) || !SatisfyQuestWeek(Nquest, false) || !SatisfyQuestSeasonal(Nquest, false)) { if (msg) @@ -15944,6 +15946,7 @@ bool Player::TakeQuestSourceItem(uint32 questId, bool msg) return false; } + ASSERT(item); bool destroyItem = true; for (uint8 n = 0; n < QUEST_ITEM_OBJECTIVES_COUNT; ++n) if (item->StartQuest == questId && srcItemId == quest->RequiredItemId[n]) @@ -21330,6 +21333,7 @@ bool Player::ActivateTaxiPathTo(std::vector const& nodes, Creature* npc if (sWorld->getBoolConfig(CONFIG_INSTANT_TAXI)) { TaxiNodesEntry const* lastPathNode = sTaxiNodesStore.LookupEntry(nodes[nodes.size()-1]); + ASSERT(lastPathNode); m_taxi.ClearTaxiDestinations(); TeleportTo(lastPathNode->map_id, lastPathNode->x, lastPathNode->y, lastPathNode->z, GetOrientation()); return false; @@ -21550,6 +21554,7 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c if (crItem->ExtendedCost) // case for new honor system { ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost); + ASSERT(iece); if (iece->reqhonorpoints) ModifyHonorPoints(- int32(iece->reqhonorpoints * count)); diff --git a/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp b/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp index 9a83c33890e..0feec20d55f 100644 --- a/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp +++ b/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp @@ -250,8 +250,9 @@ public: target->CastSpell(target, SPELL_SNAKE_WRAP, true); if (TempSummon* _me = me->ToTempSummon()) - if (Creature* sladran = _me->GetSummoner()->ToCreature()) - sladran->AI()->SetGUID(target->GetGUID(), DATA_SNAKES_WHYD_IT_HAVE_TO_BE_SNAKES); + if (Unit* summoner = _me->GetSummoner()) + if (Creature* sladran = summoner->ToCreature()) + sladran->AI()->SetGUID(target->GetGUID(), DATA_SNAKES_WHYD_IT_HAVE_TO_BE_SNAKES); me->DespawnOrUnsummon(); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp index ca0ea947295..d92d8aaf5db 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp @@ -295,13 +295,13 @@ public: Timer = 1000; if (Phase == 3) { - if (!Essence->IsAlive()) + if (Essence && !Essence->IsAlive()) DoCast(me, 7, true); else return; } else { - if (Essence->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) + if (Essence && Essence->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) { MergeThreatList(Essence); Essence->RemoveAllAuras(); @@ -312,31 +312,37 @@ public: break; case 4: Timer = 1500; - if (Essence->IsWithinDistInMap(me, 10)) + if (Essence) { - Essence->SetUInt32Value(UNIT_NPC_EMOTESTATE, 374); //rotate and disappear - Timer = 2000; - me->RemoveAurasDueToSpell(SPELL_SUBMERGE); - } - else - { - MergeThreatList(Essence); - Essence->RemoveAllAuras(); - Essence->DeleteThreatList(); - Essence->GetMotionMaster()->MoveFollow(me, 0, 0); - return; + if (Essence->IsWithinDistInMap(me, 10)) + { + Essence->SetUInt32Value(UNIT_NPC_EMOTESTATE, 374); //rotate and disappear + Timer = 2000; + me->RemoveAurasDueToSpell(SPELL_SUBMERGE); + } + else + { + MergeThreatList(Essence); + Essence->RemoveAllAuras(); + Essence->DeleteThreatList(); + Essence->GetMotionMaster()->MoveFollow(me, 0, 0); + return; + } } break; case 5: - if (Phase == 1) + if (Essence) { - Essence->AI()->Talk(SUFF_SAY_AFTER); - } - else - { - Essence->AI()->Talk(DESI_SAY_AFTER); + if (Phase == 1) + { + Essence->AI()->Talk(SUFF_SAY_AFTER); + } + else + { + Essence->AI()->Talk(DESI_SAY_AFTER); + } + Essence->DespawnOrUnsummon(); } - Essence->DespawnOrUnsummon(); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); EssenceGUID = 0; SoulCount = 0; diff --git a/src/server/scripts/Spells/spell_pet.cpp b/src/server/scripts/Spells/spell_pet.cpp index a7742630ccd..e50bc681352 100644 --- a/src/server/scripts/Spells/spell_pet.cpp +++ b/src/server/scripts/Spells/spell_pet.cpp @@ -941,6 +941,7 @@ public: if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value + ASSERT(spellInfo); mod += CalculatePct(1.0f, spellInfo->Effects[EFFECT_1].CalcValue()); } @@ -971,6 +972,7 @@ public: if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value + ASSERT(spellInfo); mod += CalculatePct(1.0f, spellInfo->Effects[EFFECT_1].CalcValue()); } diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 71e5dac28ec..03d5cbc3f06 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -237,6 +237,7 @@ class spell_pri_glyph_of_prayer_of_healing : public SpellScriptLoader PreventDefaultAction(); SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL); + ASSERT(triggeredSpellInfo); int32 heal = int32(CalculatePct(int32(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()) / triggeredSpellInfo->GetMaxTicks()); GetTarget()->CastCustomSpell(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL, SPELLVALUE_BASE_POINT0, heal, eventInfo.GetProcTarget(), true, NULL, aurEff); } diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index d1d43684f3e..1773805b671 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -429,6 +429,7 @@ class spell_rog_preparation : public SpellScriptLoader for (SpellCooldowns::const_iterator itr = cm.begin(); itr != cm.end();) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); + ASSERT(spellInfo); if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE) { diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 36e63b5a94e..b538d296c3d 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -271,6 +271,7 @@ class spell_warl_demonic_circle_summon : public SpellScriptLoader // If not in range remove the WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST. SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMONIC_CIRCLE_TELEPORT); + ASSERT(spellInfo); if (GetTarget()->IsWithinDist(circle, spellInfo->GetMaxRange(true))) { @@ -353,6 +354,7 @@ class spell_warl_demonic_empowerment : public SpellScriptLoader if (targetCreature->IsPet()) { CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(targetCreature->GetEntry()); + ASSERT(ci); switch (ci->family) { case CREATURE_FAMILY_SUCCUBUS: @@ -361,6 +363,7 @@ class spell_warl_demonic_empowerment : public SpellScriptLoader case CREATURE_FAMILY_VOIDWALKER: { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER); + ASSERT(spellInfo); int32 hp = int32(targetCreature->CountPctFromMaxHealth(GetCaster()->CalculateSpellDamage(targetCreature, spellInfo, 0))); targetCreature->CastCustomSpell(targetCreature, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER, &hp, NULL, NULL, true); //unitTarget->CastSpell(unitTarget, 54441, true); diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index 5a655a92996..d309051114c 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -274,6 +274,7 @@ class spell_warr_deep_wounds : public SpellScriptLoader damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE); SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC); + ASSERT(spellInfo); uint32 ticks = spellInfo->GetDuration() / spellInfo->Effects[EFFECT_0].Amplitude; // Add remaining ticks to damage done -- cgit v1.2.3 From 6dcd8c8545a65a7bfbd0daaa16f650d8c3a90262 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sat, 22 Mar 2014 14:54:32 +0100 Subject: Core/Misc: Fix some static analysis issues Fix some static analysis issues about: - uninitialized values, most of which are false positives, always initialized before being accessed - unchecked return values - dead code never executed - bad formatting leading to wrong behavior Please ensure EventMap is never used with event id set to 0 or those events will never execute. --- src/server/collision/Models/GameObjectModel.h | 2 +- src/server/game/Entities/Unit/Unit.cpp | 6 ++---- src/server/game/Spells/Spell.cpp | 1 + .../EasternKingdoms/AlteracValley/boss_balinda.cpp | 7 ++++++- .../BlackrockSpire/boss_rend_blackhand.cpp | 7 ++++++- .../BlackwingLair/instance_blackwing_lair.cpp | 22 ++++++++++++++++++++++ .../ScarletMonastery/boss_headless_horseman.cpp | 6 +++++- .../BattleForMountHyjal/boss_anetheron.cpp | 2 ++ .../BattleForMountHyjal/boss_azgalor.cpp | 3 +++ .../Kalimdor/RazorfenKraul/razorfen_kraul.cpp | 6 +++++- .../Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp | 14 ++++++++++++++ .../Northrend/Nexus/Oculus/instance_oculus.cpp | 2 ++ .../Mechanar/boss_gatewatcher_ironhand.cpp | 6 +++--- src/server/scripts/Outland/zone_netherstorm.cpp | 10 +++++++++- src/server/shared/Database/AdhocStatement.cpp | 4 ++-- src/server/shared/Database/DatabaseWorkerPool.h | 3 +-- src/server/shared/Database/QueryHolder.cpp | 3 +-- 17 files changed, 85 insertions(+), 19 deletions(-) (limited to 'src/server/scripts/Northrend') diff --git a/src/server/collision/Models/GameObjectModel.h b/src/server/collision/Models/GameObjectModel.h index 06a74cc6eb0..a1c0942dab4 100644 --- a/src/server/collision/Models/GameObjectModel.h +++ b/src/server/collision/Models/GameObjectModel.h @@ -45,7 +45,7 @@ class GameObjectModel /*, public Intersectable*/ float iScale; VMAP::WorldModel* iModel; - GameObjectModel() : phasemask(0), iModel(NULL) { } + GameObjectModel() : phasemask(0), iInvScale(0), iScale(0), iModel(NULL) { } bool initialize(const GameObject& go, const GameObjectDisplayInfoEntry& info); public: diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index e77c0507d26..c9c3a511d97 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -1286,10 +1286,8 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam damageInfo->HitInfo |= HITINFO_AFFECTS_VICTIM; int32 resilienceReduction = damageInfo->damage; - if (attackType != RANGED_ATTACK) - ApplyResilience(victim, NULL, &resilienceReduction, (damageInfo->hitOutCome == MELEE_HIT_CRIT), CR_CRIT_TAKEN_MELEE); - else - ApplyResilience(victim, NULL, &resilienceReduction, (damageInfo->hitOutCome == MELEE_HIT_CRIT), CR_CRIT_TAKEN_RANGED); + // attackType is checked already for BASE_ATTACK or OFF_ATTACK so it can't be RANGED_ATTACK here + ApplyResilience(victim, NULL, &resilienceReduction, (damageInfo->hitOutCome == MELEE_HIT_CRIT), CR_CRIT_TAKEN_MELEE); resilienceReduction = damageInfo->damage - resilienceReduction; damageInfo->damage -= resilienceReduction; damageInfo->cleanDamage += resilienceReduction; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 8b88ec9af92..e215d2fc90f 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5120,6 +5120,7 @@ SpellCastResult Spell::CheckCast(bool strict) case SUMMON_CATEGORY_PET: if (m_caster->GetPetGUID()) return SPELL_FAILED_ALREADY_HAVE_SUMMON; + // intentional missing break, check both GetPetGUID() and GetCharmGUID for SUMMON_CATEGORY_PET case SUMMON_CATEGORY_PUPPET: if (m_caster->GetCharmGUID()) return SPELL_FAILED_ALREADY_HAVE_CHARM; diff --git a/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp b/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp index ab135a2fd78..0b031f54ea0 100644 --- a/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp +++ b/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp @@ -50,7 +50,12 @@ public: struct npc_water_elementalAI : public ScriptedAI { - npc_water_elementalAI(Creature* creature) : ScriptedAI(creature) { } + npc_water_elementalAI(Creature* creature) : ScriptedAI(creature) + { + waterBoltTimer = 3 * IN_MILLISECONDS; + resetTimer = 5 * IN_MILLISECONDS; + balindaGUID = 0; + } uint32 waterBoltTimer; uint64 balindaGUID; diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp index 8989a8065dc..0cb96a519e7 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp @@ -164,7 +164,12 @@ public: struct boss_rend_blackhandAI : public BossAI { - boss_rend_blackhandAI(Creature* creature) : BossAI(creature, DATA_WARCHIEF_REND_BLACKHAND) { } + boss_rend_blackhandAI(Creature* creature) : BossAI(creature, DATA_WARCHIEF_REND_BLACKHAND) + { + gythEvent = false; + victorGUID = 0; + portcullisGUID = 0; + } void Reset() OVERRIDE { diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp index 39d2a6d87d5..560f2e2e995 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp @@ -56,6 +56,28 @@ public: { instance_blackwing_lair_InstanceMapScript(Map* map) : InstanceScript(map) { + // Razorgore + EggCount = 0; + EggEvent = 0; + RazorgoreTheUntamedGUID = 0; + RazorgoreDoorGUID = 0; + // Vaelastrasz the Corrupt + VaelastraszTheCorruptGUID = 0; + VaelastraszDoorGUID = 0; + // Broodlord Lashlayer + BroodlordLashlayerGUID = 0; + BroodlordDoorGUID = 0; + // 3 Dragons + FiremawGUID = 0; + EbonrocGUID = 0; + FlamegorGUID = 0; + ChrommagusDoorGUID = 0; + // Chormaggus + ChromaggusGUID = 0; + NefarianDoorGUID = 0; + // Nefarian + LordVictorNefariusGUID = 0; + NefarianGUID = 0; SetBossNumber(EncounterCount); } diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp index 31219e18121..ad87b2d8d3d 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp @@ -787,7 +787,11 @@ public: struct npc_pulsing_pumpkinAI : public ScriptedAI { - npc_pulsing_pumpkinAI(Creature* creature) : ScriptedAI(creature) { } + npc_pulsing_pumpkinAI(Creature* creature) : ScriptedAI(creature) + { + sprouted = false; + debuffGUID = 0; + } bool sprouted; uint64 debuffGUID; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp index c7803f23e1b..e5ddcd1c2ef 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp @@ -185,6 +185,8 @@ public: { npc_towering_infernalAI(Creature* creature) : ScriptedAI(creature) { + ImmolationTimer = 5000; + CheckTimer = 5000; instance = creature->GetInstanceScript(); AnetheronGUID = instance->GetData64(DATA_ANETHERON); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp index 4decce7482f..16002b59f1a 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp @@ -191,6 +191,9 @@ public: { npc_lesser_doomguardAI(Creature* creature) : hyjal_trashAI(creature) { + CrippleTimer = 50000; + WarstompTimer = 10000; + CheckTimer = 5000; instance = creature->GetInstanceScript(); AzgalorGUID = instance->GetData64(DATA_AZGALOR); } diff --git a/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp b/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp index f04b71d1da9..1dc37e063ba 100644 --- a/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp +++ b/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp @@ -171,7 +171,11 @@ public: struct npc_snufflenose_gopherAI : public PetAI { - npc_snufflenose_gopherAI(Creature* creature) : PetAI(creature) { } + npc_snufflenose_gopherAI(Creature* creature) : PetAI(creature) + { + IsMovementActive = false; + TargetTubberGUID = 0; + } void Reset() OVERRIDE { diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp index 9e3244cccdb..988436066b6 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp @@ -898,6 +898,9 @@ public: { eye_tentacleAI(Creature* creature) : ScriptedAI(creature) { + MindflayTimer = 500; + KillSelfTimer = 35000; + Portal = 0; if (Creature* pPortal = me->SummonCreature(NPC_SMALL_PORTAL, *me, TEMPSUMMON_CORPSE_DESPAWN)) { @@ -974,6 +977,10 @@ public: { claw_tentacleAI(Creature* creature) : ScriptedAI(creature) { + GroundRuptureTimer = 500; + HamstringTimer = 2000; + EvadeTimer = 5000; + SetCombatMovement(false); Portal = 0; @@ -1085,6 +1092,11 @@ public: { giant_claw_tentacleAI(Creature* creature) : ScriptedAI(creature) { + GroundRuptureTimer = 500; + HamstringTimer = 2000; + ThrashTimer = 5000; + EvadeTimer = 5000; + SetCombatMovement(false); Portal = 0; @@ -1205,6 +1217,8 @@ public: { giant_eye_tentacleAI(Creature* creature) : ScriptedAI(creature) { + BeamTimer = 500; + SetCombatMovement(false); Portal = 0; diff --git a/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp index 2c809b17367..39dec9999cc 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp +++ b/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp @@ -208,9 +208,11 @@ class instance_oculus : public InstanceMapScript break; case DATA_VAROS: if (state == DONE) + { DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 0); if (Creature* urom = instance->GetCreature(UromGUID)) urom->SetPhaseMask(1, true); + } break; case DATA_UROM: if (state == DONE) diff --git a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_gatewatcher_ironhand.cpp b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_gatewatcher_ironhand.cpp index e34e4ebdb23..09eb261282f 100644 --- a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_gatewatcher_ironhand.cpp +++ b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_gatewatcher_ironhand.cpp @@ -48,9 +48,9 @@ enum Spells enum Events { - EVENT_STREAM_OF_MACHINE_FLUID = 0, - EVENT_JACKHAMMER = 1, - EVENT_SHADOW_POWER = 2 + EVENT_STREAM_OF_MACHINE_FLUID = 1, + EVENT_JACKHAMMER = 2, + EVENT_SHADOW_POWER = 3 }; class boss_gatewatcher_iron_hand : public CreatureScript diff --git a/src/server/scripts/Outland/zone_netherstorm.cpp b/src/server/scripts/Outland/zone_netherstorm.cpp index 72e7332381b..8542b32d631 100644 --- a/src/server/scripts/Outland/zone_netherstorm.cpp +++ b/src/server/scripts/Outland/zone_netherstorm.cpp @@ -728,7 +728,15 @@ public: struct npc_phase_hunterAI : public ScriptedAI { - npc_phase_hunterAI(Creature* creature) : ScriptedAI(creature) { } + npc_phase_hunterAI(Creature* creature) : ScriptedAI(creature) + { + Weak = false; + Materialize = false; + Drained = false; + WeakPercent = 25; + PlayerGUID = 0; + ManaBurnTimer = 5000; + } bool Weak; bool Materialize; diff --git a/src/server/shared/Database/AdhocStatement.cpp b/src/server/shared/Database/AdhocStatement.cpp index 15732f20849..896fefde5b7 100644 --- a/src/server/shared/Database/AdhocStatement.cpp +++ b/src/server/shared/Database/AdhocStatement.cpp @@ -42,13 +42,13 @@ bool BasicStatementTask::Execute() if (m_has_result) { ResultSet* result = m_conn->Query(m_sql); - if (!result || !result->GetRowCount()) + if (!result || !result->GetRowCount() || !result->NextRow()) { delete result; m_result.set(QueryResult(NULL)); return false; } - result->NextRow(); + m_result.set(QueryResult(result)); return true; } diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index 6c2e961d2ad..e2ebda9e8ae 100644 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -232,13 +232,12 @@ class DatabaseWorkerPool ResultSet* result = conn->Query(sql); conn->Unlock(); - if (!result || !result->GetRowCount()) + if (!result || !result->GetRowCount() || !result->NextRow()) { delete result; return QueryResult(NULL); } - result->NextRow(); return QueryResult(result); } diff --git a/src/server/shared/Database/QueryHolder.cpp b/src/server/shared/Database/QueryHolder.cpp index 0c80f70acd2..7b4105ee076 100644 --- a/src/server/shared/Database/QueryHolder.cpp +++ b/src/server/shared/Database/QueryHolder.cpp @@ -89,10 +89,9 @@ QueryResult SQLQueryHolder::GetResult(size_t index) if (index < m_queries.size()) { ResultSet* result = m_queries[index].second.qresult; - if (!result || !result->GetRowCount()) + if (!result || !result->GetRowCount() || !result->NextRow()) return QueryResult(NULL); - result->NextRow(); return QueryResult(result); } else -- cgit v1.2.3 From 529cabea68ab90e34ccafa276fc40a8f2723902b Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 22 Mar 2014 19:40:36 +0100 Subject: Core/Map: Save weather, light and music overrides in map to send them to players logging in --- src/server/game/DataStores/DBCStores.cpp | 17 ++++ src/server/game/DataStores/DBCStores.h | 2 + src/server/game/DataStores/DBCStructure.h | 18 ++++ src/server/game/DataStores/DBCfmt.h | 1 + src/server/game/Maps/Map.cpp | 103 ++++++++++++++++++++- src/server/game/Maps/Map.h | 22 +++++ .../IcecrownCitadel/boss_the_lich_king.cpp | 70 ++++---------- .../Northrend/IcecrownCitadel/icecrown_citadel.h | 16 ++-- .../IcecrownCitadel/instance_icecrown_citadel.cpp | 10 +- .../Northrend/Nexus/EyeOfEternity/boss_malygos.cpp | 33 ++----- 10 files changed, 198 insertions(+), 94 deletions(-) (limited to 'src/server/scripts/Northrend') diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index a4b3ded80e5..37f4f4c1930 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -123,6 +123,7 @@ DBCStorage sItemRandomSuffixStore(ItemRandomSuffixfmt); DBCStorage sItemSetStore(ItemSetEntryfmt); DBCStorage sLFGDungeonStore(LFGDungeonEntryfmt); +DBCStorage sLightStore(LightEntryfmt); DBCStorage sLiquidTypeStore(LiquidTypefmt); DBCStorage sLockStore(LockEntryfmt); @@ -371,6 +372,7 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales, bad_dbc_files, sItemSetStore, dbcPath, "ItemSet.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sLFGDungeonStore, dbcPath, "LFGDungeons.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sLightStore, dbcPath, "Light.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sLiquidTypeStore, dbcPath, "LiquidType.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sLockStore, dbcPath, "Lock.dbc"); @@ -944,3 +946,18 @@ LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty) return NULL; } + +uint32 GetDefaultMapLight(uint32 mapId) +{ + for (int32 i = sLightStore.GetNumRows(); i >= 0; --i) + { + LightEntry const* light = sLightStore.LookupEntry(uint32(i)); + if (!light) + continue; + + if (light->MapId == mapId && light->X == 0.0f && light->Y == 0.0f && light->Z == 0.0f) + return light->Id; + } + + return 0; +} diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index fe8fb35220b..39747141322 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -72,6 +72,8 @@ CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint8 class_, ui LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty); +uint32 GetDefaultMapLight(uint32 mapId); + extern DBCStorage sAchievementStore; extern DBCStorage sAchievementCriteriaStore; extern DBCStorage sAreaStore;// recommend access using functions diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index d1db4fb634d..8efc32cc9b2 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -1230,6 +1230,24 @@ struct LFGDungeonEntry uint32 Entry() const { return ID + (type << 24); } }; +struct LightEntry +{ + uint32 Id; + uint32 MapId; + float X; + float Y; + float Z; + //float FalloffStart; + //float FalloffEnd; + //uint32 SkyAndFog; + //uint32 WaterSettings; + //uint32 SunsetParams; + //uint32 OtherParams; + //uint32 DeathParams; + //uint32 Unknown; + //uint32 Unknown; + //uint32 Unknown; +}; struct LiquidTypeEntry { diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index be4369399d4..a1587dd6087 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -79,6 +79,7 @@ char const ItemRandomPropertiesfmt[] = "nxiiixxssssssssssssssssx"; char const ItemRandomSuffixfmt[] = "nssssssssssssssssxxiiixxiiixx"; char const ItemSetEntryfmt[] = "dssssssssssssssssxiiiiiiiiiixxxxxxxiiiiiiiiiiiiiiiiii"; char const LFGDungeonEntryfmt[] = "nssssssssssssssssxiiiiiiiiixxixixxxxxxxxxxxxxxxxx"; +char const LightEntryfmt[] = "nifffxxxxxxxxxx"; char const LiquidTypefmt[] = "nxxixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; char const LockEntryfmt[] = "niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx"; char const MailTemplateEntryfmt[] = "nxxxxxxxxxxxxxxxxxssssssssssssssssx"; diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 9c8f4977b78..9a26f0ae0e4 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -223,7 +223,7 @@ m_unloadTimer(0), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), m_VisibilityNotifyPeriod(DEFAULT_VISIBILITY_NOTIFY_PERIOD), m_activeNonPlayersIter(m_activeNonPlayers.end()), _transportsUpdateIter(_transports.end()), i_gridExpiry(expiry), -i_scriptLock(false) +i_scriptLock(false), _defaultLight(GetDefaultMapLight(id)) { m_parentMap = (_parent ? _parent : this); for (unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx) @@ -477,6 +477,7 @@ bool Map::AddPlayerToMap(Player* player) SendInitSelf(player); SendInitTransports(player); + SendZoneDynamicInfo(player); player->m_clientGUIDs.clear(); player->UpdateObjectVisibility(false); @@ -3433,3 +3434,103 @@ time_t Map::GetLinkedRespawnTime(uint64 guid) const return time_t(0); } +void Map::SendZoneDynamicInfo(Player* player) +{ + uint32 zoneId = GetZoneId(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); + ZoneDynamicInfoMap::const_iterator itr = _zoneDynamicInfo.find(zoneId); + if (itr == _zoneDynamicInfo.end()) + return; + + if (uint32 music = itr->second.MusicId) + { + WorldPacket data(SMSG_PLAY_MUSIC, 4); + data << uint32(music); + player->SendDirectMessage(&data); + } + + if (uint32 weather = itr->second.WeatherId) + { + WorldPacket data(SMSG_WEATHER, 4 + 4 + 1); + data << uint32(weather); + data << float(itr->second.WeatherGrade); + data << uint8(0); + player->SendDirectMessage(&data); + } + + if (uint32 overrideLight = itr->second.OverrideLightId) + { + WorldPacket data(SMSG_OVERRIDE_LIGHT, 4 + 4 + 1); + data << uint32(_defaultLight); + data << uint32(overrideLight); + data << uint32(itr->second.LightFadeInTime); + player->SendDirectMessage(&data); + } +} + +void Map::SetZoneMusic(uint32 zoneId, uint32 musicId) +{ + if (_zoneDynamicInfo.find(zoneId) == _zoneDynamicInfo.end()) + _zoneDynamicInfo.insert(ZoneDynamicInfoMap::value_type(zoneId, ZoneDynamicInfo())); + + _zoneDynamicInfo[zoneId].MusicId = musicId; + + Map::PlayerList const& players = GetPlayers(); + if (!players.isEmpty()) + { + WorldPacket data(SMSG_PLAY_MUSIC, 4); + data << uint32(musicId); + + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if (Player* player = itr->GetSource()) + if (player->GetZoneId() == zoneId) + player->SendDirectMessage(&data); + } +} + +void Map::SetZoneWeather(uint32 zoneId, uint32 weatherId, float weatherGrade) +{ + if (_zoneDynamicInfo.find(zoneId) == _zoneDynamicInfo.end()) + _zoneDynamicInfo.insert(ZoneDynamicInfoMap::value_type(zoneId, ZoneDynamicInfo())); + + ZoneDynamicInfo& info = _zoneDynamicInfo[zoneId]; + info.WeatherId = weatherId; + info.WeatherGrade = weatherGrade; + Map::PlayerList const& players = GetPlayers(); + + if (!players.isEmpty()) + { + WorldPacket data(SMSG_WEATHER, 4 + 4 + 1); + data << uint32(weatherId); + data << float(weatherGrade); + data << uint8(0); + + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if (Player* player = itr->GetSource()) + if (player->GetZoneId() == zoneId) + player->SendDirectMessage(&data); + } +} + +void Map::SetZoneOverrideLight(uint32 zoneId, uint32 lightId, uint32 fadeInTime) +{ + if (_zoneDynamicInfo.find(zoneId) == _zoneDynamicInfo.end()) + _zoneDynamicInfo.insert(ZoneDynamicInfoMap::value_type(zoneId, ZoneDynamicInfo())); + + ZoneDynamicInfo& info = _zoneDynamicInfo[zoneId]; + info.OverrideLightId = lightId; + info.LightFadeInTime = fadeInTime; + Map::PlayerList const& players = GetPlayers(); + + if (!players.isEmpty()) + { + WorldPacket data(SMSG_OVERRIDE_LIGHT, 4 + 4 + 1); + data << uint32(_defaultLight); + data << uint32(lightId); + data << uint32(fadeInTime); + + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if (Player* player = itr->GetSource()) + if (player->GetZoneId() == zoneId) + player->SendDirectMessage(&data); + } +} diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 3d376d16c3d..4daeebe43d1 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -229,6 +229,18 @@ enum LevelRequirementVsMode LEVELREQUIREMENT_HEROIC = 70 }; +struct ZoneDynamicInfo +{ + ZoneDynamicInfo() : MusicId(0), WeatherId(0), WeatherGrade(0.0f), + OverrideLightId(0), LightFadeInTime(0) { } + + uint32 MusicId; + uint32 WeatherId; + float WeatherGrade; + uint32 OverrideLightId; + uint32 LightFadeInTime; +}; + #if defined(__GNUC__) #pragma pack() #else @@ -243,6 +255,8 @@ enum LevelRequirementVsMode typedef std::map CreatureGroupHolderType; +typedef UNORDERED_MAP ZoneDynamicInfoMap; + class Map : public GridRefManager { friend class MapReference; @@ -490,6 +504,11 @@ class Map : public GridRefManager void SendInitTransports(Player* player); void SendRemoveTransports(Player* player); + void SendZoneDynamicInfo(Player* player); + + void SetZoneMusic(uint32 zoneId, uint32 musicId); + void SetZoneWeather(uint32 zoneId, uint32 weatherId, float weatherGrade); + void SetZoneOverrideLight(uint32 zoneId, uint32 lightId, uint32 fadeInTime); private: void LoadMapAndVMap(int gx, int gy); @@ -634,6 +653,9 @@ class Map : public GridRefManager UNORDERED_MAP _creatureRespawnTimes; UNORDERED_MAP _goRespawnTimes; + + ZoneDynamicInfoMap _zoneDynamicInfo; + uint32 _defaultLight; }; enum InstanceResetMethod diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp index 30d520ce7bf..b76e217fbf5 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -560,7 +560,7 @@ class boss_the_lich_king : public CreatureScript me->VisitNearbyGridObject(333.0f, worker); // Reset any light override - SendLightOverride(0, 5000); + me->GetMap()->SetZoneOverrideLight(AREA_THE_FROZEN_THRONE, 0, 5000); } bool CanAIAttack(Unit const* target) const OVERRIDE @@ -593,7 +593,7 @@ class boss_the_lich_king : public CreatureScript case ACTION_START_ENCOUNTER: instance->SetBossState(DATA_THE_LICH_KING, IN_PROGRESS); Talk(SAY_LK_INTRO_1); - SendMusicToPlayers(MUSIC_FROZEN_THRONE); + me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_FROZEN_THRONE); // schedule talks me->SetStandState(UNIT_STAND_STATE_STAND); events.ScheduleEvent(EVENT_INTRO_MOVE_1, 4000); @@ -602,10 +602,10 @@ class boss_the_lich_king : public CreatureScript events.ScheduleEvent(EVENT_START_ATTACK, 5000); break; case ACTION_PLAY_MUSIC: - SendMusicToPlayers(MUSIC_FINAL); + me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_FINAL); break; case ACTION_RESTORE_LIGHT: - SendLightOverride(0, 5000); + me->GetMap()->SetZoneOverrideLight(AREA_THE_FROZEN_THRONE, 0, 5000); break; case ACTION_BREAK_FROSTMOURNE: me->CastSpell((Unit*)NULL, SPELL_SUMMON_BROKEN_FROSTMOURNE, TRIGGERED_IGNORE_CAST_IN_PROGRESS); @@ -687,7 +687,7 @@ class boss_the_lich_king : public CreatureScript events.Reset(); events.SetPhase(PHASE_OUTRO); summons.DespawnAll(); - SendMusicToPlayers(MUSIC_FURY_OF_FROSTMOURNE); + me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_FURY_OF_FROSTMOURNE); me->InterruptNonMeleeSpells(true); me->CastSpell((Unit*)NULL, SPELL_FURY_OF_FROSTMOURNE, TRIGGERED_NONE); me->SetWalk(true); @@ -739,8 +739,8 @@ class boss_the_lich_king : public CreatureScript { summon->CastSpell((Unit*)NULL, SPELL_BROKEN_FROSTMOURNE, true); - SendLightOverride(LIGHT_SOULSTORM, 10000); - SendWeather(WEATHER_STATE_BLACKSNOW); + me->GetMap()->SetZoneOverrideLight(AREA_THE_FROZEN_THRONE, LIGHT_SOULSTORM, 10000); + me->GetMap()->SetZoneWeather(AREA_THE_FROZEN_THRONE, WEATHER_STATE_BLACKSNOW, 0.5f); events.ScheduleEvent(EVENT_OUTRO_SOUL_BARRAGE, 5000, 0, PHASE_OUTRO); return; @@ -792,8 +792,8 @@ class boss_the_lich_king : public CreatureScript { if (spell->Id == REMORSELESS_WINTER_1 || spell->Id == REMORSELESS_WINTER_2) { - SendLightOverride(LIGHT_SNOWSTORM, 5000); - SendWeather(WEATHER_STATE_LIGHT_SNOW); + me->GetMap()->SetZoneOverrideLight(AREA_THE_FROZEN_THRONE, LIGHT_SNOWSTORM, 5000); + me->GetMap()->SetZoneWeather(AREA_THE_FROZEN_THRONE, WEATHER_STATE_LIGHT_SNOW, 0.5f); } } @@ -819,7 +819,7 @@ class boss_the_lich_king : public CreatureScript case POINT_CENTER_1: me->SetFacingTo(0.0f); Talk(SAY_LK_REMORSELESS_WINTER); - SendMusicToPlayers(MUSIC_SPECIAL); + me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL); DoCast(me, SPELL_REMORSELESS_WINTER_1); events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions events.ScheduleEvent(EVENT_QUAKE, 62500, 0, PHASE_TRANSITION); @@ -834,7 +834,7 @@ class boss_the_lich_king : public CreatureScript case POINT_CENTER_2: me->SetFacingTo(0.0f); Talk(SAY_LK_REMORSELESS_WINTER); - SendMusicToPlayers(MUSIC_SPECIAL); + me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL); DoCast(me, SPELL_REMORSELESS_WINTER_2); summons.DespawnEntry(NPC_VALKYR_SHADOWGUARD); events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions @@ -920,7 +920,7 @@ class boss_the_lich_king : public CreatureScript break; case EVENT_SUMMON_SHAMBLING_HORROR: DoCast(me, SPELL_SUMMON_SHAMBLING_HORROR); - SendMusicToPlayers(MUSIC_SPECIAL); + me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL); events.ScheduleEvent(EVENT_SUMMON_SHAMBLING_HORROR, 60000, 0, PHASE_ONE); break; case EVENT_SUMMON_DRUDGE_GHOUL: @@ -980,18 +980,18 @@ class boss_the_lich_king : public CreatureScript events.SetPhase(PHASE_TWO); me->ClearUnitState(UNIT_STATE_CASTING); // clear state to ensure check in DoCastAOE passes DoCastAOE(SPELL_QUAKE); - SendMusicToPlayers(MUSIC_SPECIAL); + me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL); Talk(SAY_LK_QUAKE); break; case EVENT_QUAKE_2: events.SetPhase(PHASE_THREE); me->ClearUnitState(UNIT_STATE_CASTING); // clear state to ensure check in DoCastAOE passes DoCastAOE(SPELL_QUAKE); - SendMusicToPlayers(MUSIC_SPECIAL); + me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL); Talk(SAY_LK_QUAKE); break; case EVENT_SUMMON_VALKYR: - SendMusicToPlayers(MUSIC_SPECIAL); + me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL); Talk(SAY_LK_SUMMON_VALKYR); DoCastAOE(SUMMON_VALKYR); events.ScheduleEvent(EVENT_SUMMON_VALKYR, urand(45000, 50000), 0, PHASE_TWO); @@ -1002,7 +1002,7 @@ class boss_the_lich_king : public CreatureScript events.SetPhase(PHASE_THREE); break; case EVENT_VILE_SPIRITS: - SendMusicToPlayers(MUSIC_SPECIAL); + me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL); DoCastAOE(SPELL_VILE_SPIRITS); events.ScheduleEvent(EVENT_VILE_SPIRITS, urand(35000, 40000), EVENT_GROUP_VILE_SPIRITS, PHASE_THREE); break; @@ -1073,7 +1073,7 @@ class boss_the_lich_king : public CreatureScript case EVENT_OUTRO_RAISE_DEAD: DoCastAOE(SPELL_RAISE_DEAD); me->ClearUnitState(UNIT_STATE_CASTING); - SendMusicToPlayers(MUSIC_FINAL); + me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_FINAL); break; case EVENT_OUTRO_TALK_5: Talk(SAY_LK_OUTRO_5); @@ -1114,42 +1114,6 @@ class boss_the_lich_king : public CreatureScript } private: - void SendMusicToPlayers(uint32 musicId) const - { - WorldPacket data(SMSG_PLAY_MUSIC, 4); - data << uint32(musicId); - SendPacketToPlayers(&data); - } - - void SendLightOverride(uint32 overrideId, uint32 fadeInTime) const - { - WorldPacket data(SMSG_OVERRIDE_LIGHT, 12); - data << uint32(2488); // Light.dbc entry (map default) - data << uint32(overrideId); // Light.dbc entry (override) - data << uint32(fadeInTime); - SendPacketToPlayers(&data); - } - - void SendWeather(WeatherState weather) const - { - WorldPacket data(SMSG_WEATHER, 9); - data << uint32(weather); - data << float(0.5f); - data << uint8(0); - SendPacketToPlayers(&data); - } - - // Send packet to all players in The Frozen Throne - void SendPacketToPlayers(WorldPacket const* data) const - { - Map::PlayerList const& players = me->GetMap()->GetPlayers(); - if (!players.isEmpty()) - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - if (Player* player = itr->GetSource()) - if (player->GetAreaId() == AREA_THE_FROZEN_THRONE) - player->GetSession()->SendPacket(data); - } - uint32 _necroticPlagueStack; uint32 _vileSpiritExplosions; }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h index 8e529ba0ee9..56a8a46811c 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h @@ -68,7 +68,7 @@ enum TeleporterSpells DEATHBRINGER_S_RISE_TELEPORT = 70858, UPPER_SPIRE_TELEPORT = 70859, FROZEN_THRONE_TELEPORT = 70860, - SINDRAGOSA_S_LAIR_TELEPORT = 70861, + SINDRAGOSA_S_LAIR_TELEPORT = 70861 }; enum DataTypes @@ -285,7 +285,7 @@ enum CreaturesIds NPC_FROSTMOURNE_TRIGGER = 38584, // Generic - NPC_INVISIBLE_STALKER = 30298, + NPC_INVISIBLE_STALKER = 30298 }; enum GameObjectsIds @@ -368,7 +368,7 @@ enum GameObjectsIds GO_DOODAD_ICECROWN_SNOWEDGEWARNING01 = 202190, GO_FROZEN_LAVAMAN = 202436, GO_LAVAMAN_PILLARS_CHAINED = 202437, - GO_LAVAMAN_PILLARS_UNCHAINED = 202438, + GO_LAVAMAN_PILLARS_UNCHAINED = 202438 }; enum AchievementCriteriaIds @@ -403,7 +403,7 @@ enum AchievementCriteriaIds CRITERIA_ONCE_BITTEN_TWICE_SHY_10N = 12780, CRITERIA_ONCE_BITTEN_TWICE_SHY_25N = 13012, CRITERIA_ONCE_BITTEN_TWICE_SHY_10V = 13011, - CRITERIA_ONCE_BITTEN_TWICE_SHY_25V = 13013, + CRITERIA_ONCE_BITTEN_TWICE_SHY_25V = 13013 }; enum SharedActions @@ -431,7 +431,7 @@ enum SharedActions // The Lich King ACTION_RESTORE_LIGHT = -72262, - ACTION_FROSTMOURNE_INTRO = -36823, + ACTION_FROSTMOURNE_INTRO = -36823 }; enum WeekliesICC @@ -445,7 +445,7 @@ enum WeekliesICC QUEST_BLOOD_QUICKENING_10 = 24874, QUEST_BLOOD_QUICKENING_25 = 24879, QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_10 = 24872, - QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_25 = 24880, + QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_25 = 24880 }; enum WorldStatesICC @@ -454,12 +454,12 @@ enum WorldStatesICC WORLDSTATE_EXECUTION_TIME = 4904, WORLDSTATE_SHOW_ATTEMPTS = 4940, WORLDSTATE_ATTEMPTS_REMAINING = 4941, - WORLDSTATE_ATTEMPTS_MAX = 4942, + WORLDSTATE_ATTEMPTS_MAX = 4942 }; enum AreaIds { - AREA_THE_FROZEN_THRONE = 4859, + AREA_THE_FROZEN_THRONE = 4859 }; class spell_trigger_spell_from_caster : public SpellScriptLoader diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index edd80377d68..e2234fa5a20 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -31,7 +31,7 @@ enum EventIds { EVENT_QUAKE = 23437, EVENT_SECOND_REMORSELESS_WINTER = 23507, - EVENT_TELEPORT_TO_FROSMOURNE = 23617, + EVENT_TELEPORT_TO_FROSTMOURNE = 23617 }; enum TimedEvents @@ -68,7 +68,7 @@ DoorData const doorData[] = {GO_SINDRAGOSA_SHORTCUT_EXIT_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, {GO_ICE_WALL, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_SE }, {GO_ICE_WALL, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_SW }, - {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE}, // END + {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE} // END }; // this doesnt have to only store questgivers, also can be used for related quest spawns @@ -89,7 +89,7 @@ WeeklyQuest const WeeklyQuestData[WeeklyNPCs] = {NPC_ALRIN_THE_AGILE, {QUEST_BLOOD_QUICKENING_10, QUEST_BLOOD_QUICKENING_25 }}, // Blood Quickening {NPC_INFILTRATOR_MINCHAR_BQ, {QUEST_BLOOD_QUICKENING_10, QUEST_BLOOD_QUICKENING_25 }}, // Blood Quickening {NPC_MINCHAR_BEAM_STALKER, {QUEST_BLOOD_QUICKENING_10, QUEST_BLOOD_QUICKENING_25 }}, // Blood Quickening - {NPC_VALITHRIA_DREAMWALKER_QUEST, {QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_10, QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_25}}, // Respite for a Tormented Soul + {NPC_VALITHRIA_DREAMWALKER_QUEST, {QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_10, QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_25}} // Respite for a Tormented Soul }; class instance_icecrown_citadel : public InstanceMapScript @@ -335,7 +335,7 @@ class instance_icecrown_citadel : public InstanceMapScript { uint8 diffIndex = uint8(instance->GetSpawnMode() & 1); if (!sPoolMgr->IsSpawnedObject(WeeklyQuestData[questIndex].questId[diffIndex])) - entry = 0; + return 0; break; } } @@ -1235,7 +1235,7 @@ class instance_icecrown_citadel : public InstanceMapScript Events.ScheduleEvent(EVENT_REBUILD_PLATFORM, 1500); } break; - case EVENT_TELEPORT_TO_FROSMOURNE: // Harvest Soul (normal mode) + case EVENT_TELEPORT_TO_FROSTMOURNE: // Harvest Soul (normal mode) if (Creature* terenas = instance->SummonCreature(NPC_TERENAS_MENETHIL_FROSTMOURNE, TerenasSpawn, NULL, 63000)) { terenas->AI()->DoAction(ACTION_FROSTMOURNE_INTRO); diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 7ae9ce3faa6..1df92618a3a 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -584,7 +584,7 @@ public: { instance->SetBossState(DATA_MALYGOS_EVENT, FAIL); - SendLightOverride(LIGHT_GET_DEFAULT_FOR_MAP, 1*IN_MILLISECONDS); + me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_GET_DEFAULT_FOR_MAP, 1*IN_MILLISECONDS); if (_phase == PHASE_THREE) me->SetControlled(false, UNIT_STATE_ROOT); @@ -725,8 +725,8 @@ public: me->SetDisableGravity(true); if (Creature* alexstraszaBunny = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID))) me->SetFacingToObject(alexstraszaBunny); - SendLightOverride(LIGHT_ARCANE_RUNES, 5*IN_MILLISECONDS); - events.ScheduleEvent(EVENT_FLY_OUT_OF_PLATFORM, 18*IN_MILLISECONDS, 0, PHASE_TWO); + me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_ARCANE_RUNES, 5 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_FLY_OUT_OF_PLATFORM, 18 * IN_MILLISECONDS, 0, PHASE_TWO); break; case POINT_SURGE_OF_POWER_P_TWO: if (!_performingDestroyPlatform) @@ -737,7 +737,7 @@ public: } break; case POINT_DESTROY_PLATFORM_P_TWO: - SendLightOverride(LIGHT_OBSCURE_SPACE, 1*IN_MILLISECONDS); + me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_OBSCURE_SPACE, 1 * IN_MILLISECONDS); DoCast(me, SPELL_DESTROY_PLATFORM_CHANNEL); events.ScheduleEvent(EVENT_MOVE_TO_P_THREE_POINT, 11*IN_MILLISECONDS, 0, PHASE_TWO); break; @@ -929,7 +929,7 @@ public: } break; case EVENT_LIGHT_DIMENSION_CHANGE: - SendLightOverride(LIGHT_CHANGE_DIMENSIONS, 2*IN_MILLISECONDS); + me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_CHANGE_DIMENSIONS, 2 * IN_MILLISECONDS); break; case EVENT_DELAY_MOVE_TO_DESTROY_P: me->GetMotionMaster()->MovePoint(POINT_DESTROY_PLATFORM_P_TWO, MalygosPositions[0]); @@ -939,7 +939,7 @@ public: me->GetMotionMaster()->MovePoint(POINT_IDLE_P_THREE, MalygosPositions[4]); break; case EVENT_START_P_THREE: - SendLightOverride(LIGHT_OBSCURE_ARCANE_RUNES, 1*IN_MILLISECONDS); + me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_OBSCURE_ARCANE_RUNES, 1 * IN_MILLISECONDS); DoCast(me, SPELL_CLEAR_ALL_DEBUFFS); DoCast(me, SPELL_IMMUNE_CURSES); _canAttack = true; @@ -1026,27 +1026,6 @@ public: } } - // Function that will change lights of map for all players on map. - void SendLightOverride(uint32 overrideId, uint32 fadeInTime) const - { - WorldPacket data(SMSG_OVERRIDE_LIGHT, 12); - data << uint32(1773); // Light.dbc entry (map default) - data << uint32(overrideId); // Light.dbc entry (override) - data << uint32(fadeInTime); - SendPacketToPlayers(&data); - } - - // Send packet to all players in Eye of Eternity - void SendPacketToPlayers(WorldPacket const* data) const - { - Map::PlayerList const& players = me->GetMap()->GetPlayers(); - if (!players.isEmpty()) - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - if (Player* player = itr->GetSource()) - if (player->GetAreaId() == AREA_EYE_OF_ETERNITY) - player->GetSession()->SendPacket(data); - } - uint8 _phase; // Counter for phases used with a getter. uint8 _summonDeaths; // Keeps count of arcane trash. uint8 _preparingPulsesChecker; // In retail they use 2 preparing pulses with 7 sec CD, after they pass 2 seconds. -- cgit v1.2.3 From a4d8a26dc7eb8139190eae1e285dc629da50b950 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 23 Mar 2014 02:01:13 +0100 Subject: Scripts/Icecrown Citadel: Icecrown Gunship Battle --- sql/updates/world/2014_03_23_00_world_misc.sql | 397 ++++ src/server/game/Entities/Transport/Transport.cpp | 124 + src/server/game/Entities/Transport/Transport.h | 18 + src/server/game/Scripting/ScriptLoader.cpp | 2 + src/server/game/Spells/SpellMgr.cpp | 9 + src/server/scripts/Northrend/CMakeLists.txt | 1 + .../boss_icecrown_gunship_battle.cpp | 2389 ++++++++++++++++++++ .../IcecrownCitadel/boss_the_lich_king.cpp | 33 - .../Northrend/IcecrownCitadel/icecrown_citadel.h | 50 +- .../IcecrownCitadel/icecrown_citadel_teleport.cpp | 2 +- .../IcecrownCitadel/instance_icecrown_citadel.cpp | 154 +- src/server/scripts/Northrend/zone_storm_peaks.cpp | 32 - src/server/scripts/Spells/spell_generic.cpp | 29 + 13 files changed, 3162 insertions(+), 78 deletions(-) create mode 100644 sql/updates/world/2014_03_23_00_world_misc.sql create mode 100644 src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp (limited to 'src/server/scripts/Northrend') diff --git a/sql/updates/world/2014_03_23_00_world_misc.sql b/sql/updates/world/2014_03_23_00_world_misc.sql new file mode 100644 index 00000000000..b57f6e09bb9 --- /dev/null +++ b/sql/updates/world/2014_03_23_00_world_misc.sql @@ -0,0 +1,397 @@ +UPDATE `creature_template` SET `ScriptName`='npc_gunship' WHERE `entry`=37215; -- Orgrim's Hammer +UPDATE `creature_template` SET `ScriptName`='npc_gunship' WHERE `entry`=37540; -- The Skybreaker +UPDATE `creature_template` SET `ScriptName`='npc_high_overlord_saurfang_igb' WHERE `entry`=36939; -- High Overlord Saurfang +UPDATE `creature_template` SET `ScriptName`='npc_muradin_bronzebeard_igb' WHERE `entry`=36948; -- Muradin Bronzebeard +UPDATE `creature_template` SET `ScriptName`='npc_zafod_boombox' WHERE `entry`=37184; -- Zafod Boombox +UPDATE `creature_template` SET `ScriptName`='npc_gunship_boarding_leader' WHERE `entry` IN (36961,36960); -- Skybreaker Sergeant, Kor'kron Sergeant +UPDATE `creature_template` SET `ScriptName`='npc_gunship_boarding_add' WHERE `entry` IN (36950,36957); -- Skybreaker Marine, Kor'kron Reaver +UPDATE `creature_template` SET `ScriptName`='npc_gunship_gunner' WHERE `entry` IN (36969,36968); -- Skybreaker Rifleman, Kor'kron Axethrower +UPDATE `creature_template` SET `ScriptName`='npc_gunship_rocketeer' WHERE `entry` IN (36978,36982); -- Skybreaker Mortar Soldier, Kor'kron Rocketeer +UPDATE `creature_template` SET `ScriptName`='npc_gunship_mage' WHERE `entry` IN (37116,37117); -- Skybreaker Sorcerer, Kor'kron Battle-Mage +UPDATE `creature_template` SET `ScriptName`='npc_gunship_cannon' WHERE `entry` IN (36838,36839); -- Alliance Gunship Cannon, Horde Gunship Cannon + +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_jokkum_eject_all'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_the_lich_king_eject_all_passengers'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_gen_eject_all_passengers'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_rocket_pack'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_rocket_pack_useable'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_on_gunship_deck'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_periodic_trigger_with_power_cost'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_cannon_blast'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_incinerating_blast'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_overheat'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_below_zero'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_teleport_to_enemy_ship'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_burning_pitch_selector'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_burning_pitch'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_rocket_artillery'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_rocket_artillery_explosion'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_gunship_fall_teleport'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_check_for_players'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_teleport_players_on_victory'; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(50630,'spell_gen_eject_all_passengers'), +(63109,'spell_gen_eject_all_passengers'), +(68576,'spell_gen_eject_all_passengers'), +(68721,'spell_igb_rocket_pack'), +(70348,'spell_igb_rocket_pack_useable'), +(70120,'spell_igb_on_gunship_deck'), +(70121,'spell_igb_on_gunship_deck'), +(69470,'spell_igb_periodic_trigger_with_power_cost'), +(69487,'spell_igb_periodic_trigger_with_power_cost'), +(69399,'spell_igb_cannon_blast'), +(70172,'spell_igb_cannon_blast'), +(69402,'spell_igb_incinerating_blast'), +(70175,'spell_igb_incinerating_blast'), +(69487,'spell_igb_overheat'), +(69705,'spell_igb_below_zero'), +(70104,'spell_igb_teleport_to_enemy_ship'), +(70397,'spell_igb_burning_pitch_selector'), +(70403,'spell_igb_burning_pitch_selector'), +(71335,'spell_igb_burning_pitch'), +(71339,'spell_igb_burning_pitch'), +(69678,'spell_igb_rocket_artillery'), +(70609,'spell_igb_rocket_artillery'), +(69679,'spell_igb_rocket_artillery_explosion'), +(67335,'spell_igb_gunship_fall_teleport'), +(70331,'spell_igb_check_for_players'), +(72340,'spell_igb_teleport_players_on_victory'); + +UPDATE `creature_template` SET `difficulty_entry_1`=0,`difficulty_entry_2`=0,`difficulty_entry_3`=0 WHERE `entry`=36838; -- Alliance Gunship Cannon +UPDATE `creature_template` SET `difficulty_entry_1`=0,`difficulty_entry_2`=0,`difficulty_entry_3`=0 WHERE `entry`=36839; -- Horde Gunship Cannon +UPDATE `creature_template` SET `difficulty_entry_1`=0,`difficulty_entry_2`=0,`difficulty_entry_3`=0 WHERE `entry`=36970; -- Skybreaker Deckhand +UPDATE `creature_template` SET `difficulty_entry_1`=0,`difficulty_entry_2`=0,`difficulty_entry_3`=0 WHERE `entry`=36971; -- Orgrim's Hammer Crew +UPDATE `creature_template` SET `difficulty_entry_1`=38157,`difficulty_entry_2`=38639,`difficulty_entry_3`=38640 WHERE `entry`=36948; -- Muradin Bronzebeard +UPDATE `creature_template` SET `difficulty_entry_1`=38156,`difficulty_entry_2`=38637,`difficulty_entry_3`=38638 WHERE `entry`=36939; -- High Overlord Saurfang +UPDATE `creature_template` SET `difficulty_entry_1`=38128,`difficulty_entry_2`=38699,`difficulty_entry_3`=38700 WHERE `entry`=37540; -- The Skybreaker +UPDATE `creature_template` SET `difficulty_entry_1`=38129,`difficulty_entry_2`=38701,`difficulty_entry_3`=38702 WHERE `entry`=37215; -- Orgrim's Hammer +UPDATE `creature_template` SET `difficulty_entry_1`=38256,`difficulty_entry_2`=38693,`difficulty_entry_3`=38694 WHERE `entry`=37116; -- Skybreaker Sorcerer +UPDATE `creature_template` SET `difficulty_entry_1`=38408,`difficulty_entry_2`=38689,`difficulty_entry_3`=38690 WHERE `entry`=36969; -- Skybreaker Rifleman +UPDATE `creature_template` SET `difficulty_entry_1`=38407,`difficulty_entry_2`=38687,`difficulty_entry_3`=38688 WHERE `entry`=36978; -- Skybreaker Mortar Soldier +UPDATE `creature_template` SET `difficulty_entry_1`=38406,`difficulty_entry_2`=38685,`difficulty_entry_3`=38686 WHERE `entry`=36950; -- Skybreaker Marine +UPDATE `creature_template` SET `difficulty_entry_1`=38261,`difficulty_entry_2`=38691,`difficulty_entry_3`=38692 WHERE `entry`=36961; -- Skybreaker Sergeant +UPDATE `creature_template` SET `difficulty_entry_1`=38257,`difficulty_entry_2`=38677,`difficulty_entry_3`=38678 WHERE `entry`=37117; -- Kor'kron Battle-Mage +UPDATE `creature_template` SET `difficulty_entry_1`=38403,`difficulty_entry_2`=38675,`difficulty_entry_3`=38676 WHERE `entry`=36968; -- Kor'kron Axethrower +UPDATE `creature_template` SET `difficulty_entry_1`=38405,`difficulty_entry_2`=38681,`difficulty_entry_3`=38682 WHERE `entry`=36982; -- Kor'kron Rocketeer +UPDATE `creature_template` SET `difficulty_entry_1`=38404,`difficulty_entry_2`=38679,`difficulty_entry_3`=38680 WHERE `entry`=36957; -- Kor'kron Reaver +UPDATE `creature_template` SET `difficulty_entry_1`=38262,`difficulty_entry_2`=38683,`difficulty_entry_3`=38684 WHERE `entry`=36960; -- Kor'kron Sergeant + +UPDATE `creature_template` SET `spell1`=0,`spell2`=0,`spell3`=0,`spell4`=0,`spell5`=0,`spell6`=0,`spell7`=0,`spell8`=0 WHERE `entry` IN (36838,36839,36970,36971,36948,38157,38639,38640,36939,38156,38638,38637,37540,38128,38699,38700,37215,38129,38701,38702, +37116,38256,38693,38694,36969,38408,38689,38690,36978,38407,38687,38688,36950,38406,38685,38686,36961,38261,38691,38692,37117,38257,38677,38678,36968,38403,38675,38676,36982,38405,38681,38682,36957,38404,38679,38680,36960,38262,38683,38684,37227,37488); + +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=0,`faction_A`=1665,`faction_H`=1665,`npcflag`=0x1000000,`speed_walk`=1,`speed_run`=1,`unit_class`=4,`unit_flags`=0x4000,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`spell1`=69399,`spell2`=70174,`VehicleId`=554,`InhabitType`=1,`mechanic_immune_mask`=650854267 WHERE `entry`=36838; -- Alliance Gunship Cannon +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=0,`faction_A`=1665,`faction_H`=1665,`npcflag`=0x1000000,`speed_walk`=1,`speed_run`=1,`unit_class`=4,`unit_flags`=0x4000,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`spell1`=70172,`spell2`=69401,`VehicleId`=555,`InhabitType`=1,`mechanic_immune_mask`=650854267 WHERE `entry`=36839; -- Horde Gunship Cannon +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=0,`faction_A`=84,`faction_H`=84,`speed_walk`=1,`speed_run`=1.14286,`unit_flags`=0x300,`unit_flags2`=0x800,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`mechanic_immune_mask`=650854267 WHERE `entry`=36970; -- Skybreaker Deckhand +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=0,`faction_A`=83,`faction_H`=83,`speed_walk`=1,`speed_run`=1.14286,`unit_flags`=0x300,`unit_flags2`=0x800,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`mechanic_immune_mask`=650854267 WHERE `entry`=36971; -- Orgrim's Hammer Crew +UPDATE `creature_template` SET `gossip_menu_id`=10875,`minlevel`=83,`maxlevel`=83,`exp`=2,`faction_A`=84,`faction_H`=84,`npcflag`=0x1,`speed_walk`=1,`speed_run`=1.71429,`unit_flags`=0x8000,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=1500,`InhabitType`=1,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36948,38157,38639,38640); -- Muradin Bronzebeard +UPDATE `creature_template` SET `gossip_menu_id`=10954,`minlevel`=83,`maxlevel`=83,`exp`=2,`faction_A`=83,`faction_H`=83,`npcflag`=0x1,`speed_walk`=1,`speed_run`=1.71429,`unit_flags`=0x8000,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=1500,`InhabitType`=1,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36939,38156,38638,38637); -- High Overlord Saurfang +UPDATE `creature_template` SET `minlevel`=83,`maxlevel`=83,`exp`=2,`faction_A`=35,`faction_H`=35,`speed_walk`=1,`speed_run`=1.42857,`unit_flags`=0,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=4,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (37540,38128,38699,38700); -- The Skybreaker +UPDATE `creature_template` SET `minlevel`=83,`maxlevel`=83,`exp`=2,`faction_A`=35,`faction_H`=35,`speed_walk`=1,`speed_run`=1.42857,`unit_flags`=0,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=4,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (37215,38129,38701,38702); -- Orgrim's Hammer +UPDATE `creature_template` SET `minlevel`=81,`maxlevel`=81,`exp`=0,`faction_A`=35,`faction_H`=35,`npcflag`=0x1000000,`speed_walk`=1,`speed_run`=1,`unit_class`=1,`unit_flags`=0,`unit_flags2`=0x800,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry`=37227; -- Teleport Portal +UPDATE `creature_template` SET `minlevel`=81,`maxlevel`=81,`exp`=0,`faction_A`=35,`faction_H`=35,`npcflag`=0,`speed_walk`=1,`speed_run`=1,`unit_class`=1,`unit_flags`=0x2000000,`unit_flags2`=0x800,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry`=37488; -- Teleport Exit +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=84,`faction_H`=84,`speed_walk`=1,`speed_run`=1.71429,`unit_class`=2,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (37116,38256,38693,38694); -- Skybreaker Sorcerer +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=84,`faction_H`=84,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=1,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36969,38408,38689,38690); -- Skybreaker Rifleman +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=84,`faction_H`=84,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=1,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36978,38407,38687,38688); -- Skybreaker Mortar Soldier +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=84,`faction_H`=84,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=1,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36950,38406,38685,38686); -- Skybreaker Marine +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=84,`faction_H`=84,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=1,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36961,38261,38691,38692); -- Skybreaker Sergeant +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=83,`faction_H`=83,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=2,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (37117,38257,38677,38678); -- Kor'kron Battle-Mage +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=83,`faction_H`=83,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=1,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36968,38403,38675,38676); -- Kor'kron Axethrower +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=83,`faction_H`=83,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=1,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36982,38405,38681,38682); -- Kor'kron Rocketeer +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=83,`faction_H`=83,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=1,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36957,38404,38679,38680); -- Kor'kron Reaver +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=83,`faction_H`=83,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=1,`unit_flags`=0x8040,`unit_flags2`=0x800,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36960,38262,38683,38684); -- Kor'kron Sergeant +UPDATE `creature_template` SET `npcflag`=1,`gossip_menu_id`=10885,`mechanic_immune_mask`=650854267 WHERE `entry`=37184; -- Zafod Boombox +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=2,`faction_A`=84,`faction_H`=84,`speed_walk`=1,`speed_run`=1.14286,`unit_class`=1,`unit_flags`=0x300,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry`=37182; -- High Captain Justin Bartlett +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=2,`faction_A`=84,`faction_H`=84,`speed_walk`=1,`speed_run`=1.14286,`unit_class`=1,`unit_flags`=0x300,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry`=37833; -- Sky-Reaver Korm Blackscar + +UPDATE `gameobject_template` SET `faction`=94,`flags`=16 WHERE `entry` IN (202178,202180,202177,202179); -- Gunship Armory +UPDATE `gameobject_template` SET `faction`=94,`flags`=16 WHERE `entry` IN (201873,201874,201872,201875); -- Gunship Armory + +DELETE FROM `creature_text` WHERE `entry`=36939 AND `groupid` BETWEEN 0 AND 13; +DELETE FROM `creature_text` WHERE `entry`=36948 AND `groupid` BETWEEN 0 AND 14; +DELETE FROM `creature_text` WHERE `entry` IN (37184,36838,36839); +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES +(36939, 0,0,'Rise up, sons and daughters of the Horde! Today we battle a hated enemy of the Horde! LOK''TAR OGAR!',14,0,100,0,0,17087,'High Overlord Saurfang - SAY_SAURFANG_INTRO_1'), +(36939, 1,0,'Kor''kron, take us out!',14,0,100,0,0,17088,'High Overlord Saurfang - SAY_SAURFANG_INTRO_2'), +(36939, 2,0,'What is that? Something approaching in the distance.',14,0,100,0,0,17089,'High Overlord Saurfang - SAY_SAURFANG_INTRO_3'), +(36939, 3,0,'ALLIANCE GUNSHIP! ALL HANDS ON DECK!',14,0,100,0,0,17090,'High Overlord Saurfang - SAY_SAURFANG_INTRO_4'), +(36939, 4,0,'You answer to Saurfang now!',14,0,100,0,0,17091,'High Overlord Saurfang - SAY_SAURFANG_INTRO_5'), +(36939, 5,0,'You will know our business soon. Kor''kron, ANNIHILATE THEM!',14,0,100,0,0,17092,'High Overlord Saurfang - SAY_SAURFANG_INTRO_6'), +(36939, 6,0,'This is not your battle, dwarf. Back down or we will be forced to destroy your ship.',14,0,100,0,0,17083,'High Overlord Saurfang - SAY_SAURFANG_INTRO_A'), +(36939, 7,0,'You DARE board my ship? Your death will come swiftly.',14,0,100,0,0,17083,'High Overlord Saurfang - SAY_SAURFANG_BOARD'), +(36939, 8,0,'Reavers, Sergeants, attack!',14,0,100,0,0,17081,'High Overlord Saurfang - SAY_SAURFANG_ENTER_SKYBREAKER'), +(36939, 9,0,'Axethrowers, hurl faster!',14,0,100,0,0,17079,'High Overlord Saurfang - SAY_SAURFANG_AXETHROWERS'), +(36939,10,0,'Rocketeers, reload!',14,0,100,0,0,17080,'High Overlord Saurfang - SAY_SAURFANG_ROCKETEERS'), +(36939,11,0,'We''re taking hull damage, get a battle-mage out here to shut down those cannons!',14,0,100,0,0,17082,'High Overlord Saurfang - SAY_SAURFANG_MAGES'), +(36939,12,0,'The Alliance falter. Onward to the Lich King!',14,0,100,0,0,17084,'High Overlord Saurfang - SAY_SAURFANG_VICTORY'), +(36939,13,0,'Damage control! Put those fires out. You haven''t seen the last of the Horde!',14,0,100,0,0,17085,'High Overlord Saurfang - SAY_SAURFANG_WIPE'), +(36948, 0,0,'Fire up the engines! We got a meetin'' with destiny, lads!',14,0,100,0,0,16962,'Muradin Bronzebeard - SAY_MURADIN_INTRO_1'), +(36948, 1,0,'Hold on to yer hats!',14,0,100,0,0,16963,'Muradin Bronzebeard - SAY_MURADIN_INTRO_2'), +(36948, 2,0,'What in the world is that? Grab me spyglass, crewman!',14,0,100,0,0,16964,'Muradin Bronzebeard - SAY_MURADIN_INTRO_3'), +(36948, 3,0,'By me own beard! HORDE SAILIN'' IN FAST ''N HOT!',14,0,100,0,0,16965,'Muradin Bronzebeard - SAY_MURADIN_INTRO_4'), +(36948, 4,0,'EVASIVE ACTION! MAN THE GUNS!',14,0,100,0,0,16966,'Muradin Bronzebeard - SAY_MURADIN_INTRO_5'), +(36948, 5,0,'Cowardly dogs! Ye blindsided us!',14,0,100,0,0,16967,'Muradin Bronzebeard - SAY_MURADIN_INTRO_6'), +(36948, 6,0,'Not me battle? I dunnae who ye think ye are, mister, but I got a score to settle with Arthas and yer not gettin'' in me way! FIRE ALL GUNS! FIRE! FIRE!',14,0,100,0,0,16968,'Muradin Bronzebeard - SAY_MURADIN_INTRO_7'), +(36948, 7,0,'Move yer jalopy or we''ll blow it out of the sky, orc! The Horde''s got no business here.',14,0,100,0,0,16969,'Muradin Bronzebeard - SAY_MURADIN_INTRO_H'), +(36948, 8,0,'What''s this then?! Ye won''t be takin'' this son o'' Ironforge''s vessel without a fight!',14,0,100,0,0,16958,'Muradin Bronzebeard - SAY_MURADIN_BOARD'), +(36948, 9,0,'Marines, Sergeants, attack!',14,0,100,0,0,16956,'Muradin Bronzebeard - SAY_MURADIN_ENTER_ORGRIMMS_HAMMER'), +(36948,10,0,'Riflemen, shoot faster!',14,0,100,0,0,16954,'Muradin Bronzebeard - SAY_MURADIN_RIFLEMAN'), +(36948,11,0,'Mortar team, reload!',14,0,100,0,0,16955,'Muradin Bronzebeard - SAY_MURADIN_MORTAR'), +(36948,12,0,'We''re taking hull damage, get a sorcerer out here to shut down those cannons!',14,0,100,0,0,16957,'Muradin Bronzebeard - SAY_MURADIN_SORCERERS'), +(36948,13,0,'Don''t say I didn''t warn ya, scoundrels! Onward, brothers and sisters!',14,0,100,0,0,16959,'Muradin Bronzebeard - SAY_MURADIN_VICTORY'), +(36948,14,0,'Captain Bartlett, get us out of here! We''re taken too much damage to stay afloat!',14,0,100,0,0,16960,'Muradin Bronzebeard - SAY_MURADIN_WIPE'), +(37184,0,0,'Rocket Pack Active!',15,0,100,0,0,0,'Zafod Boombox - SAY_ZAFOD_ROCKET_PACK_ACTIVE'), +(37184,1,0,'Rocket Pack Disabled. Move closer to Zafod Boombox to re-activate.',15,0,100,0,0,0,'Zafod Boombox - SAY_ZAFOD_ROCKET_PACK_DISABLED'), +(36838,0,0,'|TInterface\\Icons\\Spell_Fire_Flameshock.blp:20|t|cFFBC0000 OVERHEAT |r|TInterface\\Icons\\Spell_Fire_Flameshock.blp:20|t',42,0,100,0,0,0,'Alliance Gunship Cannon - SAY_OVERHEAT'), +(36839,0,0,'|TInterface\\Icons\\Spell_Fire_Flameshock.blp:20|t|cFFBC0000 OVERHEAT |r|TInterface\\Icons\\Spell_Fire_Flameshock.blp:20|t',42,0,100,0,0,0,'Horde Gunship Cannon - SAY_OVERHEAT'); + +DELETE FROM `gossip_menu` WHERE `entry` IN (10875,10954,10885); +INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES +(10875,15101), +(10954,15219), +(10885,15134), +(10885,15123); + +DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (10875,10885,10954); +INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`) VALUES +(10875,0,0,'My companions are all accounted for, Muradin. Let''s go!',1,1,0,0,0,0,''), +(10954,0,0,'My companions are all accounted for, Saurfang. Let''s go!',1,1,0,0,0,0,''), +(10885,0,0,'Yeah, I''m sure safety is your top priority. Give me a rocket pack.',1,1,0,0,0,0,''); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=10885; +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=14 AND `SourceGroup`=10885; +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (72347,70104,70173,69400,69402,70175,69705,70403,70397,70383,70374,70444,67335); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`Comment`) VALUES +(15,10885,0,0,2,49278,1,0,1,'Gossip Option - Show Option if player does not have item 49278'), +(14,10885,15134,0,2,49278,1,0,1,'Gossip Option - Show text 15134 if player does not have item 49278'), +(14,10885,15123,0,2,49278,1,0,0,'Gossip Option - Show text 15123 if player has item 49278'), +(13,1,72347,0,31,3,38569,0,0,'Lock Players and Tap Chest - target Martyr Stalker (IGB/Saurfang)'), +(13,1,70104,0,31,3,37488,0,0,'Teleport to Enemy Ship - target Teleport Exit'), +(13,2,70173,0,31,3,37540,0,0,'Cannon Blast - target The Skybreaker'), +(13,2,69400,0,31,3,37215,0,0,'Cannon Blast - target Orgrim''s Hammer'), +(13,2,69402,0,31,3,37540,0,0,'Incinerating Blast - target The Skybreaker'), +(13,2,70175,0,31,3,37215,0,0,'Incinerating Blast - target Orgrim''s Hammer'), +(13,1,69705,0,31,3,36839,0,0,'Below Zero - target Horde Gunship Cannon'), +(13,1,69705,1,31,3,36838,0,0,'Below Zero - target Alliance Gunship Cannon'), +(13,1,70403,0,31,3,37547,0,0,'Burning Pitch - target Gunship Hull'), +(13,1,70397,0,31,3,37547,0,0,'Burning Pitch - target Gunship Hull'), +(13,1,70383,0,31,3,37215,0,0,'Burning Pitch - target Orgrim''s Hammer'), +(13,1,70374,0,31,3,37540,0,0,'Burning Pitch - target The Skybreaker'), +(13,1,70444,0,31,3,37116,0,0,'Explosion - target Skybreaker Sorcerer'), +(13,1,70444,1,31,3,36969,0,0,'Explosion - target Skybreaker Rifleman'), +(13,1,70444,2,31,3,36978,0,0,'Explosion - target Skybreaker Mortar Soldier'), +(13,1,70444,3,31,3,37117,0,0,'Explosion - target Kor''kron Battle-Mage'), +(13,1,70444,4,31,3,36968,0,0,'Explosion - target Kor''kron Axethrower'), +(13,1,70444,5,31,3,36982,0,0,'Explosion - target Kor''kron Rocketeer'), +(13,1,67335,0,31,3,37540,0,0,'Gunship Fall Teleport - target The Skybreaker'), +(13,1,67335,1,31,3,37215,0,0,'Gunship Fall Teleport - target Orgrim''s Hammer'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=17 AND `SourceEntry`=68645; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`Comment`) VALUES +(17,0,68645,0,1,70348,0,0,0,173,'Rocket Pack - require Rocket Pack Useable'); + + +DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` IN (37227,36838,36839); +INSERT INTO `npc_spellclick_spells` (`npc_entry`,`spell_id`,`cast_flags`,`user_type`) VALUES +(37227,70104,3,0), +(36838,70510,1,0), +(36839,70510,1,0); + +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` IN (68645,73077); +INSERT INTO `spell_linked_spell` (`spell_trigger`,`spell_effect`,`type`,`comment`) VALUES +(68645,68721,1,'Rocket Pack - additional aura'), +(73077,69188,2,'Rocket Pack - linked aura'); + +DELETE FROM `creature_template_addon` WHERE `entry` IN (36838,36839,37184,37488); +INSERT INTO `creature_template_addon` (`entry`,`mount`,`bytes1`,`bytes2`,`auras`) VALUES +(36838,0,0x0,0x1,'69470'), -- Alliance Gunship Cannon - Heat Drain +(36839,0,0x0,0x1,'69470'), -- Horde Gunship Cannon - Heat Drain +(37184,0,0x0,0x1,'69188 70348'), -- Zafod Boombox - Rocket Pack, Rocket Pack Useable +(37488,0,0x2000000,0x1,''); -- Teleport Exit + +DELETE FROM `creature` WHERE `guid` IN (201047,201030); +SET @CGUID := 133934; +DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID AND @CGUID+58; +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`MovementType`,`npcflag`,`unit_flags`,`dynamicflags`) VALUES +(@CGUID+0,37540,672,15,1,31043,0,-13.1429,-0.36969,12.8909,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+1,37547,672,15,1,0,0,-50.1652,9.71624,23.5871,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+2,37547,672,15,1,0,0,-34.2702,-26.1897,21.3748,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+3,37547,672,15,1,0,0,-41.4456,-7.6475,20.4975,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+4,37519,672,15,1,0,0,-28.275,15.5946,20.5379,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+5,37547,672,15,1,0,0,-11.6446,-19.8518,20.8843,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+6,37547,672,15,1,0,0,-19.8822,-6.57876,20.5744,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+7,36948,672,15,1,0,0,1.34481,-0.077413,20.8492,3.15905,604800,0,0,1,0,0,0,0,0), +(@CGUID+8,32780,672,15,1,0,0,1.29247,-0.006242,20.8767,3.12414,604800,0,0,1,0,0,0,0,0), +(@CGUID+9,37547,672,15,1,0,0,0.554884,-1.2329,20.5371,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+10,37547,672,15,1,0,0,19.7229,-2.19379,33.0698,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+11,37547,672,15,1,0,0,8.5994,-28.5585,24.7992,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+12,37547,672,15,1,0,0,11.4584,16.3662,20.5419,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+13,37547,672,15,1,0,0,38.9434,-33.808,25.3962,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+14,37519,672,15,1,0,0,39.4475,0.136515,25.2321,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+15,37547,673,15,1,0,0,53.1563,29.0877,44.7302,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+16,37547,673,15,1,0,0,-58.1547,0.748094,41.8766,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+17,37547,673,15,1,0,0,-39.4953,16.6872,34.3943,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+18,37547,673,15,1,0,0,-27.097,27.9929,34.3631,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+19,37547,673,15,1,0,0,-15.0316,12.0216,33.8629,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+20,37547,673,15,1,0,0,9.46182,16.1523,35.1091,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+21,37547,673,15,1,0,0,27.6276,27.103,36.8003,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+22,36939,673,15,1,0,0,36.4055,0.184604,36.7153,3.10669,604800,0,0,1,0,0,0,0,0), +(@CGUID+23,37184,673,15,1,0,0,38.5985,18.0196,36.6939,3.94444,604800,0,0,1,0,0,0,0,0), +(@CGUID+24,37833,673,15,1,0,0,60.4547,0.021568,38.7034,3.12414,604800,0,0,1,0,0,0,0,0), +(@CGUID+25,37547,673,15,1,0,0,4.7803,-29.0523,35.0963,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+26,37547,673,15,1,0,0,23.4778,-7.53715,35.8162,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+27,37547,673,15,1,0,0,-5.60755,-6.35065,34.0036,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+28,37519,673,15,1,0,0,-19.9011,-11.1976,33.4849,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+29,37519,673,15,1,0,0,22.1763,-11.4125,34.9973,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+30,36971,673,15,1,0,0,-56.4357,12.2929,34.6332,2.51327,604800,0,0,1,0,0,0,0,0), +(@CGUID+31,36971,673,15,1,0,0,30.8803,22.7656,36.3547,1.69297,604800,0,0,1,0,0,0,0,0), +(@CGUID+32,36971,673,15,1,0,0,-26.8348,13.4803,34.6954,5.3058,604800,0,0,1,0,0,0,0,0), +(@CGUID+33,36971,673,15,1,0,0,-29.3313,-23.2348,33.9633,2.80988,604800,0,0,1,0,0,0,0,0), +(@CGUID+34,36971,673,15,1,0,0,-26.1657,-13.3904,34.679,0.890118,604800,0,0,1,0,0,0,0,0), +(@CGUID+35,36971,673,15,1,0,0,60.0911,-6.35005,38.9569,2.54818,604800,0,0,1,0,0,0,0,0), +(@CGUID+36,36971,673,15,1,0,0,59.6708,6.21392,39.0067,3.735,604800,0,0,1,0,0,0,0,0), +(@CGUID+37,36971,673,15,1,0,0,30.9602,-22.9078,36.363,4.46804,604800,0,0,1,0,0,0,0,0), +(@CGUID+38,36839,673,15,1,0,0,-15.6908,31.1423,34.391,1.5708,604800,0,0,1,0,0,0,0,0), +(@CGUID+39,37215,673,15,1,31044,0,3.8386,0.183334,24.1005,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+40,36839,673,15,1,0,0,18.1923,29.8694,36.3265,1.55334,604800,0,0,1,0,0,0,0,0), +(@CGUID+41,36971,673,15,1,0,0,-54.3389,-14.5897,34.4998,3.9619,604800,0,0,1,0,0,0,0,0), +(@CGUID+42,37184,672,15,1,0,0,18.8226,9.700101,20.41841,3.106686,604800,0,0,1,0,0,0,0,0), -- Zafod Boombox (A) +(@CGUID+43,37182,672,15,1,0,0,42.78902,-0.010491,25.24052,3.124139,604800,0,0,1,0,0,0,0,0), -- High Captain Justin Bartlett +(@CGUID+44,36970,672,15,1,0,0,42.80151,25.06216,31.84073,4.756748,604800,0,0,1,0,0,0,0,0), -- Skybreaker Deckhand +(@CGUID+45,36970,672,15,1,0,0,35.651,20.29211,25.11613,1.58825,604800,0,0,1,0,0,0,0,0), -- Skybreaker Deckhand +(@CGUID+46,36970,672,15,1,0,0,29.25061,-6.920386,23.37144,3.455752,604800,0,0,1,0,0,0,0,0), -- Skybreaker Deckhand +(@CGUID+47,36970,672,15,1,0,0,35.57132,-20.18365,25.1162,4.712389,604800,0,0,1,0,0,0,0,0), -- Skybreaker Deckhand +(@CGUID+48,36970,672,15,1,0,0,9.26111,-22.73216,21.84549,5.864306,604800,0,0,1,0,0,0,0,0), -- Skybreaker Deckhand +(@CGUID+49,36970,672,15,1,0,0,-36.38065,2.928953,20.5322,1.570796,604800,0,0,1,0,0,0,0,0), -- Skybreaker Deckhand +(@CGUID+50,36970,672,15,1,0,0,-36.22218,-2.960294,20.53312,4.694936,604800,0,0,1,0,0,0,0,0), -- Skybreaker Deckhand +(@CGUID+51,36970,672,15,1,0,0,-64.70975,4.575944,23.52326,2.094395,604800,0,0,1,0,0,0,0,0), -- Skybreaker Deckhand +(@CGUID+52,36948,672,15,1,0,0,13.51547,-0.160213,20.87252,3.106686,604800,0,0,1,0,0,0,0,0), -- Muradin Bronzebeard (A) +(@CGUID+53,36838,672,15,1,0,0,-6.155821,-25.23873,21.70498,4.712389,604800,0,0,1,0,0,0,0,0), -- Alliance Gunship Cannon +(@CGUID+54,36838,672,15,1,0,0,-33.6443,-24.06576,21.68014,4.712389,604800,0,0,1,0,0,0,0,0), -- Alliance Gunship Cannon +(@CGUID+55,36838,672,10,1,0,0,-24.66251,-24.52669,21.64428,4.712389,604800,0,0,1,0,0,0,0,0), -- Alliance Gunship Cannon +(@CGUID+56,36838,672,10,1,0,0,-15.35026,-24.90373,21.62014,4.712389,604800,0,0,1,0,0,0,0,0), -- Alliance Gunship Cannon +(@CGUID+57,36839,673,10,1,0,0,11.17875,30.73435,35.95937,1.553343,604800,0,0,1,0,0,0,0,0), -- Horde Gunship Cannon +(@CGUID+58,36839,673,10,1,0,0,-8.200627,31.49327,34.52401,1.553343,604800,0,0,1,0,0,0,0,0); -- Horde Gunship Cannon + +DELETE FROM `creature_addon` WHERE `guid` IN (@CGUID+04,@CGUID+14,@CGUID+28,@CGUID+29,200879); +INSERT INTO `creature_addon` (`guid`,`mount`,`bytes1`,`bytes2`,`auras`) VALUES +(@CGUID+04,0,0x3000000,0x1,'70120'), -- Safe Area (IGB) - On Skybreaker Deck +(@CGUID+14,0,0x3000000,0x1,'70120'), -- Safe Area (IGB) - On Skybreaker Deck +(@CGUID+28,0,0x3000000,0x1,'70121'), -- Safe Area (IGB) - On Orgrim's Hammer Deck +(@CGUID+29,0,0x3000000,0x1,'70121'), -- Safe Area (IGB) - On Orgrim's Hammer Deck +( 200879,0,0x0000000,0x1,'69942'); -- Invisible Stalker (All Phases) - Phase Normal + Dungeon Encounter 1 + +SET @OGUID := 14732; +DELETE FROM `gameobject` WHERE `id`=202211; +DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID AND @OGUID+7; +INSERT INTO `gameobject` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`position_x`,`position_y`,`position_z`,`orientation`,`rotation0`,`rotation1`,`rotation2`,`rotation3`,`spawntimesecs`,`animprogress`,`state`) VALUES +(@OGUID+0,202178,673,1,1,-19.87256,-14.17484,33.63771,4.71239,0,0,0,1,604800,255,1), -- Gunship Armory +(@OGUID+1,202180,673,2,1,-19.87256,-14.17484,33.63771,4.71239,0,0,0,1,604800,255,1), -- Gunship Armory +(@OGUID+2,202177,673,4,1,-19.87256,-14.17484,33.63771,4.71239,0,0,0,1,604800,255,1), -- Gunship Armory +(@OGUID+3,202179,673,8,1,-19.87256,-14.17484,33.63771,4.71239,0,0,0,1,604800,255,1), -- Gunship Armory +(@OGUID+4,201873,672,1,1,-45.44891,-0.062003,20.56404,0.2697698,0,0,0,1,604800,255,1), +(@OGUID+5,201874,672,2,1,-45.44891,-0.062003,20.56404,0.2697698,0,0,0,1,604800,255,1), +(@OGUID+6,201872,672,4,1,-45.44891,-0.062003,20.56404,0.2697698,0,0,0,1,604800,255,1), +(@OGUID+7,201875,672,8,1,-45.44891,-0.062003,20.56404,0.2697698,0,0,0,1,604800,255,1); + +DELETE FROM `spell_custom_attr` WHERE `entry` IN (72347); +INSERT INTO `spell_custom_attr` (`entry`,`attributes`) VALUES +(72347,4096); + +UPDATE `creature_model_info` SET `bounding_radius`=0.520500,`combat_reach`=2.25000,`gender`=0 WHERE `modelid`=30508; -- Muradin Bronzebeard +UPDATE `creature_model_info` SET `bounding_radius`=0.558000,`combat_reach`=2.25000,`gender`=0 WHERE `modelid`=30416; -- High Overlord Saurfang +UPDATE `creature_model_info` SET `bounding_radius`=0.500000,`combat_reach`=1.00000,`gender`=2 WHERE `modelid`=31043; -- The Skybreaker +UPDATE `creature_model_info` SET `bounding_radius`=0.500000,`combat_reach`=1.00000,`gender`=2 WHERE `modelid`=31044; -- Orgrim's Hammer +UPDATE `creature_model_info` SET `bounding_radius`=1.250000,`combat_reach`=1.25000,`gender`=2 WHERE `modelid`=30615; -- Teleport Portal, Teleport Exit +UPDATE `creature_model_info` SET `bounding_radius`=0.364000,`combat_reach`=2.62500,`gender`=1 WHERE `modelid`=30609; -- Skybreaker Sorcerer +UPDATE `creature_model_info` SET `bounding_radius`=0.615825,`combat_reach`=3.01875,`gender`=1 WHERE `modelid`=30610; -- Skybreaker Sorcerer +UPDATE `creature_model_info` SET `bounding_radius`=0.615825,`combat_reach`=3.01875,`gender`=0 WHERE `modelid`=30611; -- Skybreaker Sorcerer +UPDATE `creature_model_info` SET `bounding_radius`=0.347000,`combat_reach`=1.50000,`gender`=0 WHERE `modelid`=30603; -- Skybreaker Rifleman +UPDATE `creature_model_info` SET `bounding_radius`=0.381700,`combat_reach`=1.65000,`gender`=0 WHERE `modelid`=30604; -- Skybreaker Rifleman +UPDATE `creature_model_info` SET `bounding_radius`=0.347000,`combat_reach`=1.50000,`gender`=1 WHERE `modelid`=30605; -- Skybreaker Rifleman +UPDATE `creature_model_info` SET `bounding_radius`=0.416400,`combat_reach`=1.80000,`gender`=0 WHERE `modelid`=30602; -- Skybreaker Mortar Soldier +UPDATE `creature_model_info` SET `bounding_radius`=0.306000,`combat_reach`=1.50000,`gender`=0 WHERE `modelid`=30598; -- Skybreaker Marine +UPDATE `creature_model_info` SET `bounding_radius`=0.306000,`combat_reach`=1.50000,`gender`=0 WHERE `modelid`=30599; -- Skybreaker Marine +UPDATE `creature_model_info` SET `bounding_radius`=1.000000,`combat_reach`=1.50000,`gender`=0 WHERE `modelid`=30600; -- Skybreaker Marine +UPDATE `creature_model_info` SET `bounding_radius`=0.208000,`combat_reach`=1.50000,`gender`=1 WHERE `modelid`=30601; -- Skybreaker Marine +UPDATE `creature_model_info` SET `bounding_radius`=0.397800,`combat_reach`=1.95000,`gender`=0 WHERE `modelid`=30606; -- Skybreaker Sergeant +UPDATE `creature_model_info` SET `bounding_radius`=0.367200,`combat_reach`=1.80000,`gender`=0 WHERE `modelid`=30607; -- Skybreaker Sergeant +UPDATE `creature_model_info` SET `bounding_radius`=0.382500,`combat_reach`=1.87500,`gender`=0 WHERE `modelid`=30608; -- Skybreaker Sergeant +UPDATE `creature_model_info` SET `bounding_radius`=0.670250,`combat_reach`=2.62500,`gender`=0 WHERE `modelid`=30741; -- Kor'kron Battle-Mage +UPDATE `creature_model_info` SET `bounding_radius`=0.670250,`combat_reach`=2.62500,`gender`=0 WHERE `modelid`=30742; -- Kor'kron Battle-Mage +UPDATE `creature_model_info` SET `bounding_radius`=0.670250,`combat_reach`=2.62500,`gender`=1 WHERE `modelid`=30743; -- Kor'kron Battle-Mage +UPDATE `creature_model_info` SET `bounding_radius`=0.670250,`combat_reach`=2.62500,`gender`=1 WHERE `modelid`=30744; -- Kor'kron Battle-Mage +UPDATE `creature_model_info` SET `bounding_radius`=0.306000,`combat_reach`=1.50000,`gender`=0 WHERE `modelid`=30739; -- Kor'kron Axethrower +UPDATE `creature_model_info` SET `bounding_radius`=0.306000,`combat_reach`=1.50000,`gender`=0 WHERE `modelid`=30740; -- Kor'kron Axethrower +UPDATE `creature_model_info` SET `bounding_radius`=0.459000,`combat_reach`=2.25000,`gender`=0 WHERE `modelid`=30748; -- Kor'kron Rocketeer +UPDATE `creature_model_info` SET `bounding_radius`=0.459000,`combat_reach`=2.25000,`gender`=1 WHERE `modelid`=30749; -- Kor'kron Rocketeer +UPDATE `creature_model_info` SET `bounding_radius`=0.372000,`combat_reach`=1.50000,`gender`=0 WHERE `modelid`=30750; -- Kor'kron Reaver +UPDATE `creature_model_info` SET `bounding_radius`=0.372000,`combat_reach`=1.50000,`gender`=0 WHERE `modelid`=30751; -- Kor'kron Reaver +UPDATE `creature_model_info` SET `bounding_radius`=0.236000,`combat_reach`=1.50000,`gender`=1 WHERE `modelid`=30752; -- Kor'kron Reaver +UPDATE `creature_model_info` SET `bounding_radius`=0.520833,`combat_reach`=2.25000,`gender`=0 WHERE `modelid`=30745; -- Kor'kron Sergeant +UPDATE `creature_model_info` SET `bounding_radius`=0.520833,`combat_reach`=2.25000,`gender`=0 WHERE `modelid`=30746; -- Kor'kron Sergeant +UPDATE `creature_model_info` SET `bounding_radius`=0.520833,`combat_reach`=2.25000,`gender`=0 WHERE `modelid`=30747; -- Kor'kron Sergeant + +DELETE FROM `creature_equip_template` WHERE `entry` IN (36948,36939,37116,36969,36950,36961,37117,36968,36957,36960,36970,36971,37182,37833); +INSERT INTO `creature_equip_template` (`entry`,`id`,`itemEntry1`,`itemEntry2`,`itemEntry3`) VALUES +(36948,1,49775,49774,0), -- Muradin Bronzebeard +(36939,1,49773,0,0), -- High Overlord Saurfang +(37116,1,39746,0,0), -- Skybreaker Sorcerer +(36969,1,0,0,12523), -- Skybreaker Rifleman +(36950,1,49687,0,0), -- Skybreaker Marine +(36961,1,49637,0,0), -- Skybreaker Sergeant +(37117,1,39746,0,0), -- Kor'kron Battle-Mage +(36968,1,49691,0,49873), -- Kor'kron Axethrower +(36957,1,49689,0,0), -- Kor'kron Reaver +(36960,1,34638,0,0), -- Kor'kron Sergeant +(36970,1,1493,0,0), -- Skybreaker Deckhand +(36971,1,11019,0,0), -- Orgrim's Hammer Crew +(37182,1,42757,0,2552), -- High Captain Justin Bartlett +(37833,1,43175,0,21554); -- Sky-Reaver Korm Blackscar + +DELETE FROM `spell_target_position` WHERE `id` IN (70446,71284,72340); +INSERT INTO `spell_target_position` (`id`,`effIndex`,`target_map`,`target_position_x`,`target_position_y`,`target_position_z`,`target_orientation`) VALUES +(70446,1,631,-437.078,2390.10,191.233,1.57080), +(71284,1,631,-437.447,2032.51,191.234,4.73831), +(72340,1,631,-548.983,2211.24,539.290,0.00576); + +DELETE FROM `spell_scripts` WHERE `id`=50630; + +DELETE FROM `gameobject_loot_template` WHERE `entry` IN (28045,28072,28057,28090); +INSERT INTO `gameobject_loot_template` (`entry`, `item`, `ChanceOrQuestChance`, `lootmode`, `groupid`, `mincountOrRef`, `maxcount`) VALUES +(28045,1,100,1,0,-12036,2), +(28045,49426,100,1,0,2,2), -- 10N, Emblem of Frost +(28072,1,100,1,0,-34251,2), +(28072,49426,100,1,0,2,2), -- 25N, Emblem of Frost +(28072,49908,38,1,0,1,1), -- 25N, Primordial Saronite +(28072,50274,-35,1,0,1,1), -- 25N, Shadowfrost Shard +(28057,1,100,1,0,-34263,2), +(28057,49426,100,1,0,2,2), -- 10H, Emblem of Frost +(28057,49908,38,1,0,1,1), -- 10H, Primordial Saronite +(28090,1,100,1,0,-34275,2), +(28090,49426,100,1,0,2,2), -- 25H, Emblem of Frost +(28090,49908,50,1,0,1,1), -- 25H, Primordial Saronite +(28090,50274,-75,1,0,1,1); -- 25H, Shadowfrost Shard + +DELETE FROM `disables` WHERE `sourceType`=4 AND `entry` IN (12771,12777,12947,13041,13052,13079,13080,13081,13094,13109,13110,13111,13187,13198,13333,13353); +DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (12771,12777,12947,13041,13052,13079,13080,13081,13094,13109,13110,13111,13187,13198,13333,13353); +INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`,`ScriptName`) VALUES +(13333,12,0,0,''), -- Lich King 10-player bosses defeated +(13353,12,1,0,''), -- Lich King 25-player bosses defeated +(12771,12,0,0,''), -- Storming the Citadel (10 player) +(13041,12,2,0,''), -- Heroic: Storming the Citadel (10 player) +(12947,12,0,0,''), -- Storming the Citadel (25 player) +(13052,12,3,0,''), -- Heroic: Storming the Citadel (25 player) +(12777,12,0,0,''), -- I'm on a Boat (10 player) +(13080,12,1,0,''), -- I'm on a Boat (25 player) +(13079,12,2,0,''), -- I'm on a Boat (10 player, Heroic) +(13081,12,3,0,''), -- I'm on a Boat (25 player, Heroic) +(12777,11,0,0,'achievement_im_on_a_boat'), -- I'm on a Boat (10 player) +(13080,11,0,0,'achievement_im_on_a_boat'), -- I'm on a Boat (25 player) +(13079,11,0,0,'achievement_im_on_a_boat'), -- I'm on a Boat (10 player, Heroic) +(13081,11,0,0,'achievement_im_on_a_boat'), -- I'm on a Boat (25 player, Heroic) +(13094,12,0,0,''), -- Gunship Battle victories (Icecrown 10 player) +(13110,12,2,0,''), -- Gunship Battle victories (Heroic Icecrown 10 player) +(13109,12,1,0,''), -- Gunship Battle victories (Icecrown 25 player) +(13111,12,3,0,''), -- Gunship Battle victories (Heroic Icecrown 25 player) +(13187,12,3,0,''), +(13198,12,2,0,''); diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 9e05ade2a21..cf7cadadbfd 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -31,6 +31,7 @@ #include "Player.h" #include "Cell.h" #include "CellImpl.h" +#include "Totem.h" Transport::Transport() : GameObject(), _transportInfo(NULL), _isMoving(true), _pendingStop(false), @@ -328,6 +329,129 @@ GameObject* Transport::CreateGOPassenger(uint32 guid, GameObjectData const* data return go; } +TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSummonType summonType, SummonPropertiesEntry const* properties /*= NULL*/, uint32 duration /*= 0*/, Unit* summoner /*= NULL*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/) +{ + Map* map = FindMap(); + if (!map) + return NULL; + + uint32 mask = UNIT_MASK_SUMMON; + if (properties) + { + switch (properties->Category) + { + case SUMMON_CATEGORY_PET: + mask = UNIT_MASK_GUARDIAN; + break; + case SUMMON_CATEGORY_PUPPET: + mask = UNIT_MASK_PUPPET; + break; + case SUMMON_CATEGORY_VEHICLE: + mask = UNIT_MASK_MINION; + break; + case SUMMON_CATEGORY_WILD: + case SUMMON_CATEGORY_ALLY: + case SUMMON_CATEGORY_UNK: + { + switch (properties->Type) + { + case SUMMON_TYPE_MINION: + case SUMMON_TYPE_GUARDIAN: + case SUMMON_TYPE_GUARDIAN2: + mask = UNIT_MASK_GUARDIAN; + break; + case SUMMON_TYPE_TOTEM: + case SUMMON_TYPE_LIGHTWELL: + mask = UNIT_MASK_TOTEM; + break; + case SUMMON_TYPE_VEHICLE: + case SUMMON_TYPE_VEHICLE2: + mask = UNIT_MASK_SUMMON; + break; + case SUMMON_TYPE_MINIPET: + mask = UNIT_MASK_MINION; + break; + default: + if (properties->Flags & 512) // Mirror Image, Summon Gargoyle + mask = UNIT_MASK_GUARDIAN; + break; + } + break; + } + default: + return NULL; + } + } + + uint32 phase = PHASEMASK_NORMAL; + uint32 team = 0; + if (summoner) + { + phase = summoner->GetPhaseMask(); + if (summoner->GetTypeId() == TYPEID_PLAYER) + team = summoner->ToPlayer()->GetTeam(); + } + + TempSummon* summon = NULL; + switch (mask) + { + case UNIT_MASK_SUMMON: + summon = new TempSummon(properties, summoner, false); + break; + case UNIT_MASK_GUARDIAN: + summon = new Guardian(properties, summoner, false); + break; + case UNIT_MASK_PUPPET: + summon = new Puppet(properties, summoner); + break; + case UNIT_MASK_TOTEM: + summon = new Totem(properties, summoner); + break; + case UNIT_MASK_MINION: + summon = new Minion(properties, summoner, false); + break; + } + + float x, y, z, o; + pos.GetPosition(x, y, z, o); + CalculatePassengerPosition(x, y, z, &o); + + if (!summon->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, phase, entry, vehId, team, x, y, z, o)) + { + delete summon; + return NULL; + } + + summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId); + + summon->SetTransport(this); + summon->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); + summon->m_movementInfo.transport.guid = GetGUID(); + summon->m_movementInfo.transport.pos.Relocate(pos); + summon->Relocate(x, y, z, o); + summon->SetHomePosition(x, y, z, o); + summon->SetTransportHomePosition(pos); + + /// @HACK - transport models are not added to map's dynamic LoS calculations + /// because the current GameObjectModel cannot be moved without recreating + summon->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING); + + summon->InitStats(duration); + + if (!map->AddToMap(summon)) + { + delete summon; + return NULL; + } + + _staticPassengers.insert(summon); + + summon->InitSummon(); + summon->SetTempSummonType(summonType); + + return summon; +} + void Transport::UpdatePosition(float x, float y, float z, float o) { bool newActive = GetMap()->IsGridLoaded(x, y); diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index f429d938429..398356c4980 100644 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -47,6 +47,24 @@ class Transport : public GameObject, public TransportBase Creature* CreateNPCPassenger(uint32 guid, CreatureData const* data); GameObject* CreateGOPassenger(uint32 guid, GameObjectData const* data); + /** + * @fn bool Transport::SummonPassenger(uint64, Position const&, TempSummonType, SummonPropertiesEntry const*, uint32, Unit*, uint32, uint32) + * + * @brief Temporarily summons a creature as passenger on this transport. + * + * @param entry Id of the creature from creature_template table + * @param pos Initial position of the creature (transport offsets) + * @param summonType + * @param properties + * @param duration Determines how long the creauture will exist in world depending on @summonType (in milliseconds) + * @param summoner Summoner of the creature (for AI purposes) + * @param spellId + * @param vehId If set, this value overrides vehicle id from creature_template that the creature will use + * + * @return Summoned creature. + */ + TempSummon* SummonPassenger(uint32 entry, Position const& pos, TempSummonType summonType, SummonPropertiesEntry const* properties = NULL, uint32 duration = 0, Unit* summoner = NULL, uint32 spellId = 0, uint32 vehId = 0); + /// This method transforms supplied transport offsets into global coordinates void CalculatePassengerPosition(float& x, float& y, float& z, float* o = NULL) const OVERRIDE { diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 8da94ef2852..7365d592a62 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -522,6 +522,7 @@ void AddSC_boss_falric(); void AddSC_boss_marwyn(); void AddSC_boss_lord_marrowgar(); // Icecrown Citadel void AddSC_boss_lady_deathwhisper(); +void AddSC_boss_icecrown_gunship_battle(); void AddSC_boss_deathbringer_saurfang(); void AddSC_boss_festergut(); void AddSC_boss_rotface(); @@ -1361,6 +1362,7 @@ void AddNorthrendScripts() AddSC_boss_marwyn(); AddSC_boss_lord_marrowgar(); // Icecrown Citadel AddSC_boss_lady_deathwhisper(); + AddSC_boss_icecrown_gunship_battle(); AddSC_boss_deathbringer_saurfang(); AddSC_boss_festergut(); AddSC_boss_rotface(); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 93f264d2d61..009b9861eb6 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3384,6 +3384,15 @@ void SpellMgr::LoadSpellInfoCorrections() case 71169: // Shadow's Fate spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS; break; + case 72347: // Lock Players and Tap Chest + spellInfo->AttributesEx3 &= ~SPELL_ATTR3_NO_INITIAL_AGGRO; + break; + case 73843: // Award Reputation - Boss Kill + case 73844: // Award Reputation - Boss Kill + case 73845: // Award Reputation - Boss Kill + case 73846: // Award Reputation - Boss Kill + spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd + break; case 72378: // Blood Nova (Deathbringer Saurfang) case 73058: // Blood Nova (Deathbringer Saurfang) spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); diff --git a/src/server/scripts/Northrend/CMakeLists.txt b/src/server/scripts/Northrend/CMakeLists.txt index 42a7ee15bb6..aff3c0a9528 100644 --- a/src/server/scripts/Northrend/CMakeLists.txt +++ b/src/server/scripts/Northrend/CMakeLists.txt @@ -168,6 +168,7 @@ set(scripts_STAT_SRCS Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp + Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp Northrend/IcecrownCitadel/boss_festergut.cpp Northrend/IcecrownCitadel/boss_rotface.cpp diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp new file mode 100644 index 00000000000..3e18213b745 --- /dev/null +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp @@ -0,0 +1,2389 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "CreatureTextMgr.h" +#include "MoveSpline.h" +#include "MoveSplineInit.h" +#include "SpellScript.h" +#include "ScriptMgr.h" +#include "Transport.h" +#include "TransportMgr.h" +#include "Vehicle.h" +#include "icecrown_citadel.h" + +enum Texts +{ + // High Overlord Saurfang + SAY_SAURFANG_INTRO_1 = 0, + SAY_SAURFANG_INTRO_2 = 1, + SAY_SAURFANG_INTRO_3 = 2, + SAY_SAURFANG_INTRO_4 = 3, + SAY_SAURFANG_INTRO_5 = 4, + SAY_SAURFANG_INTRO_6 = 5, + SAY_SAURFANG_INTRO_A = 6, + SAY_SAURFANG_BOARD = 7, + SAY_SAURFANG_ENTER_SKYBREAKER = 8, + SAY_SAURFANG_AXETHROWERS = 9, + SAY_SAURFANG_ROCKETEERS = 10, + SAY_SAURFANG_MAGES = 11, + SAY_SAURFANG_VICTORY = 12, + SAY_SAURFANG_WIPE = 13, + + // Muradin Bronzebeard + SAY_MURADIN_INTRO_1 = 0, + SAY_MURADIN_INTRO_2 = 1, + SAY_MURADIN_INTRO_3 = 2, + SAY_MURADIN_INTRO_4 = 3, + SAY_MURADIN_INTRO_5 = 4, + SAY_MURADIN_INTRO_6 = 5, + SAY_MURADIN_INTRO_7 = 6, + SAY_MURADIN_INTRO_H = 7, + SAY_MURADIN_BOARD = 8, + SAY_MURADIN_ENTER_ORGRIMMS_HAMMER = 9, + SAY_MURADIN_RIFLEMAN = 10, + SAY_MURADIN_MORTAR = 11, + SAY_MURADIN_SORCERERS = 12, + SAY_MURADIN_VICTORY = 13, + SAY_MURADIN_WIPE = 14, + + SAY_ZAFOD_ROCKET_PACK_ACTIVE = 0, + SAY_ZAFOD_ROCKET_PACK_DISABLED = 1, + + SAY_OVERHEAT = 0 +}; + +enum Events +{ + // High Overlord Saurfang + EVENT_INTRO_H_1 = 1, + EVENT_INTRO_H_2 = 2, + EVENT_INTRO_SUMMON_SKYBREAKER = 3, + EVENT_INTRO_H_3 = 4, + EVENT_INTRO_H_4 = 5, + EVENT_INTRO_H_5 = 6, + EVENT_INTRO_H_6 = 7, + + // Muradin Bronzebeard + EVENT_INTRO_A_1 = 1, + EVENT_INTRO_A_2 = 2, + EVENT_INTRO_SUMMON_ORGRIMS_HAMMER = 3, + EVENT_INTRO_A_3 = 4, + EVENT_INTRO_A_4 = 5, + EVENT_INTRO_A_5 = 6, + EVENT_INTRO_A_6 = 7, + EVENT_INTRO_A_7 = 8, + + EVENT_KEEP_PLAYER_IN_COMBAT = 9, + EVENT_SUMMON_MAGE = 10, + EVENT_ADDS = 11, + EVENT_ADDS_BOARD_YELL = 12, + EVENT_CHECK_RIFLEMAN = 13, + EVENT_CHECK_MORTAR = 14, + EVENT_CLEAVE = 15, + + EVENT_BLADESTORM = 16, + EVENT_WOUNDING_STRIKE = 17 +}; + +enum Spells +{ + // Applied on friendly transport NPCs + SPELL_FRIENDLY_BOSS_DAMAGE_MOD = 70339, + SPELL_CHECK_FOR_PLAYERS = 70332, + SPELL_GUNSHIP_FALL_TELEPORT = 67335, + SPELL_TELEPORT_PLAYERS_ON_RESET_A = 70446, + SPELL_TELEPORT_PLAYERS_ON_RESET_H = 71284, + SPELL_TELEPORT_PLAYERS_ON_VICTORY = 72340, + SPELL_ACHIEVEMENT = 72959, + SPELL_AWARD_REPUTATION_BOSS_KILL = 73843, + + // Murading Bronzebeard + // High Overlord Saurfang + SPELL_BATTLE_FURY = 69637, + SPELL_RENDING_THROW = 70309, + SPELL_CLEAVE = 15284, + SPELL_TASTE_OF_BLOOD = 69634, + + // Applied on enemy NPCs + SPELL_MELEE_TARGETING_ON_SKYBREAKER = 70219, + SPELL_MELEE_TARGETING_ON_ORGRIMS_HAMMER = 70294, + + // Gunship Hull + SPELL_EXPLOSION_WIPE = 72134, + SPELL_EXPLOSION_VICTORY = 72137, + + // Hostile NPCs + SPELL_TELEPORT_TO_ENEMY_SHIP = 70104, + SPELL_BATTLE_EXPERIENCE = 71201, + SPELL_EXPERIENCED = 71188, + SPELL_VETERAN = 71193, + SPELL_ELITE = 71195, + SPELL_ADDS_BERSERK = 72525, + + // Skybreaker Sorcerer + // Kor'kron Battle-Mage + SPELL_SHADOW_CHANNELING = 43897, + SPELL_BELOW_ZERO = 69705, + + // Skybreaker Rifleman + // Kor'kron Axethrower + SPELL_SHOOT = 70162, + SPELL_HURL_AXE = 70161, + SPELL_BURNING_PITCH_A = 70403, + SPELL_BURNING_PITCH_H = 70397, + SPELL_BURNING_PITCH = 69660, + + // Skybreaker Mortar Soldier + // Kor'kron Rocketeer + SPELL_ROCKET_ARTILLERY_A = 70609, + SPELL_ROCKET_ARTILLERY_H = 69678, + SPELL_BURNING_PITCH_DAMAGE_A = 70383, + SPELL_BURNING_PITCH_DAMAGE_H = 70374, + + // Skybreaker Marine + // Kor'kron Reaver + SPELL_DESPERATE_RESOLVE = 69647, + + // Skybreaker Sergeant + // Kor'kron Sergeant + SPELL_BLADESTORM = 69652, + SPELL_WOUNDING_STRIKE = 69651, + + // + SPELL_LOCK_PLAYERS_AND_TAP_CHEST = 72347, + SPELL_ON_SKYBREAKER_DECK = 70120, + SPELL_ON_ORGRIMS_HAMMER_DECK = 70121, + + // Rocket Pack + SPELL_ROCKET_PACK_DAMAGE = 69193, + SPELL_ROCKET_BURST = 69192, + SPELL_ROCKET_PACK_USEABLE = 70348, + + // Alliance Gunship Cannon + // Horde Gunship Cannon + SPELL_OVERHEAT = 69487, + SPELL_EJECT_ALL_PASSENGERS_BELOW_ZERO = 68576, + SPELL_EJECT_ALL_PASSENGERS_WIPE = 50630 +}; + +enum MiscData +{ + ITEM_GOBLIN_ROCKET_PACK = 49278, + + PHASE_COMBAT = 0, + PHASE_INTRO = 1, + + MUSIC_ENCOUNTER = 17289 +}; + +enum EncounterActions +{ + ACTION_SPAWN_MAGE = 1, + ACTION_SPAWN_ALL_ADDS = 2, + ACTION_CLEAR_SLOT = 3, + ACTION_SET_SLOT = 4, + ACTION_SHIP_VISITS = 5 +}; + +Position const SkybreakerAddsSpawnPos = { 15.91131f, 0.0f, 20.4628f, M_PI }; +Position const OrgrimsHammerAddsSpawnPos = { 60.728395f, 0.0f, 38.93467f, M_PI }; + +// Horde encounter +Position const SkybreakerTeleportPortal = { 6.666975f, 0.013001f, 20.87888f, 0.0f }; +Position const OrgrimsHammerTeleportExit = { 7.461699f, 0.158853f, 35.72989f, 0.0f }; + +// Alliance encounter +Position const OrgrimsHammerTeleportPortal = { 47.550990f, -0.101778f, 37.61111f, 0.0f }; +Position const SkybreakerTeleportExit = { -17.55738f, -0.090421f, 21.18366f, 0.0f }; + +enum PassengerSlots +{ + // Freezing the cannons + SLOT_FREEZE_MAGE = 0, + + // Channeling the portal, refilled with adds that board player's ship + SLOT_MAGE_1 = 1, + SLOT_MAGE_2 = 2, + + // Rifleman + SLOT_RIFLEMAN_1 = 3, + SLOT_RIFLEMAN_2 = 4, + SLOT_RIFLEMAN_3 = 5, + SLOT_RIFLEMAN_4 = 6, + + // Additional Rifleman on 25 man + SLOT_RIFLEMAN_5 = 7, + SLOT_RIFLEMAN_6 = 8, + SLOT_RIFLEMAN_7 = 9, + SLOT_RIFLEMAN_8 = 10, + + // Mortar + SLOT_MORTAR_1 = 11, + SLOT_MORTAR_2 = 12, + + // Additional spawns on 25 man + SLOT_MORTAR_3 = 13, + SLOT_MORTAR_4 = 14, + + // Marines + SLOT_MARINE_1 = 15, + SLOT_MARINE_2 = 16, + + // Additional spawns on 25 man + SLOT_MARINE_3 = 17, + SLOT_MARINE_4 = 18, + + // Sergeants + SLOT_SERGEANT_1 = 19, + + // Additional spawns on 25 man + SLOT_SERGEANT_2 = 20, + + MAX_SLOTS +}; + +struct SlotInfo +{ + uint32 Entry; + Position TargetPosition; + uint32 Cooldown; +}; + +SlotInfo const SkybreakerSlotInfo[MAX_SLOTS] = +{ + { NPC_SKYBREAKER_SORCERER, { -9.479858f, 0.05663967f, 20.77026f, 4.729842f }, 0 }, + + { NPC_SKYBREAKER_SORCERER, { 6.385986f, 4.978760f, 20.55417f, 4.694936f }, 0 }, + { NPC_SKYBREAKER_SORCERER, { 6.579102f, -4.674561f, 20.55060f, 1.553343f }, 0 }, + + { NPC_SKYBREAKER_RIFLEMAN, { -29.563900f, -17.95801f, 20.73837f, 4.747295f }, 30 }, + { NPC_SKYBREAKER_RIFLEMAN, { -18.017210f, -18.82056f, 20.79150f, 4.747295f }, 30 }, + { NPC_SKYBREAKER_RIFLEMAN, { -9.1193850f, -18.79102f, 20.58887f, 4.712389f }, 30 }, + { NPC_SKYBREAKER_RIFLEMAN, { -0.3364258f, -18.87183f, 20.56824f, 4.712389f }, 30 }, + + { NPC_SKYBREAKER_RIFLEMAN, { -34.705810f, -17.67261f, 20.51523f, 4.729842f }, 30 }, + { NPC_SKYBREAKER_RIFLEMAN, { -23.562010f, -18.28564f, 20.67859f, 4.729842f }, 30 }, + { NPC_SKYBREAKER_RIFLEMAN, { -13.602780f, -18.74268f, 20.59622f, 4.712389f }, 30 }, + { NPC_SKYBREAKER_RIFLEMAN, { -4.3350220f, -18.84619f, 20.58234f, 4.712389f }, 30 }, + + { NPC_SKYBREAKER_MORTAR_SOLDIER, { -31.70142f, 18.02783f, 20.77197f, 4.712389f }, 30 }, + { NPC_SKYBREAKER_MORTAR_SOLDIER, { -9.368652f, 18.75806f, 20.65335f, 4.712389f }, 30 }, + + { NPC_SKYBREAKER_MORTAR_SOLDIER, { -20.40851f, 18.40381f, 20.50647f, 4.694936f }, 30 }, + { NPC_SKYBREAKER_MORTAR_SOLDIER, { 0.1585693f, 18.11523f, 20.41949f, 4.729842f }, 30 }, + + { NPC_SKYBREAKER_MARINE, SkybreakerTeleportPortal, 0 }, + { NPC_SKYBREAKER_MARINE, SkybreakerTeleportPortal, 0 }, + + { NPC_SKYBREAKER_MARINE, SkybreakerTeleportPortal, 0 }, + { NPC_SKYBREAKER_MARINE, SkybreakerTeleportPortal, 0 }, + + { NPC_SKYBREAKER_SERGEANT, SkybreakerTeleportPortal, 0 }, + + { NPC_SKYBREAKER_SERGEANT, SkybreakerTeleportPortal, 0 } +}; + +SlotInfo const OrgrimsHammerSlotInfo[MAX_SLOTS] = +{ + { NPC_KOR_KRON_BATTLE_MAGE, { 13.58548f, 0.3867192f, 34.99243f, 1.53589f }, 0 }, + + { NPC_KOR_KRON_BATTLE_MAGE, { 47.29290f, -4.308941f, 37.55550f, 1.570796f }, 0 }, + { NPC_KOR_KRON_BATTLE_MAGE, { 47.34621f, 4.032004f, 37.70952f, 4.817109f }, 0 }, + + { NPC_KOR_KRON_AXETHROWER, { -12.09280f, 27.65942f, 33.58557f, 1.53589f }, 30 }, + { NPC_KOR_KRON_AXETHROWER, { -3.170555f, 28.30652f, 34.21082f, 1.53589f }, 30 }, + { NPC_KOR_KRON_AXETHROWER, { 14.928040f, 26.18018f, 35.47803f, 1.53589f }, 30 }, + { NPC_KOR_KRON_AXETHROWER, { 24.703310f, 25.36584f, 35.97845f, 1.53589f }, 30 }, + + { NPC_KOR_KRON_AXETHROWER, { -16.65302f, 27.59668f, 33.18726f, 1.53589f }, 30 }, + { NPC_KOR_KRON_AXETHROWER, { -8.084572f, 28.21448f, 33.93805f, 1.53589f }, 30 }, + { NPC_KOR_KRON_AXETHROWER, { 7.594765f, 27.41968f, 35.00775f, 1.53589f }, 30 }, + { NPC_KOR_KRON_AXETHROWER, { 20.763390f, 25.58215f, 35.75287f, 1.53589f }, 30 }, + + { NPC_KOR_KRON_ROCKETEER, { -11.44849f, -25.71838f, 33.64343f, 1.518436f }, 30 }, + { NPC_KOR_KRON_ROCKETEER, { 12.30336f, -25.69653f, 35.32373f, 1.518436f }, 30 }, + + { NPC_KOR_KRON_ROCKETEER, { -0.05931854f, -25.46399f, 34.50592f, 1.518436f }, 30 }, + { NPC_KOR_KRON_ROCKETEER, { 27.62149000f, -23.48108f, 36.12708f, 1.518436f }, 30 }, + + { NPC_KOR_KRON_REAVER, OrgrimsHammerTeleportPortal, 0 }, + { NPC_KOR_KRON_REAVER, OrgrimsHammerTeleportPortal, 0 }, + + { NPC_KOR_KRON_REAVER, OrgrimsHammerTeleportPortal, 0 }, + { NPC_KOR_KRON_REAVER, OrgrimsHammerTeleportPortal, 0 }, + + { NPC_KOR_KRON_SERGEANT, OrgrimsHammerTeleportPortal, 0 }, + + { NPC_KOR_KRON_SERGEANT, OrgrimsHammerTeleportPortal, 0 } +}; + +class PassengerController +{ +public: + PassengerController() + { + ResetSlots(HORDE); + } + + void SetTransport(Transport* transport) { _transport = transport; } + + void ResetSlots(uint32 team) + { + _transport = NULL; + memset(_controlledSlots, 0, sizeof(uint64)* MAX_SLOTS); + memset(_respawnCooldowns, 0, sizeof(time_t)* MAX_SLOTS); + _spawnPoint = team == HORDE ? &OrgrimsHammerAddsSpawnPos : &SkybreakerAddsSpawnPos; + _slotInfo = team == HORDE ? OrgrimsHammerSlotInfo : SkybreakerSlotInfo; + } + + bool SummonCreatures(PassengerSlots first, PassengerSlots last) + { + if (!_transport) + return false; + + bool summoned = false; + time_t now = time(NULL); + for (int32 i = first; i <= last; ++i) + { + if (_respawnCooldowns[i] > now) + continue; + + if (_controlledSlots[i]) + { + Creature* current = ObjectAccessor::GetCreature(*_transport, _controlledSlots[i]); + if (current && current->IsAlive()) + continue; + } + + if (Creature* passenger = _transport->SummonPassenger(_slotInfo[i].Entry, SelectSpawnPoint(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, NULL, 15000)) + { + _controlledSlots[i] = passenger->GetGUID(); + _respawnCooldowns[i] = time_t(0); + passenger->AI()->SetData(ACTION_SET_SLOT, i); + summoned = true; + } + } + + return summoned; + } + + void ClearSlot(PassengerSlots slot) + { + _controlledSlots[slot] = 0; + _respawnCooldowns[slot] = time(NULL) + _slotInfo[slot].Cooldown; + } + + bool SlotsNeedRefill(PassengerSlots first, PassengerSlots last) const + { + for (int32 i = first; i <= last; ++i) + if (!_controlledSlots[i]) + return true; + + return false; + } + +private: + Position SelectSpawnPoint() const + { + Position newPos; + float angle = frand(-M_PI * 0.5f, M_PI * 0.5f); + newPos.m_positionX = _spawnPoint->GetPositionX() + 2.0f * std::cos(angle); + newPos.m_positionY = _spawnPoint->GetPositionY() + 2.0f * std::sin(angle); + newPos.m_positionZ = _spawnPoint->GetPositionZ(); + newPos.SetOrientation(_spawnPoint->GetOrientation()); + return newPos; + } + + Transport* _transport; + uint64 _controlledSlots[MAX_SLOTS]; + time_t _respawnCooldowns[MAX_SLOTS]; + Position const* _spawnPoint; + SlotInfo const* _slotInfo; +}; + +class DelayedMovementEvent : public BasicEvent +{ +public: + DelayedMovementEvent(Creature* owner, Position const& dest) : _owner(owner), _dest(dest) { } + + bool Execute(uint64, uint32) OVERRIDE + { + if (!_owner->IsAlive()) + return true; + + _owner->GetMotionMaster()->MovePoint(EVENT_CHARGE_PREPATH, *_owner, false); + + Movement::MoveSplineInit init(_owner); + init.DisableTransportPathTransformations(); + init.MoveTo(_dest.GetPositionX(), _dest.GetPositionY(), _dest.GetPositionZ(), false); + init.Launch(); + + return true; + } + +private: + Creature* _owner; + Position const& _dest; +}; + +class ResetEncounterEvent : public BasicEvent +{ +public: + ResetEncounterEvent(Unit* caster, uint32 spellId, uint64 otherTransport) : _caster(caster), _spellId(spellId), _otherTransport(otherTransport) { } + + bool Execute(uint64, uint32) OVERRIDE + { + _caster->CastSpell(_caster, _spellId, true); + _caster->GetTransport()->AddObjectToRemoveList(); + + if (GameObject* go = HashMapHolder::Find(_otherTransport)) + go->AddObjectToRemoveList(); + + return true; + } + +private: + Unit* _caster; + uint32 _spellId; + uint64 _otherTransport; +}; + +class BattleExperienceEvent : public BasicEvent +{ +public: + static uint32 const ExperiencedSpells[5]; + static uint32 const ExperiencedTimes[5]; + + BattleExperienceEvent(Creature* creature) : _creature(creature), _level(0) { } + + bool Execute(uint64 timer, uint32 /*diff*/) OVERRIDE + { + if (!_creature->IsAlive()) + return true; + + _creature->RemoveAurasDueToSpell(ExperiencedSpells[_level]); + ++_level; + + _creature->CastSpell(_creature, ExperiencedSpells[_level], TRIGGERED_FULL_MASK); + if (_level < (_creature->GetMap()->IsHeroic() ? 4 : 3)) + { + _creature->m_Events.AddEvent(this, timer + ExperiencedTimes[_level]); + return false; + } + + return true; + } + +private: + Creature* _creature; + int32 _level; +}; + +uint32 const BattleExperienceEvent::ExperiencedSpells[5] = { 0, SPELL_EXPERIENCED, SPELL_VETERAN, SPELL_ELITE, SPELL_ADDS_BERSERK }; +uint32 const BattleExperienceEvent::ExperiencedTimes[5] = { 100000, 70000, 60000, 90000, 0 }; + +struct gunship_npc_AI : public ScriptedAI +{ + gunship_npc_AI(Creature* creature) : ScriptedAI(creature), + Instance(creature->GetInstanceScript()), Slot(NULL), Index(uint32(-1)) + { + BurningPitchId = Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_BURNING_PITCH_A : SPELL_BURNING_PITCH_H; + me->setRegeneratingHealth(false); + } + + void SetData(uint32 type, uint32 data) OVERRIDE + { + if (type == ACTION_SET_SLOT && data < MAX_SLOTS) + { + SetSlotInfo(data); + + me->SetReactState(REACT_PASSIVE); + + float x, y, z, o; + Slot->TargetPosition.GetPosition(x, y, z, o); + + me->SetTransportHomePosition(Slot->TargetPosition); + float hx = x, hy = y, hz = z, ho = o; + me->GetTransport()->CalculatePassengerPosition(hx, hy, hz, &ho); + me->SetHomePosition(hx, hy, hz, ho); + + me->GetMotionMaster()->MovePoint(EVENT_CHARGE_PREPATH, Slot->TargetPosition, false); + + Movement::MoveSplineInit init(me); + init.DisableTransportPathTransformations(); + init.MoveTo(x, y, z, false); + init.Launch(); + } + } + + void EnterEvadeMode() OVERRIDE + { + if (!me->IsAlive() || !me->IsInCombat()) + return; + + me->DeleteThreatList(); + me->CombatStop(true); + me->GetMotionMaster()->MoveTargetedHome(); + } + + void JustDied(Unit* /*killer*/) OVERRIDE + { + if (Slot) + if (Creature* captain = me->FindNearestCreature(Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? NPC_IGB_MURADIN_BRONZEBEARD : NPC_IGB_HIGH_OVERLORD_SAURFANG, 200.0f)) + captain->AI()->SetData(ACTION_CLEAR_SLOT, Index); + } + + void MovementInform(uint32 type, uint32 pointId) OVERRIDE + { + if (type != POINT_MOTION_TYPE) + return; + + if (pointId == EVENT_CHARGE_PREPATH && Slot) + { + me->SetFacingTo(Slot->TargetPosition.GetOrientation()); + me->m_Events.AddEvent(new BattleExperienceEvent(me), me->m_Events.CalculateTime(BattleExperienceEvent::ExperiencedTimes[0])); + DoCast(me, SPELL_BATTLE_EXPERIENCE, true); + me->SetReactState(REACT_AGGRESSIVE); + } + } + + bool CanAIAttack(Unit const* target) const OVERRIDE + { + return target->HasAura(Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_ON_ORGRIMS_HAMMER_DECK : SPELL_ON_SKYBREAKER_DECK); + } + +protected: + void SetSlotInfo(uint32 index) + { + Index = index; + Slot = &((Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SkybreakerSlotInfo : OrgrimsHammerSlotInfo)[Index]); + } + + bool SelectVictim() + { + if (Instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) + return false; + + if (!me->HasReactState(REACT_PASSIVE)) + { + if (Unit* victim = me->SelectVictim()) + AttackStart(victim); + return me->GetVictim(); + } + else if (me->getThreatManager().isThreatListEmpty()) + { + EnterEvadeMode(); + return false; + } + + return true; + } + + void TriggerBurningPitch() + { + if (Instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == IN_PROGRESS && + !me->HasUnitState(UNIT_STATE_CASTING) && !me->HasReactState(REACT_PASSIVE) && + !me->HasSpellCooldown(BurningPitchId)) + { + DoCastAOE(BurningPitchId, true); + me->_AddCreatureSpellCooldown(BurningPitchId, time(NULL) + urand(3000, 4000) / IN_MILLISECONDS); + } + } + + InstanceScript* Instance; + SlotInfo const* Slot; + uint32 Index; + uint32 BurningPitchId; +}; + +class npc_gunship : public CreatureScript +{ + public: + npc_gunship() : CreatureScript("npc_gunship") { } + + struct npc_gunshipAI : public NullCreatureAI + { + npc_gunshipAI(Creature* creature) : NullCreatureAI(creature), + _teamInInstance(creature->GetInstanceScript()->GetData(DATA_TEAM_IN_INSTANCE)), + _summonedFirstMage(false), _died(false) + { + me->setRegeneratingHealth(false); + } + + void DamageTaken(Unit* /*source*/, uint32& damage) OVERRIDE + { + if (damage > me->GetHealth()) + { + JustDied(NULL); + damage = me->GetHealth() - 1; + return; + } + + if (_summonedFirstMage) + return; + + if (me->GetTransport()->GetEntry() != uint32(_teamInInstance == HORDE ? GO_THE_SKYBREAKER_H : GO_ORGRIMS_HAMMER_A)) + return; + + if (!me->HealthBelowPctDamaged(90, damage)) + return; + + _summonedFirstMage = true; + if (Creature* captain = me->FindNearestCreature(_teamInInstance == HORDE ? NPC_IGB_MURADIN_BRONZEBEARD : NPC_IGB_HIGH_OVERLORD_SAURFANG, 100.0f)) + captain->AI()->DoAction(ACTION_SPAWN_MAGE); + } + + void JustDied(Unit* /*killer*/) OVERRIDE + { + if (_died) + return; + + _died = true; + + bool isVictory = me->GetTransport()->GetEntry() == GO_THE_SKYBREAKER_H || me->GetTransport()->GetEntry() == GO_ORGRIMS_HAMMER_A; + InstanceScript* instance = me->GetInstanceScript(); + if (Creature* creature = me->FindNearestCreature(me->GetEntry() == NPC_ORGRIMS_HAMMER ? NPC_THE_SKYBREAKER : NPC_ORGRIMS_HAMMER, 200.0f)) + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, creature); + creature->RemoveAurasDueToSpell(SPELL_CHECK_FOR_PLAYERS); + } + + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + me->RemoveAurasDueToSpell(SPELL_CHECK_FOR_PLAYERS); + + me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, 0); + std::list creatures; + GetCreatureListWithEntryInGrid(creatures, me, NPC_MARTYR_STALKER_IGB_SAURFANG, SIZE_OF_GRIDS); + for (std::list::iterator itr = creatures.begin(); itr != creatures.end(); ++itr) + (*itr)->AI()->EnterEvadeMode(); + + + uint32 explosionSpell = isVictory ? SPELL_EXPLOSION_VICTORY : SPELL_EXPLOSION_WIPE; + creatures.clear(); + GetCreatureListWithEntryInGrid(creatures, me, NPC_GUNSHIP_HULL, 200.0f); + for (std::list::iterator itr = creatures.begin(); itr != creatures.end(); ++itr) + { + Creature* hull = *itr; + if (hull->GetTransport() != me->GetTransport()) + continue; + + hull->CastSpell(hull, explosionSpell, TRIGGERED_FULL_MASK); + } + + creatures.clear(); + GetCreatureListWithEntryInGrid(creatures, me, _teamInInstance == HORDE ? NPC_HORDE_GUNSHIP_CANNON : NPC_ALLIANCE_GUNSHIP_CANNON, 200.0f); + for (std::list::iterator itr = creatures.begin(); itr != creatures.end(); ++itr) + { + Creature* cannon = *itr; + if (isVictory) + { + cannon->CastSpell(cannon, SPELL_EJECT_ALL_PASSENGERS_BELOW_ZERO, TRIGGERED_FULL_MASK); + + WorldPacket data(SMSG_PLAYER_VEHICLE_DATA, cannon->GetPackGUID().size() + 4); + data.append(cannon->GetPackGUID()); + data << uint32(0); + cannon->SendMessageToSet(&data, true); + + cannon->RemoveVehicleKit(); + } + else + cannon->CastSpell(cannon, SPELL_EJECT_ALL_PASSENGERS_WIPE, TRIGGERED_FULL_MASK); + } + + uint32 creatureEntry = NPC_IGB_MURADIN_BRONZEBEARD; + uint8 textId = isVictory ? SAY_MURADIN_VICTORY : SAY_MURADIN_WIPE; + if (_teamInInstance == HORDE) + { + creatureEntry = NPC_IGB_HIGH_OVERLORD_SAURFANG; + textId = isVictory ? SAY_SAURFANG_VICTORY : SAY_SAURFANG_WIPE; + } + + if (Creature* creature = me->FindNearestCreature(creatureEntry, 100.0f)) + creature->AI()->Talk(textId); + + if (isVictory) + { + if (GameObject* go = HashMapHolder::Find(instance->GetData64(DATA_ICECROWN_GUNSHIP_BATTLE))) + if (Transport* otherTransport = go->ToTransport()) + otherTransport->EnableMovement(true); + + me->GetTransport()->EnableMovement(true); + + if (Creature* ship = me->FindNearestCreature(_teamInInstance == HORDE ? NPC_ORGRIMS_HAMMER : NPC_THE_SKYBREAKER, 200.0f)) + { + ship->CastSpell(ship, SPELL_TELEPORT_PLAYERS_ON_VICTORY, TRIGGERED_FULL_MASK); + ship->CastSpell(ship, SPELL_ACHIEVEMENT, TRIGGERED_FULL_MASK); + ship->CastSpell(ship, SPELL_AWARD_REPUTATION_BOSS_KILL, TRIGGERED_FULL_MASK); + } + } + else + { + uint32 teleportSpellId = _teamInInstance == HORDE ? SPELL_TELEPORT_PLAYERS_ON_RESET_H : SPELL_TELEPORT_PLAYERS_ON_RESET_A; + me->m_Events.AddEvent(new ResetEncounterEvent(me, teleportSpellId, me->GetInstanceScript()->GetData64(DATA_ENEMY_GUNSHIP)), + me->m_Events.CalculateTime(8000)); + } + + instance->SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, isVictory ? DONE : FAIL); + } + + void SetGUID(uint64 guid, int32 id/* = 0*/) OVERRIDE + { + if (id != ACTION_SHIP_VISITS) + return; + + std::map::iterator itr = _shipVisits.find(guid); + if (itr == _shipVisits.end()) + _shipVisits[guid] = 1; + else + ++itr->second; + } + + uint32 GetData(uint32 id) const OVERRIDE + { + if (id != ACTION_SHIP_VISITS) + return 0; + + uint32 max = 0; + for (std::map::const_iterator itr = _shipVisits.begin(); itr != _shipVisits.end(); ++itr) + max = std::max(max, itr->second); + + return max; + } + + private: + uint32 _teamInInstance; + std::map _shipVisits; + bool _summonedFirstMage; + bool _died; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + if (!creature->GetTransport()) + return NULL; + + return GetIcecrownCitadelAI(creature); + } +}; + +class npc_high_overlord_saurfang_igb : public CreatureScript +{ + public: + npc_high_overlord_saurfang_igb() : CreatureScript("npc_high_overlord_saurfang_igb") { } + + struct npc_high_overlord_saurfang_igbAI : public ScriptedAI + { + npc_high_overlord_saurfang_igbAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + _controller.ResetSlots(HORDE); + _controller.SetTransport(creature->GetTransport()); + me->setRegeneratingHealth(false); + me->m_CombatDistance = 70.0f; + } + + void InitializeAI() OVERRIDE + { + ScriptedAI::InitializeAI(); + + _events.Reset(); + _firstMageCooldown = time(NULL) + 60; + _axethrowersYellCooldown = time_t(0); + _rocketeersYellCooldown = time_t(0); + } + + void EnterCombat(Unit* /*target*/) OVERRIDE + { + _events.SetPhase(PHASE_COMBAT); + DoCast(me, _instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_FRIENDLY_BOSS_DAMAGE_MOD : SPELL_MELEE_TARGETING_ON_ORGRIMS_HAMMER, true); + DoCast(me, SPELL_BATTLE_FURY, true); + _events.ScheduleEvent(EVENT_CLEAVE, urand(2000, 10000)); + } + + void EnterEvadeMode() OVERRIDE + { + if (!me->IsAlive()) + return; + + me->DeleteThreatList(); + me->CombatStop(true); + me->GetMotionMaster()->MoveTargetedHome(); + + Reset(); + } + + void DoAction(int32 action) OVERRIDE + { + if (action == ACTION_ENEMY_GUNSHIP_TALK) + { + if (Creature* muradin = me->FindNearestCreature(NPC_IGB_MURADIN_BRONZEBEARD, 100.0f)) + muradin->AI()->DoAction(ACTION_SPAWN_ALL_ADDS); + + Talk(SAY_SAURFANG_INTRO_5); + _events.ScheduleEvent(EVENT_INTRO_H_5, 4000); + _events.ScheduleEvent(EVENT_INTRO_H_6, 11000); + _events.ScheduleEvent(EVENT_KEEP_PLAYER_IN_COMBAT, 1); + + _instance->SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, IN_PROGRESS); + // Combat starts now + if (Creature* skybreaker = me->FindNearestCreature(NPC_THE_SKYBREAKER, 100.0f)) + _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, skybreaker, 1); + + if (Creature* orgrimsHammer = me->FindNearestCreature(NPC_ORGRIMS_HAMMER, 100.0f)) + { + _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, orgrimsHammer, 2); + orgrimsHammer->CastSpell(orgrimsHammer, SPELL_CHECK_FOR_PLAYERS, TRIGGERED_FULL_MASK); + } + + me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_ENCOUNTER); + } + else if (action == ACTION_SPAWN_MAGE) + { + time_t now = time(NULL); + if (_firstMageCooldown < now) + _events.ScheduleEvent(EVENT_SUMMON_MAGE, (now - _firstMageCooldown) * IN_MILLISECONDS); + else + _events.ScheduleEvent(EVENT_SUMMON_MAGE, 1); + } + else if (action == ACTION_SPAWN_ALL_ADDS) + { + _events.ScheduleEvent(EVENT_ADDS, 12000); + _events.ScheduleEvent(EVENT_CHECK_RIFLEMAN, 13000); + _events.ScheduleEvent(EVENT_CHECK_MORTAR, 13000); + if (Is25ManRaid()) + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MORTAR_4); + else + { + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2); + _controller.SummonCreatures(SLOT_MORTAR_1, SLOT_MORTAR_2); + _controller.SummonCreatures(SLOT_RIFLEMAN_1, SLOT_RIFLEMAN_4); + } + } + } + + void SetData(uint32 type, uint32 data) OVERRIDE + { + if (type == ACTION_CLEAR_SLOT) + { + _controller.ClearSlot(PassengerSlots(data)); + if (data == SLOT_FREEZE_MAGE) + _events.ScheduleEvent(EVENT_SUMMON_MAGE, urand(30000, 33500)); + } + } + + void sGossipSelect(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/) OVERRIDE + { + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + me->GetTransport()->EnableMovement(true); + _events.SetPhase(PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_H_1, 5000, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_H_2, 16000, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_SUMMON_SKYBREAKER, 24600, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_H_3, 29600, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_H_4, 39200, 0, PHASE_INTRO); + } + + void DamageTaken(Unit* , uint32& damage) OVERRIDE + { + if (me->HealthBelowPctDamaged(65, damage) && !me->HasAura(SPELL_TASTE_OF_BLOOD)) + DoCast(me, SPELL_TASTE_OF_BLOOD, true); + + if (damage > me->GetHealth()) + damage = me->GetHealth() - 1; + } + + void UpdateAI(uint32 diff) OVERRIDE + { + if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO) && _instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_INTRO_H_1: + Talk(SAY_SAURFANG_INTRO_1); + break; + case EVENT_INTRO_H_2: + Talk(SAY_SAURFANG_INTRO_2); + break; + case EVENT_INTRO_SUMMON_SKYBREAKER: + sTransportMgr->CreateTransport(GO_THE_SKYBREAKER_H, 0, me->GetMap()); + break; + case EVENT_INTRO_H_3: + Talk(SAY_SAURFANG_INTRO_3); + break; + case EVENT_INTRO_H_4: + Talk(SAY_SAURFANG_INTRO_4); + break; + case EVENT_INTRO_H_5: + if (Creature* muradin = me->FindNearestCreature(NPC_IGB_MURADIN_BRONZEBEARD, 100.0f)) + muradin->AI()->Talk(SAY_MURADIN_INTRO_H); + break; + case EVENT_INTRO_H_6: + Talk(SAY_SAURFANG_INTRO_6); + break; + case EVENT_KEEP_PLAYER_IN_COMBAT: + if (_instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == IN_PROGRESS) + { + _instance->DoCastSpellOnPlayers(SPELL_LOCK_PLAYERS_AND_TAP_CHEST); + _events.ScheduleEvent(EVENT_KEEP_PLAYER_IN_COMBAT, urand(5000, 8000)); + } + break; + case EVENT_SUMMON_MAGE: + Talk(SAY_SAURFANG_MAGES); + _controller.SummonCreatures(SLOT_FREEZE_MAGE, SLOT_FREEZE_MAGE); + break; + case EVENT_ADDS: + Talk(SAY_SAURFANG_ENTER_SKYBREAKER); + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2); + _controller.SummonCreatures(SLOT_MARINE_1, Is25ManRaid() ? SLOT_MARINE_4 : SLOT_MARINE_2); + _controller.SummonCreatures(SLOT_SERGEANT_1, Is25ManRaid() ? SLOT_SERGEANT_2 : SLOT_SERGEANT_1); + if (Transport* orgrimsHammer = me->GetTransport()) + orgrimsHammer->SummonPassenger(NPC_TELEPORT_PORTAL, OrgrimsHammerTeleportPortal, TEMPSUMMON_TIMED_DESPAWN, NULL, 21000); + + if (GameObject* go = HashMapHolder::Find(_instance->GetData64(DATA_ICECROWN_GUNSHIP_BATTLE))) + if (Transport* skybreaker = go->ToTransport()) + skybreaker->SummonPassenger(NPC_TELEPORT_EXIT, SkybreakerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, NULL, 23000); + + _events.ScheduleEvent(EVENT_ADDS_BOARD_YELL, 6000); + _events.ScheduleEvent(EVENT_ADDS, 60000); + break; + case EVENT_ADDS_BOARD_YELL: + if (Creature* muradin = me->FindNearestCreature(NPC_IGB_MURADIN_BRONZEBEARD, 200.0f)) + muradin->AI()->Talk(SAY_MURADIN_BOARD); + break; + case EVENT_CHECK_RIFLEMAN: + if (_controller.SummonCreatures(SLOT_RIFLEMAN_1, Is25ManRaid() ? SLOT_RIFLEMAN_8 : SLOT_RIFLEMAN_4)) + { + if (_axethrowersYellCooldown < time(NULL)) + { + Talk(SAY_SAURFANG_AXETHROWERS); + _axethrowersYellCooldown = time(NULL) + 5; + } + } + _events.ScheduleEvent(EVENT_CHECK_RIFLEMAN, 1000); + break; + case EVENT_CHECK_MORTAR: + if (_controller.SummonCreatures(SLOT_MORTAR_1, Is25ManRaid() ? SLOT_MORTAR_4 : SLOT_MORTAR_2)) + { + if (_rocketeersYellCooldown < time(NULL)) + { + Talk(SAY_SAURFANG_ROCKETEERS); + _rocketeersYellCooldown = time(NULL) + 5; + } + } + _events.ScheduleEvent(EVENT_CHECK_MORTAR, 1000); + break; + case EVENT_CLEAVE: + DoCastVictim(SPELL_CLEAVE); + _events.ScheduleEvent(EVENT_CLEAVE, urand(2000, 10000)); + break; + default: + break; + } + } + + if (me->IsWithinMeleeRange(me->GetVictim())) + DoMeleeAttackIfReady(); + else if (me->isAttackReady()) + { + DoCastVictim(SPELL_RENDING_THROW); + me->resetAttackTimer(); + } + } + + bool CanAIAttack(Unit const* target) const OVERRIDE + { + return target->HasAura(SPELL_ON_ORGRIMS_HAMMER_DECK) || !target->IsControlledByPlayer(); + } + + private: + EventMap _events; + PassengerController _controller; + InstanceScript* _instance; + time_t _firstMageCooldown; + time_t _axethrowersYellCooldown; + time_t _rocketeersYellCooldown; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetIcecrownCitadelAI(creature); + } +}; + +class npc_muradin_bronzebeard_igb : public CreatureScript +{ + public: + npc_muradin_bronzebeard_igb() : CreatureScript("npc_muradin_bronzebeard_igb") { } + + struct npc_muradin_bronzebeard_igbAI : public ScriptedAI + { + npc_muradin_bronzebeard_igbAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + _controller.ResetSlots(ALLIANCE); + _controller.SetTransport(creature->GetTransport()); + me->setRegeneratingHealth(false); + me->m_CombatDistance = 70.0f; + } + + void InitializeAI() OVERRIDE + { + ScriptedAI::InitializeAI(); + + _events.Reset(); + _firstMageCooldown = time(NULL) + 60; + _riflemanYellCooldown = time_t(0); + _mortarYellCooldown = time_t(0); + } + + void EnterCombat(Unit* /*target*/) OVERRIDE + { + _events.SetPhase(PHASE_COMBAT); + DoCast(me, _instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE ? SPELL_FRIENDLY_BOSS_DAMAGE_MOD : SPELL_MELEE_TARGETING_ON_SKYBREAKER, true); + DoCast(me, SPELL_BATTLE_FURY, true); + _events.ScheduleEvent(EVENT_CLEAVE, urand(2000, 10000)); + } + + void EnterEvadeMode() OVERRIDE + { + if (!me->IsAlive()) + return; + + me->DeleteThreatList(); + me->CombatStop(true); + me->GetMotionMaster()->MoveTargetedHome(); + + Reset(); + } + + void DoAction(int32 action) OVERRIDE + { + if (action == ACTION_ENEMY_GUNSHIP_TALK) + { + if (Creature* muradin = me->FindNearestCreature(NPC_IGB_HIGH_OVERLORD_SAURFANG, 100.0f)) + muradin->AI()->DoAction(ACTION_SPAWN_ALL_ADDS); + + Talk(SAY_MURADIN_INTRO_6); + _events.ScheduleEvent(EVENT_INTRO_A_6, 5000); + _events.ScheduleEvent(EVENT_INTRO_A_7, 11000); + _events.ScheduleEvent(EVENT_KEEP_PLAYER_IN_COMBAT, 1); + + _instance->SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, IN_PROGRESS); + // Combat starts now + if (Creature* orgrimsHammer = me->FindNearestCreature(NPC_ORGRIMS_HAMMER, 100.0f)) + _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, orgrimsHammer, 1); + + if (Creature* skybreaker = me->FindNearestCreature(NPC_THE_SKYBREAKER, 100.0f)) + { + _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, skybreaker, 2); + skybreaker->CastSpell(skybreaker, SPELL_CHECK_FOR_PLAYERS, TRIGGERED_FULL_MASK); + } + + me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_ENCOUNTER); + } + else if (action == ACTION_SPAWN_MAGE) + { + time_t now = time(NULL); + if (_firstMageCooldown < now) + _events.ScheduleEvent(EVENT_SUMMON_MAGE, (now - _firstMageCooldown) * IN_MILLISECONDS); + else + _events.ScheduleEvent(EVENT_SUMMON_MAGE, 1); + } + else if (action == ACTION_SPAWN_ALL_ADDS) + { + _events.ScheduleEvent(EVENT_ADDS, 12000); + _events.ScheduleEvent(EVENT_CHECK_RIFLEMAN, 13000); + _events.ScheduleEvent(EVENT_CHECK_MORTAR, 13000); + if (Is25ManRaid()) + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MORTAR_4); + else + { + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2); + _controller.SummonCreatures(SLOT_MORTAR_1, SLOT_MORTAR_2); + _controller.SummonCreatures(SLOT_RIFLEMAN_1, SLOT_RIFLEMAN_4); + } + } + } + + void SetData(uint32 type, uint32 data) OVERRIDE + { + if (type == ACTION_CLEAR_SLOT) + { + _controller.ClearSlot(PassengerSlots(data)); + if (data == SLOT_FREEZE_MAGE) + _events.ScheduleEvent(EVENT_SUMMON_MAGE, urand(30000, 33500)); + } + } + + void sGossipSelect(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/) OVERRIDE + { + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + me->GetTransport()->EnableMovement(true); + _events.SetPhase(PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_A_1, 5000); + _events.ScheduleEvent(EVENT_INTRO_A_2, 10000, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_SUMMON_ORGRIMS_HAMMER, 28000, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_A_3, 33000, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_A_4, 39000, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_A_5, 45000, 0, PHASE_INTRO); + } + + void DamageTaken(Unit* , uint32& damage) OVERRIDE + { + if (me->HealthBelowPctDamaged(65, damage) && me->HasAura(SPELL_TASTE_OF_BLOOD)) + DoCast(me, SPELL_TASTE_OF_BLOOD, true); + + if (damage > me->GetHealth()) + damage = me->GetHealth() - 1; + } + + void UpdateAI(uint32 diff) OVERRIDE + { + if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO) && _instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_INTRO_A_1: + Talk(SAY_MURADIN_INTRO_1); + break; + case EVENT_INTRO_A_2: + Talk(SAY_MURADIN_INTRO_2); + break; + case EVENT_INTRO_SUMMON_ORGRIMS_HAMMER: + sTransportMgr->CreateTransport(GO_ORGRIMS_HAMMER_A, 0, me->GetMap()); + break; + case EVENT_INTRO_A_3: + Talk(SAY_MURADIN_INTRO_3); + break; + case EVENT_INTRO_A_4: + Talk(SAY_MURADIN_INTRO_4); + break; + case EVENT_INTRO_A_5: + Talk(SAY_MURADIN_INTRO_5); + break; + case EVENT_INTRO_A_6: + if (Creature* saurfang = me->FindNearestCreature(NPC_IGB_HIGH_OVERLORD_SAURFANG, 100.0f)) + saurfang->AI()->Talk(SAY_SAURFANG_INTRO_A); + break; + case EVENT_INTRO_A_7: + Talk(SAY_MURADIN_INTRO_7); + break; + case EVENT_KEEP_PLAYER_IN_COMBAT: + if (_instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == IN_PROGRESS) + { + _instance->DoCastSpellOnPlayers(SPELL_LOCK_PLAYERS_AND_TAP_CHEST); + _events.ScheduleEvent(EVENT_KEEP_PLAYER_IN_COMBAT, urand(5000, 8000)); + } + break; + case EVENT_SUMMON_MAGE: + Talk(SAY_MURADIN_SORCERERS); + _controller.SummonCreatures(SLOT_FREEZE_MAGE, SLOT_FREEZE_MAGE); + break; + case EVENT_ADDS: + Talk(SAY_MURADIN_ENTER_ORGRIMMS_HAMMER); + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2); + _controller.SummonCreatures(SLOT_MARINE_1, Is25ManRaid() ? SLOT_MARINE_4 : SLOT_MARINE_2); + _controller.SummonCreatures(SLOT_SERGEANT_1, Is25ManRaid() ? SLOT_SERGEANT_2 : SLOT_SERGEANT_1); + if (Transport* skybreaker = me->GetTransport()) + skybreaker->SummonPassenger(NPC_TELEPORT_PORTAL, SkybreakerTeleportPortal, TEMPSUMMON_TIMED_DESPAWN, NULL, 21000); + + if (GameObject* go = HashMapHolder::Find(_instance->GetData64(DATA_ICECROWN_GUNSHIP_BATTLE))) + if (Transport* orgrimsHammer = go->ToTransport()) + orgrimsHammer->SummonPassenger(NPC_TELEPORT_EXIT, OrgrimsHammerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, NULL, 23000); + + _events.ScheduleEvent(EVENT_ADDS_BOARD_YELL, 6000); + _events.ScheduleEvent(EVENT_ADDS, 60000); + break; + case EVENT_ADDS_BOARD_YELL: + if (Creature* saurfang = me->FindNearestCreature(NPC_IGB_HIGH_OVERLORD_SAURFANG, 200.0f)) + saurfang->AI()->Talk(SAY_SAURFANG_BOARD); + break; + case EVENT_CHECK_RIFLEMAN: + if (_controller.SummonCreatures(SLOT_RIFLEMAN_1, Is25ManRaid() ? SLOT_RIFLEMAN_8 : SLOT_RIFLEMAN_4)) + { + if (_riflemanYellCooldown < time(NULL)) + { + Talk(SAY_MURADIN_RIFLEMAN); + _riflemanYellCooldown = time(NULL) + 5; + } + } + _events.ScheduleEvent(EVENT_CHECK_RIFLEMAN, 1000); + break; + case EVENT_CHECK_MORTAR: + if (_controller.SummonCreatures(SLOT_MORTAR_1, Is25ManRaid() ? SLOT_MORTAR_4 : SLOT_MORTAR_2)) + { + if (_mortarYellCooldown < time(NULL)) + { + Talk(SAY_MURADIN_MORTAR); + _mortarYellCooldown = time(NULL) + 5; + } + } + _events.ScheduleEvent(EVENT_CHECK_MORTAR, 1000); + break; + case EVENT_CLEAVE: + DoCastVictim(SPELL_CLEAVE); + _events.ScheduleEvent(EVENT_CLEAVE, urand(2000, 10000)); + break; + default: + break; + } + } + + if (me->IsWithinMeleeRange(me->GetVictim())) + DoMeleeAttackIfReady(); + else if (me->isAttackReady()) + { + DoCastVictim(SPELL_RENDING_THROW); + me->resetAttackTimer(); + } + } + + bool CanAIAttack(Unit const* target) const OVERRIDE + { + return target->HasAura(SPELL_ON_SKYBREAKER_DECK) || !target->IsControlledByPlayer(); + } + + private: + EventMap _events; + PassengerController _controller; + InstanceScript* _instance; + time_t _firstMageCooldown; + time_t _riflemanYellCooldown; + time_t _mortarYellCooldown; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetIcecrownCitadelAI(creature); + } +}; + +class npc_zafod_boombox : public CreatureScript +{ + public: + npc_zafod_boombox() : CreatureScript("npc_zafod_boombox") { } + + struct npc_zafod_boomboxAI : public gunship_npc_AI + { + npc_zafod_boomboxAI(Creature* creature) : gunship_npc_AI(creature) + { + } + + void Reset() OVERRIDE + { + me->SetReactState(REACT_PASSIVE); + } + + void sGossipSelect(Player* player, uint32 /*sender*/, uint32 /*action*/) OVERRIDE + { + player->AddItem(ITEM_GOBLIN_ROCKET_PACK, 1); + player->PlayerTalkClass->SendCloseGossip(); + } + + void UpdateAI(uint32 /*diff*/) OVERRIDE + { + UpdateVictim(); + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetIcecrownCitadelAI(creature); + } +}; + +struct npc_gunship_boarding_addAI : public gunship_npc_AI +{ + npc_gunship_boarding_addAI(Creature* creature) : gunship_npc_AI(creature) + { + me->m_CombatDistance = 80.0f; + _usedDesperateResolve = false; + } + + void SetData(uint32 type, uint32 data) OVERRIDE + { + // detach from captain + if (type == ACTION_SET_SLOT) + { + SetSlotInfo(data); + + me->SetReactState(REACT_PASSIVE); + + me->m_Events.AddEvent(new DelayedMovementEvent(me, Slot->TargetPosition), me->m_Events.CalculateTime(3000 * (Index - SLOT_MARINE_1))); + + if (Creature* captain = me->FindNearestCreature(Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? NPC_IGB_MURADIN_BRONZEBEARD : NPC_IGB_HIGH_OVERLORD_SAURFANG, 200.0f)) + captain->AI()->SetData(ACTION_CLEAR_SLOT, Index); + } + } + + void MovementInform(uint32 type, uint32 pointId) OVERRIDE + { + if (type != POINT_MOTION_TYPE) + return; + + if (pointId == EVENT_CHARGE_PREPATH && Slot) + { + Position const& otherTransportPos = Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? OrgrimsHammerTeleportExit : SkybreakerTeleportExit; + float x, y, z, o; + otherTransportPos.GetPosition(x, y, z, o); + + Transport* myTransport = me->GetTransport(); + if (!myTransport) + return; + + if (GameObject* go = HashMapHolder::Find(Instance->GetData64(DATA_ICECROWN_GUNSHIP_BATTLE))) + if (Transport* destTransport = go->ToTransport()) + destTransport->CalculatePassengerPosition(x, y, z, &o); + + float angle = frand(0, M_PI * 2.0f); + x += 2.0f * std::cos(angle); + y += 2.0f * std::sin(angle); + + me->SetHomePosition(x, y, z, o); + myTransport->CalculatePassengerOffset(x, y, z, &o); + me->SetTransportHomePosition(x, y, z, o); + + me->m_Events.AddEvent(new BattleExperienceEvent(me), me->m_Events.CalculateTime(BattleExperienceEvent::ExperiencedTimes[0])); + DoCast(me, SPELL_BATTLE_EXPERIENCE, true); + DoCast(me, SPELL_TELEPORT_TO_ENEMY_SHIP, true); + DoCast(me, Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_MELEE_TARGETING_ON_ORGRIMS_HAMMER : SPELL_MELEE_TARGETING_ON_SKYBREAKER, true); + me->_AddCreatureSpellCooldown(BurningPitchId, time(NULL) + 3); + + std::list players; + Trinity::UnitAuraCheck check(true, Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_ON_ORGRIMS_HAMMER_DECK : SPELL_ON_SKYBREAKER_DECK); + Trinity::PlayerListSearcher searcher(me, players, check); + me->VisitNearbyWorldObject(200.0f, searcher); + + players.remove_if([this](Player* player) + { + return !me->_IsTargetAcceptable(player) || !me->CanStartAttack(player, true); + }); + + if (!players.empty()) + { + players.sort(Trinity::ObjectDistanceOrderPred(me)); + for (std::list::iterator itr = players.begin(); itr != players.end(); ++itr) + me->AddThreat(*itr, 1.0f); + + AttackStart(players.front()); + } + + me->SetReactState(REACT_AGGRESSIVE); + } + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE + { + if (_usedDesperateResolve) + return; + + if (!me->HealthBelowPctDamaged(25, damage)) + return; + + _usedDesperateResolve = true; + DoCast(me, SPELL_DESPERATE_RESOLVE, true); + } + + void UpdateAI(uint32 /*diff*/) OVERRIDE + { + if (!SelectVictim()) + { + TriggerBurningPitch(); + return; + } + + if (!HasAttackablePlayerNearby()) + TriggerBurningPitch(); + + DoMeleeAttackIfReady(); + } + + bool CanAIAttack(Unit const* target) const OVERRIDE + { + uint32 spellId = SPELL_ON_SKYBREAKER_DECK; + uint32 creatureEntry = NPC_IGB_MURADIN_BRONZEBEARD; + if (Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE) + { + spellId = SPELL_ON_ORGRIMS_HAMMER_DECK; + creatureEntry = NPC_IGB_HIGH_OVERLORD_SAURFANG; + } + + return target->HasAura(spellId) || target->GetEntry() == creatureEntry; + } + + bool HasAttackablePlayerNearby() + { + std::list players; + Trinity::UnitAuraCheck check(true, Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_ON_ORGRIMS_HAMMER_DECK : SPELL_ON_SKYBREAKER_DECK); + Trinity::PlayerListSearcher searcher(me, players, check); + me->VisitNearbyWorldObject(200.0f, searcher); + + players.remove_if([this](Player* player) + { + return !me->_IsTargetAcceptable(player) || !me->CanStartAttack(player, true); + }); + + return !players.empty(); + } + +private: + bool _usedDesperateResolve; +}; + +class npc_gunship_boarding_leader : public CreatureScript +{ + public: + npc_gunship_boarding_leader() : CreatureScript("npc_gunship_boarding_leader") { } + + struct npc_gunship_boarding_leaderAI : public npc_gunship_boarding_addAI + { + npc_gunship_boarding_leaderAI(Creature* creature) : npc_gunship_boarding_addAI(creature) + { + } + + void EnterCombat(Unit* target) OVERRIDE + { + npc_gunship_boarding_addAI::EnterCombat(target); + _events.ScheduleEvent(EVENT_BLADESTORM, urand(13000, 18000)); + _events.ScheduleEvent(EVENT_WOUNDING_STRIKE, urand(8000, 10000)); + } + + void UpdateAI(uint32 diff) OVERRIDE + { + if (!SelectVictim()) + { + TriggerBurningPitch(); + return; + } + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasAura(SPELL_BLADESTORM)) + return; + + if (!HasAttackablePlayerNearby()) + TriggerBurningPitch(); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_BLADESTORM: + DoCastAOE(SPELL_BLADESTORM); + _events.ScheduleEvent(EVENT_BLADESTORM, urand(25000, 30000)); + break; + case EVENT_WOUNDING_STRIKE: + DoCastVictim(SPELL_WOUNDING_STRIKE); + _events.ScheduleEvent(EVENT_WOUNDING_STRIKE, urand(9000, 13000)); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetIcecrownCitadelAI(creature); + } +}; + +class npc_gunship_boarding_add : public CreatureScript +{ + public: + npc_gunship_boarding_add() : CreatureScript("npc_gunship_boarding_add") { } + + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetIcecrownCitadelAI(creature); + } +}; + +class npc_gunship_gunner : public CreatureScript +{ + public: + npc_gunship_gunner() : CreatureScript("npc_gunship_gunner") { } + + struct npc_gunship_gunnerAI : public gunship_npc_AI + { + npc_gunship_gunnerAI(Creature* creature) : gunship_npc_AI(creature) + { + creature->m_CombatDistance = 200.0f; + } + + void AttackStart(Unit* target) OVERRIDE + { + me->Attack(target, false); + } + + void MovementInform(uint32 type, uint32 pointId) OVERRIDE + { + gunship_npc_AI::MovementInform(type, pointId); + if (type == POINT_MOTION_TYPE && pointId == EVENT_CHARGE_PREPATH) + me->SetControlled(true, UNIT_STATE_ROOT); + } + + void UpdateAI(uint32 /*diff*/) OVERRIDE + { + if (!SelectVictim()) + { + TriggerBurningPitch(); + return; + } + + DoSpellAttackIfReady(me->GetEntry() == NPC_SKYBREAKER_RIFLEMAN ? SPELL_SHOOT : SPELL_HURL_AXE); + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetIcecrownCitadelAI(creature); + } +}; + +class npc_gunship_rocketeer : public CreatureScript +{ + public: + npc_gunship_rocketeer() : CreatureScript("npc_gunship_rocketeer") { } + + struct npc_gunship_rocketeerAI : public gunship_npc_AI + { + npc_gunship_rocketeerAI(Creature* creature) : gunship_npc_AI(creature) + { + creature->m_CombatDistance = 200.0f; + } + + void MovementInform(uint32 type, uint32 pointId) OVERRIDE + { + gunship_npc_AI::MovementInform(type, pointId); + if (type == POINT_MOTION_TYPE && pointId == EVENT_CHARGE_PREPATH) + me->SetControlled(true, UNIT_STATE_ROOT); + } + + void UpdateAI(uint32 /*diff*/) OVERRIDE + { + if (!SelectVictim()) + return; + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + uint32 spellId = me->GetEntry() == NPC_SKYBREAKER_MORTAR_SOLDIER ? SPELL_ROCKET_ARTILLERY_A : SPELL_ROCKET_ARTILLERY_H; + if (me->HasSpellCooldown(spellId)) + return; + + DoCastAOE(spellId, true); + me->_AddCreatureSpellCooldown(spellId, time(NULL) + 9); + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetIcecrownCitadelAI(creature); + } +}; + +class npc_gunship_mage : public CreatureScript +{ + public: + npc_gunship_mage() : CreatureScript("npc_gunship_mage") { } + + struct npc_gunship_mageAI : public gunship_npc_AI + { + npc_gunship_mageAI(Creature* creature) : gunship_npc_AI(creature) + { + me->SetReactState(REACT_PASSIVE); + } + + void EnterEvadeMode() OVERRIDE + { + ScriptedAI::EnterEvadeMode(); + } + + void MovementInform(uint32 type, uint32 pointId) OVERRIDE + { + if (type != POINT_MOTION_TYPE) + return; + + if (pointId == EVENT_CHARGE_PREPATH && Slot) + { + SlotInfo const* slots = Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SkybreakerSlotInfo : OrgrimsHammerSlotInfo; + me->SetFacingTo(slots[Index].TargetPosition.GetOrientation()); + switch (Index) + { + case SLOT_FREEZE_MAGE: + DoCastAOE(SPELL_BELOW_ZERO); + break; + case SLOT_MAGE_1: + case SLOT_MAGE_2: + DoCastAOE(SPELL_SHADOW_CHANNELING); + break; + default: + break; + } + + me->SetControlled(true, UNIT_STATE_ROOT); + } + } + + void UpdateAI(uint32 /*diff*/) OVERRIDE + { + UpdateVictim(); + } + + bool CanAIAttack(Unit const* /*target*/) const OVERRIDE + { + return true; + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetIcecrownCitadelAI(creature); + } +}; + +/** @HACK This AI only resets MOVEMENTFLAG_ROOT on the vehicle. + Currently the core always removes MOVEMENTFLAG_ROOT sent from client packets to prevent cheaters from freezing clients of other players + but it actually is a valid flag - needs more research to fix both freezes and keep the flag as is (see WorldSession::ReadMovementInfo) + +Example packet: +ClientToServer: CMSG_FORCE_MOVE_ROOT_ACK (0x00E9) Length: 67 ConnectionIndex: 0 Time: 03/04/2010 03:57:55.000 Number: 471326 +Guid: +Movement Counter: 80 +Movement Flags: OnTransport, Root (2560) +Extra Movement Flags: None (0) +Time: 52291611 +Position: X: -396.0302 Y: 2482.906 Z: 249.86 +Orientation: 1.468665 +Transport GUID: Full: 0x1FC0000000000460 Type: MOTransport Low: 1120 +Transport Position: X: -6.152398 Y: -23.49037 Z: 21.64464 O: 4.827727 +Transport Time: 9926 +Transport Seat: 255 +Fall Time: 824 +*/ +class npc_gunship_cannon : public CreatureScript +{ + public: + npc_gunship_cannon() : CreatureScript("npc_gunship_cannon") { } + + struct npc_gunship_cannonAI : public PassiveAI + { + npc_gunship_cannonAI(Creature* creature) : PassiveAI(creature) + { + } + + void OnCharmed(bool /*apply*/) OVERRIDE { } + + void PassengerBoarded(Unit* /*passenger*/, int8 /*seat*/, bool apply) OVERRIDE + { + if (!apply) + { + me->SetControlled(false, UNIT_STATE_ROOT); + me->SetControlled(true, UNIT_STATE_ROOT); + } + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new npc_gunship_cannonAI(creature); + } +}; + +class spell_igb_rocket_pack : public SpellScriptLoader +{ + public: + spell_igb_rocket_pack() : SpellScriptLoader("spell_igb_rocket_pack") { } + + class spell_igb_rocket_pack_AuraScript : public AuraScript + { + PrepareAuraScript(spell_igb_rocket_pack_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE + { + if (!sSpellMgr->GetSpellInfo(SPELL_ROCKET_PACK_DAMAGE) || + !sSpellMgr->GetSpellInfo(SPELL_ROCKET_BURST)) + return false; + + return true; + } + + void HandlePeriodic(AuraEffect const* /*aurEff*/) + { + if (GetTarget()->movespline->Finalized()) + Remove(AURA_REMOVE_BY_EXPIRE); + } + + void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + SpellInfo const* damageInfo = sSpellMgr->GetSpellInfo(SPELL_ROCKET_PACK_DAMAGE); + GetTarget()->CastCustomSpell(SPELL_ROCKET_PACK_DAMAGE, SPELLVALUE_BASE_POINT0, 2 * (damageInfo->Effects[EFFECT_0].CalcValue() + aurEff->GetTickNumber() * aurEff->GetAmplitude()), NULL, TRIGGERED_FULL_MASK); + GetTarget()->CastSpell(NULL, SPELL_ROCKET_BURST, TRIGGERED_FULL_MASK); + } + + void Register() OVERRIDE + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_igb_rocket_pack_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + OnEffectRemove += AuraEffectRemoveFn(spell_igb_rocket_pack_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_igb_rocket_pack_AuraScript(); + } +}; + +class spell_igb_rocket_pack_useable : public SpellScriptLoader +{ + public: + spell_igb_rocket_pack_useable() : SpellScriptLoader("spell_igb_rocket_pack_useable") { } + + class spell_igb_rocket_pack_useable_AuraScript : public AuraScript + { + PrepareAuraScript(spell_igb_rocket_pack_useable_AuraScript); + + bool Load() + { + return GetOwner()->GetInstanceScript(); + } + + bool CheckAreaTarget(Unit* target) + { + return target->GetTypeId() == TYPEID_PLAYER && GetOwner()->GetInstanceScript()->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != DONE; + } + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* owner = GetOwner()->ToCreature()) + if (Player* target = GetTarget()->ToPlayer()) + if (target->HasItemCount(ITEM_GOBLIN_ROCKET_PACK, 1)) + sCreatureTextMgr->SendChat(owner, SAY_ZAFOD_ROCKET_PACK_ACTIVE, target, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, target); + } + + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* owner = GetOwner()->ToCreature()) + if (Player* target = GetTarget()->ToPlayer()) + if (target->HasItemCount(ITEM_GOBLIN_ROCKET_PACK, 1)) + sCreatureTextMgr->SendChat(owner, SAY_ZAFOD_ROCKET_PACK_DISABLED, target, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, target); + } + + void Register() OVERRIDE + { + DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_igb_rocket_pack_useable_AuraScript::CheckAreaTarget); + AfterEffectApply += AuraEffectApplyFn(spell_igb_rocket_pack_useable_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_igb_rocket_pack_useable_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_igb_rocket_pack_useable_AuraScript(); + } +}; + +class spell_igb_on_gunship_deck : public SpellScriptLoader +{ + public: + spell_igb_on_gunship_deck() : SpellScriptLoader("spell_igb_on_gunship_deck") { } + + class spell_igb_on_gunship_deck_AuraScript : public AuraScript + { + PrepareAuraScript(spell_igb_on_gunship_deck_AuraScript); + + bool Load() OVERRIDE + { + if (InstanceScript* instance = GetOwner()->GetInstanceScript()) + _teamInInstance = instance->GetData(DATA_TEAM_IN_INSTANCE); + else + _teamInInstance = 0; + return true; + } + + bool CheckAreaTarget(Unit* unit) + { + return unit->GetTypeId() == TYPEID_PLAYER; + } + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetSpellInfo()->Id == uint32(_teamInInstance == HORDE ? SPELL_ON_SKYBREAKER_DECK : SPELL_ON_ORGRIMS_HAMMER_DECK)) + if (Creature* gunship = GetOwner()->FindNearestCreature(_teamInInstance == HORDE ? NPC_ORGRIMS_HAMMER : NPC_THE_SKYBREAKER, 200.0f)) + gunship->AI()->SetGUID(GetTarget()->GetGUID(), ACTION_SHIP_VISITS); + } + + void Register() OVERRIDE + { + DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_igb_on_gunship_deck_AuraScript::CheckAreaTarget); + AfterEffectApply += AuraEffectApplyFn(spell_igb_on_gunship_deck_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + + uint32 _teamInInstance; + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_igb_on_gunship_deck_AuraScript(); + } +}; + +class spell_igb_periodic_trigger_with_power_cost : public SpellScriptLoader +{ + public: + spell_igb_periodic_trigger_with_power_cost() : SpellScriptLoader("spell_igb_periodic_trigger_with_power_cost") { } + + class spell_igb_periodic_trigger_with_power_cost_AuraScript : public AuraScript + { + PrepareAuraScript(spell_igb_periodic_trigger_with_power_cost_AuraScript); + + void HandlePeriodicTick(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_POWER_AND_REAGENT_COST)); + } + + void Register() OVERRIDE + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_igb_periodic_trigger_with_power_cost_AuraScript::HandlePeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_igb_periodic_trigger_with_power_cost_AuraScript(); + } +}; + +class spell_igb_cannon_blast : public SpellScriptLoader +{ + public: + spell_igb_cannon_blast() : SpellScriptLoader("spell_igb_cannon_blast") { } + + class spell_igb_cannon_blast_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_cannon_blast_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void CheckEnergy() + { + if (GetCaster()->GetPower(POWER_ENERGY) >= 100) + { + GetCaster()->CastSpell(GetCaster(), SPELL_OVERHEAT, TRIGGERED_FULL_MASK); + if (Vehicle* vehicle = GetCaster()->GetVehicleKit()) + if (Unit* passenger = vehicle->GetPassenger(0)) + sCreatureTextMgr->SendChat(GetCaster()->ToCreature(), SAY_OVERHEAT, passenger); + } + } + + void Register() OVERRIDE + { + AfterHit += SpellHitFn(spell_igb_cannon_blast_SpellScript::CheckEnergy); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_cannon_blast_SpellScript(); + } +}; + +class spell_igb_incinerating_blast : public SpellScriptLoader +{ + public: + spell_igb_incinerating_blast() : SpellScriptLoader("spell_igb_incinerating_blast") { } + + class spell_igb_incinerating_blast_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_incinerating_blast_SpellScript); + + void StoreEnergy() + { + _energyLeft = GetCaster()->GetPower(POWER_ENERGY) - 10; + } + + void RemoveEnergy() + { + GetCaster()->SetPower(POWER_ENERGY, 0); + } + + void CalculateDamage(SpellEffIndex /*effIndex*/) + { + SetEffectValue(GetEffectValue() + _energyLeft * _energyLeft * 8); + } + + void Register() OVERRIDE + { + OnCast += SpellCastFn(spell_igb_incinerating_blast_SpellScript::StoreEnergy); + AfterCast += SpellCastFn(spell_igb_incinerating_blast_SpellScript::RemoveEnergy); + OnEffectLaunchTarget += SpellEffectFn(spell_igb_incinerating_blast_SpellScript::CalculateDamage, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE); + } + + uint32 _energyLeft; + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_incinerating_blast_SpellScript(); + } +}; + +class spell_igb_overheat : public SpellScriptLoader +{ + public: + spell_igb_overheat() : SpellScriptLoader("spell_igb_overheat") { } + + class spell_igb_overheat_AuraScript : public AuraScript + { + PrepareAuraScript(spell_igb_overheat_AuraScript); + + bool Load() OVERRIDE + { + if (GetAura()->GetType() != UNIT_AURA_TYPE) + return false; + return GetUnitOwner()->IsVehicle(); + } + + void SendClientControl(uint8 value) + { + if (Vehicle* vehicle = GetUnitOwner()->GetVehicleKit()) + { + if (Unit* passenger = vehicle->GetPassenger(0)) + { + if (Player* player = passenger->ToPlayer()) + { + WorldPacket data(SMSG_CLIENT_CONTROL_UPDATE, GetUnitOwner()->GetPackGUID().size() + 1); + data.append(GetUnitOwner()->GetPackGUID()); + data << uint8(value); + player->GetSession()->SendPacket(&data); + } + } + } + } + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + SendClientControl(0); + } + + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + SendClientControl(1); + } + + void Register() OVERRIDE + { + AfterEffectApply += AuraEffectApplyFn(spell_igb_overheat_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_igb_overheat_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_igb_overheat_AuraScript(); + } +}; + +class spell_igb_below_zero : public SpellScriptLoader +{ + public: + spell_igb_below_zero() : SpellScriptLoader("spell_igb_below_zero") { } + + class spell_igb_below_zero_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_below_zero_SpellScript); + + void RemovePassengers() + { + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_EJECT_ALL_PASSENGERS_BELOW_ZERO, TRIGGERED_FULL_MASK); + } + + void Register() OVERRIDE + { + BeforeHit += SpellHitFn(spell_igb_below_zero_SpellScript::RemovePassengers); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_below_zero_SpellScript(); + } +}; + +class spell_igb_teleport_to_enemy_ship : public SpellScriptLoader +{ + public: + spell_igb_teleport_to_enemy_ship() : SpellScriptLoader("spell_igb_teleport_to_enemy_ship") { } + + class spell_igb_teleport_to_enemy_ship_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_teleport_to_enemy_ship_SpellScript); + + void RelocateTransportOffset(SpellEffIndex /*effIndex*/) + { + WorldLocation const* dest = GetHitDest(); + Unit* target = GetHitUnit(); + if (!dest || !target || !target->GetTransport()) + return; + + float x, y, z, o; + dest->GetPosition(x, y, z, o); + target->GetTransport()->CalculatePassengerOffset(x, y, z, &o); + target->m_movementInfo.transport.pos.Relocate(x, y, z, o); + } + + void Register() OVERRIDE + { + OnEffectHitTarget += SpellEffectFn(spell_igb_teleport_to_enemy_ship_SpellScript::RelocateTransportOffset, EFFECT_0, SPELL_EFFECT_TELEPORT_UNITS); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_teleport_to_enemy_ship_SpellScript(); + } +}; + +class spell_igb_burning_pitch_selector : public SpellScriptLoader +{ + public: + spell_igb_burning_pitch_selector() : SpellScriptLoader("spell_igb_burning_pitch_selector") { } + + class spell_igb_burning_pitch_selector_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_burning_pitch_selector_SpellScript); + + void FilterTargets(std::list& targets) + { + uint32 team = HORDE; + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + team = instance->GetData(DATA_TEAM_IN_INSTANCE); + + targets.remove_if([team](WorldObject* target) -> bool + { + if (Transport* transport = target->GetTransport()) + return transport->GetEntry() != uint32(team == HORDE ? GO_ORGRIMS_HAMMER_H : GO_THE_SKYBREAKER_A); + return true; + }); + + if (!targets.empty()) + { + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + } + + void HandleDummy(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), TRIGGERED_NONE); + } + + void Register() OVERRIDE + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_igb_burning_pitch_selector_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnEffectHitTarget += SpellEffectFn(spell_igb_burning_pitch_selector_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_burning_pitch_selector_SpellScript(); + } +}; + +class spell_igb_burning_pitch : public SpellScriptLoader +{ + public: + spell_igb_burning_pitch() : SpellScriptLoader("spell_igb_burning_pitch") { } + + class spell_igb_burning_pitch_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_burning_pitch_SpellScript); + + void HandleDummy(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->CastCustomSpell(uint32(GetEffectValue()), SPELLVALUE_BASE_POINT0, 8000, NULL, TRIGGERED_FULL_MASK); + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_BURNING_PITCH, TRIGGERED_FULL_MASK); + } + + void Register() OVERRIDE + { + OnEffectHitTarget += SpellEffectFn(spell_igb_burning_pitch_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_burning_pitch_SpellScript(); + } +}; + +class spell_igb_rocket_artillery : public SpellScriptLoader +{ + public: + spell_igb_rocket_artillery() : SpellScriptLoader("spell_igb_rocket_artillery") { } + + class spell_igb_rocket_artillery_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_rocket_artillery_SpellScript); + + void SelectRandomTarget(std::list& targets) + { + if (!targets.empty()) + { + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), TRIGGERED_NONE); + } + + void Register() OVERRIDE + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_igb_rocket_artillery_SpellScript::SelectRandomTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_igb_rocket_artillery_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_rocket_artillery_SpellScript(); + } +}; + +class spell_igb_rocket_artillery_explosion : public SpellScriptLoader +{ + public: + spell_igb_rocket_artillery_explosion() : SpellScriptLoader("spell_igb_rocket_artillery_explosion") { } + + class spell_igb_rocket_artillery_explosion_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_rocket_artillery_explosion_SpellScript); + + void DamageGunship(SpellEffIndex /*effIndex*/) + { + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + GetCaster()->CastCustomSpell(instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_BURNING_PITCH_DAMAGE_A : SPELL_BURNING_PITCH_DAMAGE_H, SPELLVALUE_BASE_POINT0, 5000, NULL, TRIGGERED_FULL_MASK); + } + + void Register() OVERRIDE + { + OnEffectHit += SpellEffectFn(spell_igb_rocket_artillery_explosion_SpellScript::DamageGunship, EFFECT_0, SPELL_EFFECT_TRIGGER_MISSILE); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_rocket_artillery_explosion_SpellScript(); + } +}; + +class spell_igb_gunship_fall_teleport : public SpellScriptLoader +{ + public: + spell_igb_gunship_fall_teleport() : SpellScriptLoader("spell_igb_gunship_fall_teleport") { } + + class spell_igb_gunship_fall_teleport_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_gunship_fall_teleport_SpellScript); + + bool Load() + { + return GetCaster()->GetInstanceScript(); + } + + void SelectTransport(WorldObject*& target) + { + if (InstanceScript* instance = target->GetInstanceScript()) + target = HashMapHolder::Find(instance->GetData64(DATA_ICECROWN_GUNSHIP_BATTLE)); + } + + void RelocateDest(SpellEffIndex /*effIndex*/) + { + if (GetCaster()->GetInstanceScript()->GetData(DATA_TEAM_IN_INSTANCE) == HORDE) + GetHitDest()->RelocateOffset({ 0.0f, 0.0f, 36.0f, 0.0f }); + else + GetHitDest()->RelocateOffset({ 0.0f, 0.0f, 21.0f, 0.0f }); + } + + void Register() OVERRIDE + { + OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_igb_gunship_fall_teleport_SpellScript::SelectTransport, EFFECT_0, TARGET_DEST_NEARBY_ENTRY); + OnEffectLaunch += SpellEffectFn(spell_igb_gunship_fall_teleport_SpellScript::RelocateDest, EFFECT_0, SPELL_EFFECT_TELEPORT_UNITS); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_gunship_fall_teleport_SpellScript(); + } +}; + +class spell_igb_check_for_players : public SpellScriptLoader +{ + public: + spell_igb_check_for_players() : SpellScriptLoader("spell_igb_check_for_players") { } + + class spell_igb_check_for_players_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_check_for_players_SpellScript); + + bool Load() OVERRIDE + { + _playerCount = 0; + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void CountTargets(std::list& targets) + { + _playerCount = targets.size(); + } + + void TriggerWipe() + { + if (!_playerCount) + GetCaster()->ToCreature()->AI()->JustDied(NULL); + } + + void TeleportPlayer(SpellEffIndex /*effIndex*/) + { + if (GetHitUnit()->GetPositionZ() < GetCaster()->GetPositionZ() - 10.0f) + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_GUNSHIP_FALL_TELEPORT, TRIGGERED_FULL_MASK); + } + + void Register() OVERRIDE + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_igb_check_for_players_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + AfterCast += SpellCastFn(spell_igb_check_for_players_SpellScript::TriggerWipe); + OnEffectHitTarget += SpellEffectFn(spell_igb_check_for_players_SpellScript::TeleportPlayer, EFFECT_0, SPELL_EFFECT_DUMMY); + } + + uint32 _playerCount; + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_check_for_players_SpellScript(); + } +}; + +class spell_igb_teleport_players_on_victory : public SpellScriptLoader +{ + public: + spell_igb_teleport_players_on_victory() : SpellScriptLoader("spell_igb_teleport_players_on_victory") { } + + class spell_igb_teleport_players_on_victory_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_teleport_players_on_victory_SpellScript); + + bool Load() OVERRIDE + { + return GetCaster()->GetInstanceScript(); + } + + void FilterTargets(std::list& targets) + { + InstanceScript* instance = GetCaster()->GetInstanceScript(); + targets.remove_if([instance](WorldObject* target) -> bool + { + return target->GetTransGUID() != instance->GetData64(DATA_ENEMY_GUNSHIP); + }); + } + + void Register() OVERRIDE + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_igb_teleport_players_on_victory_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_teleport_players_on_victory_SpellScript(); + } +}; + +class achievement_im_on_a_boat : public AchievementCriteriaScript +{ + public: + achievement_im_on_a_boat() : AchievementCriteriaScript("achievement_im_on_a_boat") { } + + bool OnCheck(Player* /*source*/, Unit* target) OVERRIDE + { + return target->GetAI() && target->GetAI()->GetData(ACTION_SHIP_VISITS) <= 2; + } +}; + +void AddSC_boss_icecrown_gunship_battle() +{ + new npc_gunship(); + new npc_high_overlord_saurfang_igb(); + new npc_muradin_bronzebeard_igb(); + new npc_zafod_boombox(); + new npc_gunship_boarding_leader(); + new npc_gunship_boarding_add(); + new npc_gunship_gunner(); + new npc_gunship_rocketeer(); + new npc_gunship_mage(); + new npc_gunship_cannon(); + new spell_igb_rocket_pack(); + new spell_igb_rocket_pack_useable(); + new spell_igb_on_gunship_deck(); + new spell_igb_periodic_trigger_with_power_cost(); + new spell_igb_cannon_blast(); + new spell_igb_incinerating_blast(); + new spell_igb_overheat(); + new spell_igb_below_zero(); + new spell_igb_teleport_to_enemy_ship(); + new spell_igb_burning_pitch_selector(); + new spell_igb_burning_pitch(); + new spell_igb_rocket_artillery(); + new spell_igb_rocket_artillery_explosion(); + new spell_igb_gunship_fall_teleport(); + new spell_igb_check_for_players(); + new spell_igb_teleport_players_on_victory(); + new achievement_im_on_a_boat(); +} diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp index b76e217fbf5..0d262110b5f 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -2570,38 +2570,6 @@ class spell_the_lich_king_valkyr_target_search : public SpellScriptLoader } }; -class spell_the_lich_king_eject_all_passengers : public SpellScriptLoader -{ - public: - spell_the_lich_king_eject_all_passengers() : SpellScriptLoader("spell_the_lich_king_eject_all_passengers") { } - - class spell_the_lich_king_eject_all_passengers_SpellScript : public SpellScript - { - PrepareSpellScript(spell_the_lich_king_eject_all_passengers_SpellScript); - - bool Load() OVERRIDE - { - return GetCaster()->IsVehicle(); - } - - void HandleDummy(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - GetCaster()->GetVehicleKit()->RemoveAllPassengers(); - } - - void Register() OVERRIDE - { - OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_eject_all_passengers_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const OVERRIDE - { - return new spell_the_lich_king_eject_all_passengers_SpellScript(); - } -}; - class spell_the_lich_king_cast_back_to_caster : public SpellScriptLoader { public: @@ -3234,7 +3202,6 @@ void AddSC_boss_the_lich_king() new spell_the_lich_king_summon_into_air(); new spell_the_lich_king_soul_reaper(); new spell_the_lich_king_valkyr_target_search(); - new spell_the_lich_king_eject_all_passengers(); new spell_the_lich_king_cast_back_to_caster(); new spell_the_lich_king_life_siphon(); new spell_the_lich_king_vile_spirits(); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h index 56a8a46811c..ba64107e618 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h @@ -76,7 +76,7 @@ enum DataTypes // Encounter States/Boss GUIDs DATA_LORD_MARROWGAR = 0, DATA_LADY_DEATHWHISPER = 1, - DATA_GUNSHIP_EVENT = 2, + DATA_ICECROWN_GUNSHIP_BATTLE = 2, DATA_DEATHBRINGER_SAURFANG = 3, DATA_FESTERGUT = 4, DATA_ROTFACE = 5, @@ -116,6 +116,7 @@ enum DataTypes DATA_HIGHLORD_TIRION_FORDRING = 37, DATA_ARTHAS_PLATFORM = 38, DATA_TERENAS_MENETHIL = 39, + DATA_ENEMY_GUNSHIP = 40 }; enum CreaturesIds @@ -169,6 +170,33 @@ enum CreaturesIds NPC_REANIMATED_ADHERENT = 38010, NPC_VENGEFUL_SHADE = 38222, + // Icecrown Gunship Battle + NPC_MARTYR_STALKER_IGB_SAURFANG = 38569, + NPC_ALLIANCE_GUNSHIP_CANNON = 36838, + NPC_HORDE_GUNSHIP_CANNON = 36839, + NPC_SKYBREAKER_DECKHAND = 36970, + NPC_ORGRIMS_HAMMER_CREW = 36971, + NPC_IGB_HIGH_OVERLORD_SAURFANG = 36939, + NPC_IGB_MURADIN_BRONZEBEARD = 36948, + NPC_THE_SKYBREAKER = 37540, + NPC_ORGRIMS_HAMMER = 37215, + NPC_GUNSHIP_HULL = 37547, + NPC_TELEPORT_PORTAL = 37227, + NPC_TELEPORT_EXIT = 37488, + NPC_SKYBREAKER_SORCERER = 37116, + NPC_SKYBREAKER_RIFLEMAN = 36969, + NPC_SKYBREAKER_MORTAR_SOLDIER = 36978, + NPC_SKYBREAKER_MARINE = 36950, + NPC_SKYBREAKER_SERGEANT = 36961, + NPC_KOR_KRON_BATTLE_MAGE = 37117, + NPC_KOR_KRON_AXETHROWER = 36968, + NPC_KOR_KRON_ROCKETEER = 36982, + NPC_KOR_KRON_REAVER = 36957, + NPC_KOR_KRON_SERGEANT = 36960, + NPC_ZAFOD_BOOMBOX = 37184, + NPC_HIGH_CAPTAIN_JUSTIN_BARTLETT = 37182, + NPC_SKY_REAVER_KORM_BLACKSCAR = 37833, + // Deathbringer Saurfang NPC_DEATHBRINGER_SAURFANG = 37813, NPC_BLOOD_BEAST = 38508, @@ -305,6 +333,22 @@ enum GameObjectsIds GO_ORATORY_OF_THE_DAMNED_ENTRANCE = 201563, GO_LADY_DEATHWHISPER_ELEVATOR = 202220, + // Icecrown Gunship Battle - Horde raid + GO_ORGRIMS_HAMMER_H = 201812, + GO_THE_SKYBREAKER_H = 201811, + GO_GUNSHIP_ARMORY_H_10N = 202178, + GO_GUNSHIP_ARMORY_H_25N = 202180, + GO_GUNSHIP_ARMORY_H_10H = 202177, + GO_GUNSHIP_ARMORY_H_25H = 202179, + + // Icecrown Gunship Battle - Alliance raid + GO_ORGRIMS_HAMMER_A = 201581, + GO_THE_SKYBREAKER_A = 201580, + GO_GUNSHIP_ARMORY_A_10N = 201873, + GO_GUNSHIP_ARMORY_A_25N = 201874, + GO_GUNSHIP_ARMORY_A_10H = 201872, + GO_GUNSHIP_ARMORY_A_25H = 201875, + // Deathbringer Saurfang GO_SAURFANG_S_DOOR = 201825, GO_DEATHBRINGER_S_CACHE_10N = 202239, @@ -408,6 +452,9 @@ enum AchievementCriteriaIds enum SharedActions { + // Icecrown Gunship Battle + ACTION_ENEMY_GUNSHIP_TALK = -369390, + // Festergut ACTION_FESTERGUT_COMBAT = -366260, ACTION_FESTERGUT_GAS = -366261, @@ -459,6 +506,7 @@ enum WorldStatesICC enum AreaIds { + AREA_ICECROWN_CITADEL = 4812, AREA_THE_FROZEN_THRONE = 4859 }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp index ad06bc1c485..b56e0dd6360 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp @@ -38,7 +38,7 @@ class icecrown_citadel_teleport : public GameObjectScript player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Oratory of the Damned.", GOSSIP_SENDER_ICC_PORT, ORATORY_OF_THE_DAMNED_TELEPORT); if (instance->GetBossState(DATA_LADY_DEATHWHISPER) == DONE) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Rampart of Skulls.", GOSSIP_SENDER_ICC_PORT, RAMPART_OF_SKULLS_TELEPORT); - if (instance->GetBossState(DATA_GUNSHIP_EVENT) == DONE) + if (instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == DONE) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Deathbringer's Rise.", GOSSIP_SENDER_ICC_PORT, DEATHBRINGER_S_RISE_TELEPORT); if (instance->GetData(DATA_COLDFLAME_JETS) == DONE) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Upper Spire.", GOSSIP_SENDER_ICC_PORT, UPPER_SPIRE_TELEPORT); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index e2234fa5a20..bfacd6fafcc 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -15,20 +15,27 @@ * with this program. If not, see . */ -#include "ObjectMgr.h" -#include "ScriptMgr.h" +#include "AccountMgr.h" #include "InstanceScript.h" -#include "ScriptedCreature.h" #include "Map.h" -#include "PoolMgr.h" -#include "AccountMgr.h" -#include "icecrown_citadel.h" +#include "ObjectMgr.h" #include "Player.h" +#include "PoolMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "Transport.h" +#include "TransportMgr.h" #include "WorldPacket.h" #include "WorldSession.h" +#include "icecrown_citadel.h" enum EventIds { + EVENT_PLAYERS_GUNSHIP_SPAWN = 22663, + EVENT_PLAYERS_GUNSHIP_COMBAT = 22664, + EVENT_PLAYERS_GUNSHIP_SAURFANG = 22665, + EVENT_ENEMY_GUNSHIP_COMBAT = 22860, + EVENT_ENEMY_GUNSHIP_DESPAWN = 22861, EVENT_QUAKE = 23437, EVENT_SECOND_REMORSELESS_WINTER = 23507, EVENT_TELEPORT_TO_FROSTMOURNE = 23617 @@ -39,6 +46,7 @@ enum TimedEvents EVENT_UPDATE_EXECUTION_TIME = 1, EVENT_QUAKE_SHATTER = 2, EVENT_REBUILD_PLATFORM = 3, + EVENT_RESPAWN_GUNSHIP = 4 }; DoorData const doorData[] = @@ -106,6 +114,9 @@ class instance_icecrown_citadel : public InstanceMapScript TeamInInstance = 0; HeroicAttempts = MaxHeroicAttempts; LadyDeathwisperElevatorGUID = 0; + GunshipGUID = 0; + EnemyGunshipGUID = 0; + GunshipArmoryGUID = 0; DeathbringerSaurfangGUID = 0; DeathbringerSaurfangDoorGUID = 0; DeathbringerSaurfangEventGUID = 0; @@ -164,6 +175,9 @@ class instance_icecrown_citadel : public InstanceMapScript { if (!TeamInInstance) TeamInInstance = player->GetTeam(); + + if (GetBossState(DATA_LADY_DEATHWHISPER) == DONE && GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != DONE) + SpawnGunship(); } void OnCreatureCreate(Creature* creature) OVERRIDE @@ -217,6 +231,10 @@ class instance_icecrown_citadel : public InstanceMapScript case NPC_DEATHBRINGER_SAURFANG: DeathbringerSaurfangGUID = creature->GetGUID(); break; + case NPC_ALLIANCE_GUNSHIP_CANNON: + case NPC_HORDE_GUNSHIP_CANNON: + creature->SetControlled(true, UNIT_STATE_ROOT); + break; case NPC_SE_HIGH_OVERLORD_SAURFANG: if (TeamInInstance == ALLIANCE) creature->UpdateEntry(NPC_SE_MURADIN_BRONZEBEARD, ALLIANCE, creature->GetCreatureData()); @@ -341,6 +359,54 @@ class instance_icecrown_citadel : public InstanceMapScript } break; } + case NPC_HORDE_GUNSHIP_CANNON: + case NPC_ORGRIMS_HAMMER_CREW: + case NPC_SKY_REAVER_KORM_BLACKSCAR: + if (TeamInInstance == ALLIANCE) + return 0; + break; + case NPC_ALLIANCE_GUNSHIP_CANNON: + case NPC_SKYBREAKER_DECKHAND: + case NPC_HIGH_CAPTAIN_JUSTIN_BARTLETT: + if (TeamInInstance == HORDE) + return 0; + break; + case NPC_ZAFOD_BOOMBOX: + if (GameObjectTemplate const* go = sObjectMgr->GetGameObjectTemplate(GO_THE_SKYBREAKER_A)) + if ((TeamInInstance == ALLIANCE && data->mapid == go->moTransport.mapID) || + (TeamInInstance == HORDE && data->mapid != go->moTransport.mapID)) + return entry; + return 0; + case NPC_IGB_MURADIN_BRONZEBEARD: + if ((TeamInInstance == ALLIANCE && data->posX > 10.0f) || + (TeamInInstance == HORDE && data->posX < 10.0f)) + return entry; + return 0; + default: + break; + } + + return entry; + } + + uint32 GetGameObjectEntry(uint32 /*guidLow*/, uint32 entry) OVERRIDE + { + switch (entry) + { + case GO_GUNSHIP_ARMORY_H_10N: + case GO_GUNSHIP_ARMORY_H_25N: + case GO_GUNSHIP_ARMORY_H_10H: + case GO_GUNSHIP_ARMORY_H_25H: + if (TeamInInstance == ALLIANCE) + return 0; + break; + case GO_GUNSHIP_ARMORY_A_10N: + case GO_GUNSHIP_ARMORY_A_25N: + case GO_GUNSHIP_ARMORY_A_10H: + case GO_GUNSHIP_ARMORY_A_25H: + if (TeamInInstance == HORDE) + return 0; + break; default: break; } @@ -446,6 +512,20 @@ class instance_icecrown_citadel : public InstanceMapScript go->SetGoState(GO_STATE_READY); } break; + case GO_THE_SKYBREAKER_H: + case GO_ORGRIMS_HAMMER_A: + EnemyGunshipGUID = go->GetGUID(); + break; + case GO_GUNSHIP_ARMORY_H_10N: + case GO_GUNSHIP_ARMORY_H_25N: + case GO_GUNSHIP_ARMORY_H_10H: + case GO_GUNSHIP_ARMORY_H_25H: + case GO_GUNSHIP_ARMORY_A_10N: + case GO_GUNSHIP_ARMORY_A_25N: + case GO_GUNSHIP_ARMORY_A_10H: + case GO_GUNSHIP_ARMORY_A_25H: + GunshipArmoryGUID = go->GetGUID(); + break; case GO_SAURFANG_S_DOOR: DeathbringerSaurfangDoorGUID = go->GetGUID(); AddDoor(go, true); @@ -587,6 +667,10 @@ class instance_icecrown_citadel : public InstanceMapScript case GO_ICE_WALL: AddDoor(go, false); break; + case GO_THE_SKYBREAKER_A: + case GO_ORGRIMS_HAMMER_H: + GunshipGUID = 0; + break; default: break; } @@ -621,6 +705,10 @@ class instance_icecrown_citadel : public InstanceMapScript { switch (type) { + case DATA_ICECROWN_GUNSHIP_BATTLE: + return GunshipGUID; + case DATA_ENEMY_GUNSHIP: + return EnemyGunshipGUID; case DATA_DEATHBRINGER_SAURFANG: return DeathbringerSaurfangGUID; case DATA_SAURFANG_EVENT_NPC: @@ -691,7 +779,7 @@ class instance_icecrown_citadel : public InstanceMapScript switch (type) { case DATA_LADY_DEATHWHISPER: - SetBossState(DATA_GUNSHIP_EVENT, state); // TEMP HACK UNTIL GUNSHIP SCRIPTED + { if (state == DONE) { if (GameObject* elevator = instance->GetGameObject(LadyDeathwisperElevatorGUID)) @@ -699,8 +787,20 @@ class instance_icecrown_citadel : public InstanceMapScript elevator->SetUInt32Value(GAMEOBJECT_LEVEL, 0); elevator->SetGoState(GO_STATE_READY); } + + SpawnGunship(); } break; + } + case DATA_ICECROWN_GUNSHIP_BATTLE: + if (state == DONE) + { + if (GameObject* loot = instance->GetGameObject(GunshipArmoryGUID)) + loot->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN); + } + else if (state == FAIL) + Events.ScheduleEvent(EVENT_RESPAWN_GUNSHIP, 30000); + break; case DATA_DEATHBRINGER_SAURFANG: switch (state) { @@ -846,6 +946,17 @@ class instance_icecrown_citadel : public InstanceMapScript return true; } + void SpawnGunship() + { + if (!GunshipGUID) + { + SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, NOT_STARTED); + uint32 gunshipEntry = TeamInInstance == HORDE ? GO_ORGRIMS_HAMMER_H : GO_THE_SKYBREAKER_A; + if (Transport* gunship = sTransportMgr->CreateTransport(gunshipEntry, 0, instance)) + GunshipGUID = gunship->GetGUID(); + } + } + void SetData(uint32 type, uint32 data) OVERRIDE { switch (type) @@ -1066,10 +1177,10 @@ class instance_icecrown_citadel : public InstanceMapScript return false; // no break case DATA_DEATHBRINGER_SAURFANG: - if (GetBossState(DATA_GUNSHIP_EVENT) != DONE) + if (GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != DONE) return false; // no break - case DATA_GUNSHIP_EVENT: + case DATA_ICECROWN_GUNSHIP_BATTLE: if (GetBossState(DATA_LADY_DEATHWHISPER) != DONE) return false; // no break @@ -1163,7 +1274,7 @@ class instance_icecrown_citadel : public InstanceMapScript void Update(uint32 diff) OVERRIDE { - if (BloodQuickeningState != IN_PROGRESS && GetBossState(DATA_THE_LICH_KING) != IN_PROGRESS) + if (BloodQuickeningState != IN_PROGRESS && GetBossState(DATA_THE_LICH_KING) != IN_PROGRESS && GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != FAIL) return; Events.Update(diff); @@ -1213,16 +1324,34 @@ class instance_icecrown_citadel : public InstanceMapScript if (GameObject* wind = instance->GetGameObject(FrozenThroneWindGUID)) wind->SetGoState(GO_STATE_ACTIVE); break; + case EVENT_RESPAWN_GUNSHIP: + SpawnGunship(); + break; default: break; } } } - void ProcessEvent(WorldObject* /*source*/, uint32 eventId) OVERRIDE + void ProcessEvent(WorldObject* source, uint32 eventId) OVERRIDE { switch (eventId) { + case EVENT_ENEMY_GUNSHIP_DESPAWN: + if (GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == DONE) + source->AddObjectToRemoveList(); + break; + case EVENT_ENEMY_GUNSHIP_COMBAT: + if (Creature* captain = source->FindNearestCreature(TeamInInstance == HORDE ? NPC_IGB_HIGH_OVERLORD_SAURFANG : NPC_IGB_MURADIN_BRONZEBEARD, 100.0f)) + captain->AI()->DoAction(ACTION_ENEMY_GUNSHIP_TALK); + // no break; + case EVENT_PLAYERS_GUNSHIP_SPAWN: + case EVENT_PLAYERS_GUNSHIP_COMBAT: + case EVENT_PLAYERS_GUNSHIP_SAURFANG: + if (GameObject* go = source->ToGameObject()) + if (Transport* transport = go->ToTransport()) + transport->EnableMovement(false); + break; case EVENT_QUAKE: if (GameObject* warning = instance->GetGameObject(FrozenThroneWarningGUID)) warning->SetGoState(GO_STATE_ACTIVE); @@ -1261,6 +1390,9 @@ class instance_icecrown_citadel : public InstanceMapScript protected: EventMap Events; uint64 LadyDeathwisperElevatorGUID; + uint64 GunshipGUID; + uint64 EnemyGunshipGUID; + uint64 GunshipArmoryGUID; uint64 DeathbringerSaurfangGUID; uint64 DeathbringerSaurfangDoorGUID; uint64 DeathbringerSaurfangEventGUID; // Muradin Bronzebeard or High Overlord Saurfang diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp index 84cf02cfe13..bd80de627a8 100644 --- a/src/server/scripts/Northrend/zone_storm_peaks.cpp +++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp @@ -792,37 +792,6 @@ class spell_veranus_summon : public SpellScriptLoader } }; -/*##### -# spell_jokkum_eject_all -#####*/ - -class spell_jokkum_eject_all : public SpellScriptLoader -{ - public: spell_jokkum_eject_all() : SpellScriptLoader("spell_jokkum_eject_all") { } - - class spell_jokkum_eject_all_SpellScript : public SpellScript - { - PrepareSpellScript(spell_jokkum_eject_all_SpellScript); - - void HandleScriptEffect(SpellEffIndex /* effIndex */) - { - if (Unit* caster = GetCaster()) - if (caster->IsVehicle()) - caster->GetVehicleKit()->RemoveAllPassengers(); - } - - void Register() OVERRIDE - { - OnEffectHitTarget += SpellEffectFn(spell_jokkum_eject_all_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; - - SpellScript* GetSpellScript() const OVERRIDE - { - return new spell_jokkum_eject_all_SpellScript(); - } -}; - enum CloseRift { SPELL_DESPAWN_RIFT = 61665 @@ -882,6 +851,5 @@ void AddSC_storm_peaks() new npc_king_jokkum_vehicle(); new spell_jokkum_scriptcast(); new spell_veranus_summon(); - new spell_jokkum_eject_all(); new spell_close_rift(); } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 1e9a8713019..9a81582b0b9 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -36,6 +36,7 @@ #include "SkillDiscovery.h" #include "SpellScript.h" #include "SpellAuraEffects.h" +#include "Vehicle.h" class spell_gen_absorb0_hitlimit1 : public SpellScriptLoader { @@ -3673,6 +3674,33 @@ class spell_gen_whisper_gulch_yogg_saron_whisper : public SpellScriptLoader } }; +class spell_gen_eject_all_passengers : public SpellScriptLoader +{ + public: + spell_gen_eject_all_passengers() : SpellScriptLoader("spell_gen_eject_all_passengers") { } + + class spell_gen_eject_all_passengers_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_eject_all_passengers_SpellScript); + + void RemoveVehicleAuras() + { + if (Vehicle* vehicle = GetHitUnit()->GetVehicleKit()) + vehicle->RemoveAllPassengers(); + } + + void Register() OVERRIDE + { + AfterHit += SpellHitFn(spell_gen_eject_all_passengers_SpellScript::RemoveVehicleAuras); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_gen_eject_all_passengers_SpellScript(); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -3754,4 +3782,5 @@ void AddSC_generic_spell_scripts() new spell_gen_vendor_bark_trigger(); new spell_gen_wg_water(); new spell_gen_whisper_gulch_yogg_saron_whisper(); + new spell_gen_eject_all_passengers(); } -- cgit v1.2.3 From e469ff5e88127621eae329b81cd171201c7ecead Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 23 Mar 2014 12:54:09 +0100 Subject: Fixed build without PCH --- .../Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp | 8 +++++++- src/server/shared/Common.h | 10 ---------- src/server/shared/Logging/AppenderFile.cpp | 1 + 3 files changed, 8 insertions(+), 11 deletions(-) (limited to 'src/server/scripts/Northrend') diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp index 3e18213b745..3ecbb473ac2 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp @@ -15,11 +15,17 @@ * with this program. If not, see . */ +#include "CellImpl.h" #include "CreatureTextMgr.h" +#include "GridNotifiersImpl.h" +#include "GossipDef.h" #include "MoveSpline.h" #include "MoveSplineInit.h" -#include "SpellScript.h" +#include "PassiveAI.h" #include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellAuraEffects.h" +#include "SpellScript.h" #include "Transport.h" #include "TransportMgr.h" #include "Vehicle.h" diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h index 5dea589da25..fb153f2ba3e 100644 --- a/src/server/shared/Common.h +++ b/src/server/shared/Common.h @@ -71,12 +71,6 @@ #include #include -#if PLATFORM == PLATFORM_WINDOWS -#define STRCASECMP stricmp -#else -#define STRCASECMP strcasecmp -#endif - #include #include #include @@ -114,8 +108,6 @@ #include -#define I32FMT "%08I32X" -#define I64FMT "%016I64X" #define snprintf _snprintf #define atoll _atoi64 #define vsnprintf _vsnprintf @@ -126,8 +118,6 @@ #define stricmp strcasecmp #define strnicmp strncasecmp -#define I32FMT "%08X" -#define I64FMT "%016llX" #endif diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp index a88188266e2..1a8fa8e7983 100644 --- a/src/server/shared/Logging/AppenderFile.cpp +++ b/src/server/shared/Logging/AppenderFile.cpp @@ -16,6 +16,7 @@ */ #include "AppenderFile.h" +#include "Common.h" #if PLATFORM == PLATFORM_WINDOWS # include -- cgit v1.2.3 From cd20be2cc90ae9b4da1b2af1af4f1a226a6c2e25 Mon Sep 17 00:00:00 2001 From: Shauren Date: Mon, 24 Mar 2014 00:58:37 +0100 Subject: Scripts/Icecrown Citadel * Deathbringer Saurfang will now evade if any player stands on the gunship * Fixed players being stuck in combat after defeating gunship * Fixed players not sticking to gunships --- sql/updates/world/2014_03_24_00_world_misc.sql | 4 + .../IcecrownCitadel/boss_deathbringer_saurfang.cpp | 24 +++++ .../boss_icecrown_gunship_battle.cpp | 105 ++++++++++++++++++--- .../Northrend/IcecrownCitadel/icecrown_citadel.h | 1 + .../IcecrownCitadel/instance_icecrown_citadel.cpp | 8 ++ 5 files changed, 131 insertions(+), 11 deletions(-) create mode 100644 sql/updates/world/2014_03_24_00_world_misc.sql (limited to 'src/server/scripts/Northrend') diff --git a/sql/updates/world/2014_03_24_00_world_misc.sql b/sql/updates/world/2014_03_24_00_world_misc.sql new file mode 100644 index 00000000000..a69810f0e99 --- /dev/null +++ b/sql/updates/world/2014_03_24_00_world_misc.sql @@ -0,0 +1,4 @@ +UPDATE `creature_template` SET `faction_A`=83,`faction_H`=83 WHERE `entry`=37833; -- Sky-Reaver Korm Blackscar +UPDATE `gameobject_template` SET `flags`=40 WHERE `entry` IN (201812,201811,201581,201580); +UPDATE `achievement_criteria_data` SET `value1`=1 WHERE `criteria_id`=12947 AND `type`=12;-- Storming the Citadel (25 player) +DELETE FROM `gameobject` WHERE `id`=201880; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index 7be766c0a0e..e8048404027 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -333,6 +333,7 @@ class boss_deathbringer_saurfang : public CreatureScript void JustReachedHome() OVERRIDE { _JustReachedHome(); + Reset(); instance->SetBossState(DATA_DEATHBRINGER_SAURFANG, FAIL); instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MARK_OF_THE_FALLEN_CHAMPION); } @@ -376,7 +377,16 @@ class boss_deathbringer_saurfang : public CreatureScript void JustSummoned(Creature* summon) OVERRIDE { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) + { + if (target->GetTransport()) + { + summon->DespawnOrUnsummon(1); + EnterEvadeMode(); + return; + } + summon->AI()->AttackStart(target); + } summon->CastSpell(summon, SPELL_BLOOD_LINK_BEAST, true); summon->CastSpell(summon, SPELL_RESISTANT_SKIN, true); @@ -399,6 +409,12 @@ class boss_deathbringer_saurfang : public CreatureScript void SpellHitTarget(Unit* target, SpellInfo const* spell) OVERRIDE { + if (target->GetTransport()) + { + EnterEvadeMode(); + return; + } + switch (spell->Id) { case SPELL_MARK_OF_THE_FALLEN_CHAMPION: @@ -571,6 +587,14 @@ class boss_deathbringer_saurfang : public CreatureScript } } + bool CanAIAttack(Unit const* target) const OVERRIDE + { + if (target->GetTransport()) + return false; + + return true; + } + static uint32 const FightWonValue; private: diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp index 3ecbb473ac2..4706aeae6b2 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp @@ -216,6 +216,39 @@ Position const OrgrimsHammerTeleportExit = { 7.461699f, 0.158853f, 35.72989f, 0. Position const OrgrimsHammerTeleportPortal = { 47.550990f, -0.101778f, 37.61111f, 0.0f }; Position const SkybreakerTeleportExit = { -17.55738f, -0.090421f, 21.18366f, 0.0f }; +uint32 const MuradinExitPathSize = 10; +G3D::Vector3 const MuradinExitPath[MuradinExitPathSize] = +{ + { 8.130936f, -0.2699585f, 20.31728f }, + { 6.380936f, -0.2699585f, 20.31728f }, + { 3.507703f, 0.02986573f, 20.78463f }, + { -2.767633f, 3.743143f, 20.37663f }, + { -4.017633f, 4.493143f, 20.12663f }, + { -7.242224f, 6.856013f, 20.03468f }, + { -7.742224f, 8.606013f, 20.78468f }, + { -7.992224f, 9.856013f, 21.28468f }, + { -12.24222f, 23.10601f, 21.28468f }, + { -14.88477f, 25.20844f, 21.59985f }, +}; + +uint32 const SaurfangExitPathSize = 13; +G3D::Vector3 const SaurfangExitPath[SaurfangExitPathSize] = +{ + { 30.43987f, 0.1475817f, 36.10674f }, + { 21.36141f, -3.056458f, 35.42970f }, + { 19.11141f, -3.806458f, 35.42970f }, + { 19.01736f, -3.299440f, 35.39428f }, + { 18.6747f, -5.862823f, 35.66611f }, + { 18.6747f, -7.862823f, 35.66611f }, + { 18.1747f, -17.36282f, 35.66611f }, + { 18.1747f, -22.61282f, 35.66611f }, + { 17.9247f, -24.36282f, 35.41611f }, + { 17.9247f, -26.61282f, 35.66611f }, + { 17.9247f, -27.86282f, 35.66611f }, + { 17.9247f, -29.36282f, 35.66611f }, + { 15.33203f, -30.42621f, 35.93796f } +}; + enum PassengerSlots { // Freezing the cannons @@ -569,6 +602,8 @@ struct gunship_npc_AI : public ScriptedAI bool CanAIAttack(Unit const* target) const OVERRIDE { + if (Instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) + return false; return target->HasAura(Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_ON_ORGRIMS_HAMMER_DECK : SPELL_ON_SKYBREAKER_DECK); } @@ -582,7 +617,10 @@ protected: bool SelectVictim() { if (Instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) + { + EnterEvadeMode(); return false; + } if (!me->HasReactState(REACT_PASSIVE)) { @@ -632,7 +670,7 @@ class npc_gunship : public CreatureScript void DamageTaken(Unit* /*source*/, uint32& damage) OVERRIDE { - if (damage > me->GetHealth()) + if (damage >= me->GetHealth()) { JustDied(NULL); damage = me->GetHealth() - 1; @@ -662,6 +700,7 @@ class npc_gunship : public CreatureScript bool isVictory = me->GetTransport()->GetEntry() == GO_THE_SKYBREAKER_H || me->GetTransport()->GetEntry() == GO_ORGRIMS_HAMMER_A; InstanceScript* instance = me->GetInstanceScript(); + instance->SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, isVictory ? DONE : FAIL); if (Creature* creature = me->FindNearestCreature(me->GetEntry() == NPC_ORGRIMS_HAMMER ? NPC_THE_SKYBREAKER : NPC_ORGRIMS_HAMMER, 200.0f)) { instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, creature); @@ -675,8 +714,12 @@ class npc_gunship : public CreatureScript std::list creatures; GetCreatureListWithEntryInGrid(creatures, me, NPC_MARTYR_STALKER_IGB_SAURFANG, SIZE_OF_GRIDS); for (std::list::iterator itr = creatures.begin(); itr != creatures.end(); ++itr) - (*itr)->AI()->EnterEvadeMode(); - + { + Creature* stalker = *itr; + stalker->RemoveAllAuras(); + stalker->DeleteThreatList(); + stalker->CombatStop(true); + } uint32 explosionSpell = isVictory ? SPELL_EXPLOSION_VICTORY : SPELL_EXPLOSION_WIPE; creatures.clear(); @@ -735,6 +778,14 @@ class npc_gunship : public CreatureScript ship->CastSpell(ship, SPELL_ACHIEVEMENT, TRIGGERED_FULL_MASK); ship->CastSpell(ship, SPELL_AWARD_REPUTATION_BOSS_KILL, TRIGGERED_FULL_MASK); } + + creatures.clear(); + GetCreatureListWithEntryInGrid(creatures, me, NPC_SKYBREAKER_MARINE, 200.0f); + GetCreatureListWithEntryInGrid(creatures, me, NPC_SKYBREAKER_SERGEANT, 200.0f); + GetCreatureListWithEntryInGrid(creatures, me, NPC_KOR_KRON_REAVER, 200.0f); + GetCreatureListWithEntryInGrid(creatures, me, NPC_KOR_KRON_SERGEANT, 200.0f); + for (std::list::iterator itr = creatures.begin(); itr != creatures.end(); ++itr) + (*itr)->DespawnOrUnsummon(1); } else { @@ -742,8 +793,6 @@ class npc_gunship : public CreatureScript me->m_Events.AddEvent(new ResetEncounterEvent(me, teleportSpellId, me->GetInstanceScript()->GetData64(DATA_ENEMY_GUNSHIP)), me->m_Events.CalculateTime(8000)); } - - instance->SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, isVictory ? DONE : FAIL); } void SetGUID(uint64 guid, int32 id/* = 0*/) OVERRIDE @@ -860,8 +909,8 @@ class npc_high_overlord_saurfang_igb : public CreatureScript else if (action == ACTION_SPAWN_MAGE) { time_t now = time(NULL); - if (_firstMageCooldown < now) - _events.ScheduleEvent(EVENT_SUMMON_MAGE, (now - _firstMageCooldown) * IN_MILLISECONDS); + if (_firstMageCooldown > now) + _events.ScheduleEvent(EVENT_SUMMON_MAGE, (_firstMageCooldown - now) * IN_MILLISECONDS); else _events.ScheduleEvent(EVENT_SUMMON_MAGE, 1); } @@ -879,6 +928,21 @@ class npc_high_overlord_saurfang_igb : public CreatureScript _controller.SummonCreatures(SLOT_RIFLEMAN_1, SLOT_RIFLEMAN_4); } } + else if (action == ACTION_EXIT_SHIP) + { + Position pos; + pos.Relocate(SaurfangExitPath[SaurfangExitPathSize - 1].x, SaurfangExitPath[SaurfangExitPathSize - 1].y, SaurfangExitPath[SaurfangExitPathSize - 1].z); + me->GetMotionMaster()->MovePoint(EVENT_CHARGE_PREPATH, pos, false); + + Movement::PointsArray path(SaurfangExitPath, SaurfangExitPath + SaurfangExitPathSize); + + Movement::MoveSplineInit init(me); + init.DisableTransportPathTransformations(); + init.MovebyPath(path, 0); + init.Launch(); + + me->DespawnOrUnsummon(18000); + } } void SetData(uint32 type, uint32 data) OVERRIDE @@ -908,7 +972,7 @@ class npc_high_overlord_saurfang_igb : public CreatureScript if (me->HealthBelowPctDamaged(65, damage) && !me->HasAura(SPELL_TASTE_OF_BLOOD)) DoCast(me, SPELL_TASTE_OF_BLOOD, true); - if (damage > me->GetHealth()) + if (damage >= me->GetHealth()) damage = me->GetHealth() - 1; } @@ -1017,6 +1081,8 @@ class npc_high_overlord_saurfang_igb : public CreatureScript bool CanAIAttack(Unit const* target) const OVERRIDE { + if (_instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) + return false; return target->HasAura(SPELL_ON_ORGRIMS_HAMMER_DECK) || !target->IsControlledByPlayer(); } @@ -1109,8 +1175,8 @@ class npc_muradin_bronzebeard_igb : public CreatureScript else if (action == ACTION_SPAWN_MAGE) { time_t now = time(NULL); - if (_firstMageCooldown < now) - _events.ScheduleEvent(EVENT_SUMMON_MAGE, (now - _firstMageCooldown) * IN_MILLISECONDS); + if (_firstMageCooldown > now) + _events.ScheduleEvent(EVENT_SUMMON_MAGE, (_firstMageCooldown - now) * IN_MILLISECONDS); else _events.ScheduleEvent(EVENT_SUMMON_MAGE, 1); } @@ -1128,6 +1194,21 @@ class npc_muradin_bronzebeard_igb : public CreatureScript _controller.SummonCreatures(SLOT_RIFLEMAN_1, SLOT_RIFLEMAN_4); } } + else if (action == ACTION_EXIT_SHIP) + { + Position pos; + pos.Relocate(MuradinExitPath[MuradinExitPathSize - 1].x, MuradinExitPath[MuradinExitPathSize - 1].y, MuradinExitPath[MuradinExitPathSize - 1].z); + me->GetMotionMaster()->MovePoint(EVENT_CHARGE_PREPATH, pos, false); + + Movement::PointsArray path(MuradinExitPath, MuradinExitPath + MuradinExitPathSize); + + Movement::MoveSplineInit init(me); + init.DisableTransportPathTransformations(); + init.MovebyPath(path, 0); + init.Launch(); + + me->DespawnOrUnsummon(18000); + } } void SetData(uint32 type, uint32 data) OVERRIDE @@ -1158,7 +1239,7 @@ class npc_muradin_bronzebeard_igb : public CreatureScript if (me->HealthBelowPctDamaged(65, damage) && me->HasAura(SPELL_TASTE_OF_BLOOD)) DoCast(me, SPELL_TASTE_OF_BLOOD, true); - if (damage > me->GetHealth()) + if (damage >= me->GetHealth()) damage = me->GetHealth() - 1; } @@ -1270,6 +1351,8 @@ class npc_muradin_bronzebeard_igb : public CreatureScript bool CanAIAttack(Unit const* target) const OVERRIDE { + if (_instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) + return false; return target->HasAura(SPELL_ON_SKYBREAKER_DECK) || !target->IsControlledByPlayer(); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h index ba64107e618..6aeab015b78 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h @@ -454,6 +454,7 @@ enum SharedActions { // Icecrown Gunship Battle ACTION_ENEMY_GUNSHIP_TALK = -369390, + ACTION_EXIT_SHIP = -369391, // Festergut ACTION_FESTERGUT_COMBAT = -366260, diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index bfacd6fafcc..31daa92cbe8 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -1347,11 +1347,19 @@ class instance_icecrown_citadel : public InstanceMapScript // no break; case EVENT_PLAYERS_GUNSHIP_SPAWN: case EVENT_PLAYERS_GUNSHIP_COMBAT: + if (GameObject* go = source->ToGameObject()) + if (Transport* transport = go->ToTransport()) + transport->EnableMovement(false); + break; case EVENT_PLAYERS_GUNSHIP_SAURFANG: + { + if (Creature* captain = source->FindNearestCreature(TeamInInstance == HORDE ? NPC_IGB_HIGH_OVERLORD_SAURFANG : NPC_IGB_MURADIN_BRONZEBEARD, 100.0f)) + captain->AI()->DoAction(ACTION_EXIT_SHIP); if (GameObject* go = source->ToGameObject()) if (Transport* transport = go->ToTransport()) transport->EnableMovement(false); break; + } case EVENT_QUAKE: if (GameObject* warning = instance->GetGameObject(FrozenThroneWarningGUID)) warning->SetGoState(GO_STATE_ACTIVE); -- cgit v1.2.3 From 84365f43b4bc171d9c57c1a1d96cd7f349da869f Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 25 Mar 2014 22:20:45 +0100 Subject: Scripts/Icecrown Citadel: Fixed Muradin/Saurfang attacking each other during Gunship Battle Closes #11786 --- .../Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/server/scripts/Northrend') diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp index 4706aeae6b2..4b938253584 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp @@ -1083,7 +1083,7 @@ class npc_high_overlord_saurfang_igb : public CreatureScript { if (_instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) return false; - return target->HasAura(SPELL_ON_ORGRIMS_HAMMER_DECK) || !target->IsControlledByPlayer(); + return target->HasAura(SPELL_ON_ORGRIMS_HAMMER_DECK) || target->GetEntry() == NPC_SKYBREAKER_MARINE || target->GetEntry() == NPC_SKYBREAKER_SERGEANT; } private: @@ -1353,7 +1353,7 @@ class npc_muradin_bronzebeard_igb : public CreatureScript { if (_instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) return false; - return target->HasAura(SPELL_ON_SKYBREAKER_DECK) || !target->IsControlledByPlayer(); + return target->HasAura(SPELL_ON_SKYBREAKER_DECK) || target->GetEntry() == NPC_KOR_KRON_REAVER || target->GetEntry() == NPC_KOR_KRON_SERGEANT; } private: -- cgit v1.2.3 From 808a1998c6104241dd3da5d983a70798113b017d Mon Sep 17 00:00:00 2001 From: Gacko Date: Wed, 26 Mar 2014 18:36:39 +0100 Subject: Quest: The Power of the Elements Remove hack SAI, use aura script --- sql/updates/world/2014_03_26_00_world_sai.sql | 6 ++++ .../scripts/Northrend/zone_borean_tundra.cpp | 34 ++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 sql/updates/world/2014_03_26_00_world_sai.sql (limited to 'src/server/scripts/Northrend') diff --git a/sql/updates/world/2014_03_26_00_world_sai.sql b/sql/updates/world/2014_03_26_00_world_sai.sql new file mode 100644 index 00000000000..bb1ac0c9d62 --- /dev/null +++ b/sql/updates/world/2014_03_26_00_world_sai.sql @@ -0,0 +1,6 @@ +DELETE FROM `smart_scripts` WHERE `entryorguid`=24601 AND `source_type`=0 AND `id`=2; + +DELETE FROM `spell_script_names` WHERE `spell_id`=46374; +INSERT INTO `spell_script_names`(`spell_id`,`ScriptName`) VALUE +(46374,'spell_windsoul_totem_aura'); + diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index f840c0562b3..a489c6e772f 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -2537,6 +2537,39 @@ public: }; +enum WindsoulTotemAura +{ + SPELL_WINDSOUL_CREDT = 46378 +}; + +class spell_windsoul_totem_aura : public SpellScriptLoader +{ +public: + spell_windsoul_totem_aura() : SpellScriptLoader("spell_windsoul_totem_aura") { } + + class spell_windsoul_totem_aura_AuraScript : public AuraScript + { + PrepareAuraScript(spell_windsoul_totem_aura_AuraScript); + + void OnRemove(AuraEffect const*, AuraEffectHandleModes) + { + if (GetTarget()->isDead()) + if (Unit* caster = GetCaster()) + caster->CastSpell(NULL, SPELL_WINDSOUL_CREDT); + } + + void Register() OVERRIDE + { + OnEffectRemove += AuraEffectRemoveFn(spell_windsoul_totem_aura_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_windsoul_totem_aura_AuraScript(); + } +}; + void AddSC_borean_tundra() { new npc_sinkhole_kill_credit(); @@ -2565,4 +2598,5 @@ void AddSC_borean_tundra() new npc_valiance_keep_cannoneer(); new npc_warmage_coldarra(); new npc_hidden_cultist(); + new spell_windsoul_totem_aura(); } -- cgit v1.2.3 From 46b8bc8882b12fd848dbdd755c8562fdd682fcf0 Mon Sep 17 00:00:00 2001 From: Gacko Date: Wed, 26 Mar 2014 18:51:09 +0100 Subject: Fix non-pch build and remove blank line --- sql/updates/world/2014_03_26_00_world_sai.sql | 1 - src/server/scripts/Northrend/zone_borean_tundra.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server/scripts/Northrend') diff --git a/sql/updates/world/2014_03_26_00_world_sai.sql b/sql/updates/world/2014_03_26_00_world_sai.sql index bb1ac0c9d62..44ce75cd95e 100644 --- a/sql/updates/world/2014_03_26_00_world_sai.sql +++ b/sql/updates/world/2014_03_26_00_world_sai.sql @@ -3,4 +3,3 @@ DELETE FROM `smart_scripts` WHERE `entryorguid`=24601 AND `source_type`=0 AND `i DELETE FROM `spell_script_names` WHERE `spell_id`=46374; INSERT INTO `spell_script_names`(`spell_id`,`ScriptName`) VALUE (46374,'spell_windsoul_totem_aura'); - diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index a489c6e772f..f7f473297ef 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -44,6 +44,7 @@ EndContentData */ #include "Player.h" #include "SpellInfo.h" #include "WorldSession.h" +#include "SpellScript.h" /*###### ## npc_sinkhole_kill_credit -- cgit v1.2.3 From 8c44259fae2980598980a7935a3f3941130a5a10 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Thu, 27 Mar 2014 21:43:59 +0100 Subject: Core/Misc: Fix some static analysis issues Fix uninitialized values, most of which are false positives, always initialized before being accessed. Add some asserts and additional NULL checks as sanity checks. Use SpellMgr::EnsureSpellInfo() if the spell id is valid and always supposed to return a valid not-NULL SpellInfo* . --- src/server/game/AI/SmartScripts/SmartScript.cpp | 2 +- src/server/game/Conditions/ConditionMgr.cpp | 3 +-- src/server/game/Entities/Object/Object.cpp | 4 ++++ src/server/game/Entities/Pet/Pet.cpp | 3 +-- src/server/game/Entities/Player/Player.cpp | 3 +-- src/server/game/Entities/Unit/StatSystem.cpp | 4 ++-- src/server/game/Globals/ObjectMgr.cpp | 1 + src/server/game/Spells/Auras/SpellAuraEffects.cpp | 4 ++-- src/server/game/Spells/SpellEffects.cpp | 2 +- src/server/game/Spells/SpellMgr.h | 8 ++++++++ src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp | 11 +++++++---- src/server/scripts/Kalimdor/zone_silithus.cpp | 6 +++--- .../Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp | 2 +- .../IcecrownCitadel/boss_icecrown_gunship_battle.cpp | 8 +++++++- .../TempestKeep/arcatraz/boss_dalliah_the_doomsayer.cpp | 7 ++++++- .../TempestKeep/arcatraz/boss_wrath_scryer_soccothrates.cpp | 7 ++++++- src/server/scripts/Spells/spell_dk.cpp | 4 ++-- src/server/scripts/Spells/spell_generic.cpp | 4 ++-- src/server/scripts/Spells/spell_mage.cpp | 4 ++-- src/server/scripts/Spells/spell_pet.cpp | 8 +++----- src/server/scripts/Spells/spell_priest.cpp | 3 +-- src/server/scripts/Spells/spell_rogue.cpp | 3 +-- src/server/scripts/Spells/spell_warlock.cpp | 6 ++---- src/server/scripts/Spells/spell_warrior.cpp | 3 +-- 24 files changed, 66 insertions(+), 44 deletions(-) (limited to 'src/server/scripts/Northrend') diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 6d6b43f7d2e..231f3808aa9 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -512,7 +512,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u // unless target is outside spell range, out of mana, or LOS. bool _allowMove = false; - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(e.action.cast.spell); + SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(e.action.cast.spell); int32 mana = me->GetPower(POWER_MANA); if (me->GetDistance(*itr) > spellInfo->GetMaxRange(true) || diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index c3ef88fef05..bb1a722ec42 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -1078,8 +1078,7 @@ bool ConditionMgr::addToGossipMenuItems(Condition* cond) bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) { uint32 conditionEffMask = cond->SourceGroup; - SpellInfo* spellInfo = const_cast(sSpellMgr->GetSpellInfo(cond->SourceEntry)); - ASSERT(spellInfo); + SpellInfo* spellInfo = const_cast(sSpellMgr->EnsureSpellInfo(cond->SourceEntry)); std::list sharedMasks; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 944498d0fed..12c8d0ba2ac 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -413,6 +413,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const // 0x40 if (flags & UPDATEFLAG_STATIONARY_POSITION) { + ASSERT(object); *data << object->GetStationaryX(); *data << object->GetStationaryY(); *data << object->GetStationaryZ(); @@ -486,6 +487,9 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const if (flags & UPDATEFLAG_VEHICLE) { /// @todo Allow players to aquire this updateflag. + ASSERT(unit); + ASSERT(unit->GetVehicleKit()); + ASSERT(unit->GetVehicleKit()->GetVehicleInfo()); *data << uint32(unit->GetVehicleKit()->GetVehicleInfo()->m_ID); if (unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) *data << float(unit->GetTransOffsetO()); diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 1d7db005a0b..19ac8dd57b5 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -2060,8 +2060,7 @@ void Pet::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs) continue; uint32 unSpellId = itr->first; - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(unSpellId); - ASSERT(spellInfo); + SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(unSpellId); // Not send cooldown for this spells if (spellInfo->IsCooldownStartedOnEvent()) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index d96439748e0..eb9392f0401 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4204,8 +4204,7 @@ bool Player::Has310Flyer(bool checkAllSpells, uint32 excludeSpellId) if (_spell_idx->second->skillId != SKILL_MOUNTS) break; // We can break because mount spells belong only to one skillline (at least 310 flyers do) - spellInfo = sSpellMgr->GetSpellInfo(itr->first); - ASSERT(spellInfo); + spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED && spellInfo->Effects[i].CalcValue() == 310) diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 3afa6b016d2..04136221d0d 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -1149,7 +1149,7 @@ bool Guardian::UpdateStats(Stats stat) if (itr != ToPet()->m_spells.end()) // If pet has Wild Hunt { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value + SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value AddPct(mod, spellInfo->Effects[EFFECT_0].CalcValue()); } } @@ -1318,7 +1318,7 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged) if (itr != ToPet()->m_spells.end()) // If pet has Wild Hunt { - SpellInfo const* sProto = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value + SpellInfo const* sProto = sSpellMgr->EnsureSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value mod += CalculatePct(1.0f, sProto->Effects[1].CalcValue()); } } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 2a3a79905fb..8784e2ca4e7 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -1442,6 +1442,7 @@ bool ObjectMgr::SetCreatureLinkedRespawn(uint32 guidLow, uint32 linkedGuidLow) return false; const CreatureData* master = GetCreatureData(guidLow); + ASSERT(master); uint64 guid = MAKE_NEW_GUID(guidLow, master->id, HIGHGUID_UNIT); if (!linkedGuidLow) // we're removing the linking diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index b7aabcc7589..4ed742167a5 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -4772,7 +4772,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool uint32 spellId = 24659; if (apply && caster) { - SpellInfo const* spell = sSpellMgr->GetSpellInfo(spellId); + SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(spellId); for (uint32 i = 0; i < spell->StackAmount; ++i) caster->CastSpell(target, spell->Id, true, NULL, NULL, GetCasterGUID()); @@ -4787,7 +4787,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool uint32 spellId = 24662; if (apply && caster) { - SpellInfo const* spell = sSpellMgr->GetSpellInfo(spellId); + SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(spellId); for (uint32 i = 0; i < spell->StackAmount; ++i) caster->CastSpell(target, spell->Id, true, NULL, NULL, GetCasterGUID()); break; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 73d3c39148a..609c9ba05be 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -1829,7 +1829,7 @@ void Spell::EffectEnergize(SpellEffIndex effIndex) sSpellMgr->GetSetOfSpellsInSpellGroup(SPELL_GROUP_ELIXIR_BATTLE, avalibleElixirs); for (std::set::iterator itr = avalibleElixirs.begin(); itr != avalibleElixirs.end();) { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(*itr); + SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(*itr); if (spellInfo->SpellLevel < m_spellInfo->SpellLevel || spellInfo->SpellLevel > unitTarget->getLevel()) avalibleElixirs.erase(itr++); else if (sSpellMgr->IsSpellMemberOfSpellGroup(*itr, SPELL_GROUP_ELIXIR_SHATTRATH)) diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 01fe7708db2..76d59bd1e85 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -690,6 +690,14 @@ class SpellMgr // SpellInfo object management SpellInfo const* GetSpellInfo(uint32 spellId) const { return spellId < GetSpellInfoStoreSize() ? mSpellInfoMap[spellId] : NULL; } + // Use this only with 100% valid spellIds + SpellInfo const* EnsureSpellInfo(uint32 spellId) const + { + ASSERT(spellId < GetSpellInfoStoreSize()); + SpellInfo const* spellInfo = mSpellInfoMap[spellId]; + ASSERT(spellInfo); + return spellInfo; + } uint32 GetSpellInfoStoreSize() const { return mSpellInfoMap.size(); } private: diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp index 241ac85faa2..b5c3bdd86d4 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp @@ -584,10 +584,13 @@ public: arca->MonsterYell(SAY_DIALOG_ARCANAGOS_8, LANG_UNIVERSAL, NULL); return 5000; case 12: - arca->GetMotionMaster()->MovePoint(0, -11010.82f, -1761.18f, 156.47f); - arca->setActive(true); - arca->InterruptNonMeleeSpells(true); - arca->SetSpeed(MOVE_FLIGHT, 2.0f); + if (arca) + { + arca->GetMotionMaster()->MovePoint(0, -11010.82f, -1761.18f, 156.47f); + arca->setActive(true); + arca->InterruptNonMeleeSpells(true); + arca->SetSpeed(MOVE_FLIGHT, 2.0f); + } return 10000; case 13: me->MonsterYell(SAY_DIALOG_MEDIVH_9, LANG_UNIVERSAL, NULL); diff --git a/src/server/scripts/Kalimdor/zone_silithus.cpp b/src/server/scripts/Kalimdor/zone_silithus.cpp index b002bbe8a48..24d557222eb 100644 --- a/src/server/scripts/Kalimdor/zone_silithus.cpp +++ b/src/server/scripts/Kalimdor/zone_silithus.cpp @@ -649,11 +649,11 @@ public: Unit* mob = NULL; for (uint8 i = 0; i < 4; ++i) { - mob = player->FindNearestCreature(entries[i], 50, me); + mob = player->FindNearestCreature(entries[i], 50); while (mob) { mob->RemoveFromWorld(); - mob = player->FindNearestCreature(15423, 50, me); + mob = player->FindNearestCreature(15423, 50); } } break; @@ -1021,7 +1021,7 @@ public: { if (quest->GetQuestId() == QUEST_A_PAWN_ON_THE_ETERNAL_BOARD) { - if (Creature* trigger = go->FindNearestCreature(15454, 100, player)) + if (Creature* trigger = go->FindNearestCreature(15454, 100)) { Unit* Merithra = trigger->SummonCreature(15378, -8034.535f, 1535.14f, 2.61f, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); Unit* Caelestrasz = trigger->SummonCreature(15379, -8032.767f, 1533.148f, 2.61f, 1.5f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp index 3d4ee279685..bbf3e8afc0f 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp @@ -800,7 +800,7 @@ class spell_blood_queen_pact_of_the_darkfallen_dmg : public SpellScriptLoader // this is an additional effect to be executed void PeriodicTick(AuraEffect const* aurEff) { - SpellInfo const* damageSpell = sSpellMgr->GetSpellInfo(SPELL_PACT_OF_THE_DARKFALLEN_DAMAGE); + SpellInfo const* damageSpell = sSpellMgr->EnsureSpellInfo(SPELL_PACT_OF_THE_DARKFALLEN_DAMAGE); int32 damage = damageSpell->Effects[EFFECT_0].CalcValue(); float multiplier = 0.3375f + 0.1f * uint32(aurEff->GetTickNumber()/10); // do not convert to 0.01f - we need tick number/10 as INT (damage increases every 10 ticks) damage = int32(damage * multiplier); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp index 4b938253584..0a9e207db36 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp @@ -849,6 +849,9 @@ class npc_high_overlord_saurfang_igb : public CreatureScript _controller.SetTransport(creature->GetTransport()); me->setRegeneratingHealth(false); me->m_CombatDistance = 70.0f; + _firstMageCooldown = time(NULL) + 60; + _axethrowersYellCooldown = time_t(0); + _rocketeersYellCooldown = time_t(0); } void InitializeAI() OVERRIDE @@ -1115,6 +1118,9 @@ class npc_muradin_bronzebeard_igb : public CreatureScript _controller.SetTransport(creature->GetTransport()); me->setRegeneratingHealth(false); me->m_CombatDistance = 70.0f; + _firstMageCooldown = time(NULL) + 60; + _riflemanYellCooldown = time_t(0); + _mortarYellCooldown = time_t(0); } void InitializeAI() OVERRIDE @@ -1837,7 +1843,7 @@ class spell_igb_rocket_pack : public SpellScriptLoader void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { - SpellInfo const* damageInfo = sSpellMgr->GetSpellInfo(SPELL_ROCKET_PACK_DAMAGE); + SpellInfo const* damageInfo = sSpellMgr->EnsureSpellInfo(SPELL_ROCKET_PACK_DAMAGE); GetTarget()->CastCustomSpell(SPELL_ROCKET_PACK_DAMAGE, SPELLVALUE_BASE_POINT0, 2 * (damageInfo->Effects[EFFECT_0].CalcValue() + aurEff->GetTickNumber() * aurEff->GetAmplitude()), NULL, TRIGGERED_FULL_MASK); GetTarget()->CastSpell(NULL, SPELL_ROCKET_BURST, TRIGGERED_FULL_MASK); } diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_dalliah_the_doomsayer.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_dalliah_the_doomsayer.cpp index bfc304e6a99..18388341a36 100644 --- a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_dalliah_the_doomsayer.cpp +++ b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_dalliah_the_doomsayer.cpp @@ -59,11 +59,16 @@ class boss_dalliah_the_doomsayer : public CreatureScript struct boss_dalliah_the_doomsayerAI : public BossAI { - boss_dalliah_the_doomsayerAI(Creature* creature) : BossAI(creature, DATA_DALLIAH) { } + boss_dalliah_the_doomsayerAI(Creature* creature) : BossAI(creature, DATA_DALLIAH) + { + soccothratesTaunt = false; + soccothratesDeath = false; + } void Reset() OVERRIDE { _Reset(); + soccothratesTaunt = false; soccothratesDeath = false; } diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_wrath_scryer_soccothrates.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_wrath_scryer_soccothrates.cpp index 044be4c1534..6c96708c69d 100644 --- a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_wrath_scryer_soccothrates.cpp +++ b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_wrath_scryer_soccothrates.cpp @@ -82,7 +82,12 @@ class boss_wrath_scryer_soccothrates : public CreatureScript struct boss_wrath_scryer_soccothratesAI : public BossAI { - boss_wrath_scryer_soccothratesAI(Creature* creature) : BossAI(creature, DATA_SOCCOTHRATES) { } + boss_wrath_scryer_soccothratesAI(Creature* creature) : BossAI(creature, DATA_SOCCOTHRATES) + { + preFight = false; + dalliahTaunt = false; + dalliahDeath = false; + } void Reset() OVERRIDE { diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index e8108f03e7d..c100630a452 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -197,7 +197,7 @@ class spell_dk_anti_magic_zone : public SpellScriptLoader void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) { - SpellInfo const* talentSpell = sSpellMgr->GetSpellInfo(SPELL_DK_ANTI_MAGIC_SHELL_TALENT); + SpellInfo const* talentSpell = sSpellMgr->EnsureSpellInfo(SPELL_DK_ANTI_MAGIC_SHELL_TALENT); amount = talentSpell->Effects[EFFECT_0].CalcValue(GetCaster()); if (Player* player = GetCaster()->ToPlayer()) amount += int32(2 * player->GetTotalAttackPowerValue(BASE_ATTACK)); @@ -1424,7 +1424,7 @@ class spell_dk_will_of_the_necropolis : public SpellScriptLoader { // min pct of hp is stored in effect 0 of talent spell uint8 rank = GetSpellInfo()->GetRank(); - SpellInfo const* talentProto = sSpellMgr->GetSpellInfo(sSpellMgr->GetSpellWithRank(SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1, rank)); + SpellInfo const* talentProto = sSpellMgr->EnsureSpellInfo(sSpellMgr->GetSpellWithRank(SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1, rank)); int32 remainingHp = int32(GetTarget()->GetHealth() - dmgInfo.GetDamage()); int32 minHp = int32(GetTarget()->CountPctFromMaxHealth(talentProto->Effects[EFFECT_0].CalcValue(GetCaster()))); diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 9a81582b0b9..68c16a1b2d6 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1192,7 +1192,7 @@ class spell_gen_defend : public SpellScriptLoader void Register() OVERRIDE { - SpellInfo const* spell = sSpellMgr->GetSpellInfo(m_scriptSpellId); + SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(m_scriptSpellId); // Defend spells cast by NPCs (add visuals) if (spell->Effects[EFFECT_0].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN) @@ -2178,7 +2178,7 @@ class spell_gen_mounted_charge: public SpellScriptLoader void Register() OVERRIDE { - SpellInfo const* spell = sSpellMgr->GetSpellInfo(m_scriptSpellId); + SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(m_scriptSpellId); if (spell->HasEffect(SPELL_EFFECT_SCRIPT_EFFECT)) OnEffectHitTarget += SpellEffectFn(spell_gen_mounted_charge_SpellScript::HandleScriptEffect, EFFECT_FIRST_FOUND, SPELL_EFFECT_SCRIPT_EFFECT); diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index ba59f701445..5f03c64eaf1 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -176,7 +176,7 @@ class spell_mage_cold_snap : public SpellScriptLoader const SpellCooldowns& cm = caster->GetSpellCooldownMap(); for (SpellCooldowns::const_iterator itr = cm.begin(); itr != cm.end();) { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); + SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); if (spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfo->GetSchoolMask() & SPELL_SCHOOL_MASK_FROST) && @@ -388,7 +388,7 @@ class spell_mage_ignite : public SpellScriptLoader { PreventDefaultAction(); - SpellInfo const* igniteDot = sSpellMgr->GetSpellInfo(SPELL_MAGE_IGNITE); + SpellInfo const* igniteDot = sSpellMgr->EnsureSpellInfo(SPELL_MAGE_IGNITE); int32 pct = 8 * GetSpellInfo()->GetRank(); int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), pct) / igniteDot->GetMaxTicks()); diff --git a/src/server/scripts/Spells/spell_pet.cpp b/src/server/scripts/Spells/spell_pet.cpp index e50bc681352..491bb7100b2 100644 --- a/src/server/scripts/Spells/spell_pet.cpp +++ b/src/server/scripts/Spells/spell_pet.cpp @@ -897,7 +897,7 @@ public: if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value + SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value AddPct(mod, spellInfo->Effects[EFFECT_0].CalcValue()); } @@ -940,8 +940,7 @@ public: if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value - ASSERT(spellInfo); + SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value mod += CalculatePct(1.0f, spellInfo->Effects[EFFECT_1].CalcValue()); } @@ -971,8 +970,7 @@ public: if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value - ASSERT(spellInfo); + SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value mod += CalculatePct(1.0f, spellInfo->Effects[EFFECT_1].CalcValue()); } diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 03d5cbc3f06..f12a57aa2ec 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -236,8 +236,7 @@ class spell_pri_glyph_of_prayer_of_healing : public SpellScriptLoader { PreventDefaultAction(); - SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL); - ASSERT(triggeredSpellInfo); + SpellInfo const* triggeredSpellInfo = sSpellMgr->EnsureSpellInfo(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL); int32 heal = int32(CalculatePct(int32(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()) / triggeredSpellInfo->GetMaxTicks()); GetTarget()->CastCustomSpell(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL, SPELLVALUE_BASE_POINT0, heal, eventInfo.GetProcTarget(), true, NULL, aurEff); } diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index 1773805b671..4c1a4d096b9 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -428,8 +428,7 @@ class spell_rog_preparation : public SpellScriptLoader const SpellCooldowns& cm = caster->GetSpellCooldownMap(); for (SpellCooldowns::const_iterator itr = cm.begin(); itr != cm.end();) { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); - ASSERT(spellInfo); + SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE) { diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index b538d296c3d..0e3ada5d119 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -270,8 +270,7 @@ class spell_warl_demonic_circle_summon : public SpellScriptLoader // WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST; allowing him to cast the WARLOCK_DEMONIC_CIRCLE_TELEPORT. // If not in range remove the WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST. - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMONIC_CIRCLE_TELEPORT); - ASSERT(spellInfo); + SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(SPELL_WARLOCK_DEMONIC_CIRCLE_TELEPORT); if (GetTarget()->IsWithinDist(circle, spellInfo->GetMaxRange(true))) { @@ -362,8 +361,7 @@ class spell_warl_demonic_empowerment : public SpellScriptLoader break; case CREATURE_FAMILY_VOIDWALKER: { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER); - ASSERT(spellInfo); + SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER); int32 hp = int32(targetCreature->CountPctFromMaxHealth(GetCaster()->CalculateSpellDamage(targetCreature, spellInfo, 0))); targetCreature->CastCustomSpell(targetCreature, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER, &hp, NULL, NULL, true); //unitTarget->CastSpell(unitTarget, 54441, true); diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index d309051114c..d0ba39e8b09 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -273,8 +273,7 @@ class spell_warr_deep_wounds : public SpellScriptLoader damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE); - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC); - ASSERT(spellInfo); + SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC); uint32 ticks = spellInfo->GetDuration() / spellInfo->Effects[EFFECT_0].Amplitude; // Add remaining ticks to damage done -- cgit v1.2.3 From 0b615ec159eb5cb969bac92206d059c529642d8f Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Sat, 29 Mar 2014 20:58:25 +0100 Subject: Scripts/Misc: Small code optimizations --- .../BlackwingLair/boss_nefarian.cpp | 2 +- .../MoltenCore/boss_majordomo_executus.cpp | 2 +- .../SunwellPlateau/boss_kalecgos.cpp | 4 ++-- .../EasternKingdoms/ZulAman/boss_zuljin.cpp | 2 +- .../scripts/EasternKingdoms/zone_ghostlands.cpp | 2 +- src/server/scripts/Events/childrens_week.cpp | 2 +- src/server/scripts/Kalimdor/zone_darkshore.cpp | 2 +- src/server/scripts/Kalimdor/zone_silithus.cpp | 4 ++-- .../TrialOfTheChampion/trial_of_the_champion.cpp | 4 ++-- .../Northrend/DraktharonKeep/boss_novos.cpp | 2 +- .../HallsOfReflection/halls_of_reflection.cpp | 24 +++++++++++----------- .../IcecrownCitadel/boss_lady_deathwhisper.cpp | 2 +- .../Northrend/Nexus/EyeOfEternity/boss_malygos.cpp | 4 ++-- .../Northrend/Nexus/Nexus/boss_magus_telestra.cpp | 6 +++--- .../Northrend/Ulduar/Ulduar/boss_auriaya.cpp | 6 +++--- .../scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp | 2 +- .../scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp | 2 +- .../Northrend/Ulduar/Ulduar/boss_razorscale.cpp | 4 ++-- .../UtgardeKeep/UtgardePinnacle/boss_skadi.cpp | 2 +- .../scripts/Northrend/VioletHold/boss_zuramat.cpp | 2 +- .../scripts/Northrend/zone_borean_tundra.cpp | 2 +- .../scripts/Northrend/zone_howling_fjord.cpp | 4 ++-- src/server/scripts/Northrend/zone_icecrown.cpp | 2 +- .../scripts/Northrend/zone_sholazar_basin.cpp | 6 +++--- src/server/scripts/Northrend/zone_storm_peaks.cpp | 4 ++-- .../scripts/Outland/BlackTemple/black_temple.cpp | 4 ++-- .../Outland/BlackTemple/boss_teron_gorefiend.cpp | 2 +- .../BloodFurnace/boss_kelidan_the_breaker.cpp | 2 +- .../HellfireRamparts/boss_vazruden_the_herald.cpp | 2 +- .../scripts/Outland/TempestKeep/Eye/boss_alar.cpp | 2 +- 30 files changed, 55 insertions(+), 55 deletions(-) (limited to 'src/server/scripts/Northrend') diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp index 02662cd235c..fd56bf98274 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp @@ -342,7 +342,7 @@ public: nefarian->setActive(true); nefarian->SetCanFly(true); nefarian->SetDisableGravity(true); - nefarian->AI()->DoCastAOE(SPELL_SHADOWFLAME_INITIAL); + nefarian->CastSpell((Unit*)NULL, SPELL_SHADOWFLAME_INITIAL); nefarian->GetMotionMaster()->MovePoint(1, NefarianLoc[1]); } events.CancelEvent(EVENT_MIND_CONTROL); diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp index d2bd82447dc..653992cacdf 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp @@ -107,7 +107,7 @@ class boss_majordomo : public CreatureScript { instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, me->GetEntry(), me); me->setFaction(35); - me->AI()->EnterEvadeMode(); + EnterEvadeMode(); Talk(SAY_DEFEAT); _JustDied(); events.ScheduleEvent(EVENT_OUTRO_1, 32000); diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp index 294443da0e7..46bd5bcbfdc 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp @@ -234,7 +234,7 @@ public: { if (me->GetDistance(CENTER_X, CENTER_Y, DRAGON_REALM_Z) >= 75) { - me->AI()->EnterEvadeMode(); + EnterEvadeMode(); return; } if (HealthBelowPct(10) && !isEnraged) @@ -733,7 +733,7 @@ public: Creature* Kalecgos = ObjectAccessor::GetCreature(*me, KalecgosGUID); if (Kalecgos && !Kalecgos->IsInCombat()) { - me->AI()->EnterEvadeMode(); + EnterEvadeMode(); return; } diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp index dbdc0b8e5c7..9af8eeccc5c 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp @@ -346,7 +346,7 @@ class boss_zuljin : public CreatureScript } } else - me->AI()->AttackStart(me->GetVictim()); + AttackStart(me->GetVictim()); if (NextPhase == 3) { me->RemoveAurasDueToSpell(SPELL_ENERGY_STORM); diff --git a/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp b/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp index a4f75ea23d4..86fb1677526 100644 --- a/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp @@ -95,7 +95,7 @@ public: Summ1->Attack(me, true); Summ2->Attack(player, true); } - me->AI()->AttackStart(Summ1); + AttackStart(Summ1); } break; case 19: diff --git a/src/server/scripts/Events/childrens_week.cpp b/src/server/scripts/Events/childrens_week.cpp index 92e70cd028b..9a332fe335d 100644 --- a/src/server/scripts/Events/childrens_week.cpp +++ b/src/server/scripts/Events/childrens_week.cpp @@ -308,7 +308,7 @@ class npc_snowfall_glade_playmate : public CreatureScript break; case 4: orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_2); - orphan->AI()->DoCast(me, SPELL_SNOWBALL); + orphan->CastSpell(me, SPELL_SNOWBALL); timer = 5000; break; case 5: diff --git a/src/server/scripts/Kalimdor/zone_darkshore.cpp b/src/server/scripts/Kalimdor/zone_darkshore.cpp index ae98fbc4072..c19de7b8ab3 100644 --- a/src/server/scripts/Kalimdor/zone_darkshore.cpp +++ b/src/server/scripts/Kalimdor/zone_darkshore.cpp @@ -347,7 +347,7 @@ public: me->setFaction(FACTION_HOSTILE); if (Player* pHolder = GetLeaderForFollower()) - me->AI()->AttackStart(pHolder); + AttackStart(pHolder); SetFollowComplete(); } diff --git a/src/server/scripts/Kalimdor/zone_silithus.cpp b/src/server/scripts/Kalimdor/zone_silithus.cpp index 24d557222eb..ce5591ec5db 100644 --- a/src/server/scripts/Kalimdor/zone_silithus.cpp +++ b/src/server/scripts/Kalimdor/zone_silithus.cpp @@ -728,7 +728,7 @@ public: if (AnimationCount < 65) me->CombatStop(); if (AnimationCount == 65 || eventEnd) - me->AI()->EnterEvadeMode(); + EnterEvadeMode(); } }; @@ -830,7 +830,7 @@ public: } hasTarget = true; if (target) - me->AI()->AttackStart(target); + AttackStart(target); } if (!(me->FindNearestCreature(15379, 60))) DoCast(me, 33652); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp index a60e69d6479..8b6cbb340e5 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp @@ -357,7 +357,7 @@ public: if (instance->GetData(BOSS_ARGENT_CHALLENGE_E) == NOT_STARTED && instance->GetData(BOSS_ARGENT_CHALLENGE_P) == NOT_STARTED) { if (instance->GetData(BOSS_GRAND_CHAMPIONS) == NOT_STARTED) - me->AI()->SetData(DATA_START, 0); + SetData(DATA_START, 0); if (instance->GetData(BOSS_GRAND_CHAMPIONS) == DONE) DoStartArgentChampionEncounter(); @@ -452,7 +452,7 @@ public: case VEHICLE_ORGRIMMAR_WOLF: case VEHICLE_SILVERMOON_HAWKSTRIDER: case VEHICLE_DARKSPEAR_RAPTOR: - me->AI()->SetData(DATA_LESSER_CHAMPIONS_DEFEATED, 0); + SetData(DATA_LESSER_CHAMPIONS_DEFEATED, 0); break; } } diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp index 09db3f89c26..f84f288d55a 100644 --- a/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp +++ b/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp @@ -231,7 +231,7 @@ public: if (Creature* crystalChannelTarget = crystal->FindNearestCreature(NPC_CRYSTAL_CHANNEL_TARGET, 5.0f)) { if (active) - crystalChannelTarget->AI()->DoCastAOE(SPELL_BEAM_CHANNEL); + crystalChannelTarget->CastSpell((Unit*)NULL, SPELL_BEAM_CHANNEL); else if (crystalChannelTarget->HasUnitState(UNIT_STATE_CASTING)) crystalChannelTarget->CastStop(); } diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index de14b930220..af459729eb8 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -891,7 +891,7 @@ class npc_jaina_or_sylvanas_escape_hor : public CreatureScript if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) { lichking->AI()->Talk(SAY_LK_ESCAPE_3); - lichking->AI()->DoCast(me, SPELL_RAISE_DEAD); + lichking->CastSpell(me, SPELL_RAISE_DEAD); lichking->Attack(me, true); } _events.ScheduleEvent(EVENT_ESCAPE_13, 4000); @@ -899,15 +899,15 @@ class npc_jaina_or_sylvanas_escape_hor : public CreatureScript case EVENT_ESCAPE_13: if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) { - lichking->AI()->DoCast(lichking, SPELL_REMORSELESS_WINTER, true); - lichking->AI()->DoCast(lichking, SPELL_SUMMON_RISE_WITCH_DOCTOR); + lichking->CastSpell(lichking, SPELL_REMORSELESS_WINTER, true); + lichking->CastSpell(lichking, SPELL_SUMMON_RISE_WITCH_DOCTOR); lichking->GetMotionMaster()->MoveIdle(); lichking->GetMotionMaster()->MoveChase(me); } if (Creature* walltarget = me->SummonCreature(NPC_ICE_WALL, IceWalls[0], TEMPSUMMON_MANUAL_DESPAWN, 720000)) { _walltargetGUID = walltarget->GetGUID(); - walltarget->AI()->DoCast(walltarget, SPELL_SUMMON_ICE_WALL); + walltarget->CastSpell(walltarget, SPELL_SUMMON_ICE_WALL); walltarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); me->Attack(walltarget, false); } @@ -948,7 +948,7 @@ class npc_jaina_or_sylvanas_escape_hor : public CreatureScript { lichking->StopMoving(); lichking->AI()->Talk(SAY_LK_ESCAPE_3); - lichking->AI()->DoCast(me, SPELL_RAISE_DEAD); + lichking->CastSpell(me, SPELL_RAISE_DEAD); } DestroyIceWall(); @@ -969,7 +969,7 @@ class npc_jaina_or_sylvanas_escape_hor : public CreatureScript if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) { if (_icewall && _icewall < 4) - lichking->AI()->DoCast(lichking, SPELL_SUMMON_RISE_WITCH_DOCTOR); + lichking->CastSpell(lichking, SPELL_SUMMON_RISE_WITCH_DOCTOR); lichking->GetMotionMaster()->MoveIdle(); lichking->GetMotionMaster()->MoveChase(me); lichking->SetReactState(REACT_PASSIVE); @@ -980,7 +980,7 @@ class npc_jaina_or_sylvanas_escape_hor : public CreatureScript if (Creature* walltarget = me->SummonCreature(NPC_ICE_WALL, IceWalls[_icewall], TEMPSUMMON_MANUAL_DESPAWN, 720000)) { _walltargetGUID = walltarget->GetGUID(); - walltarget->AI()->DoCast(walltarget, SPELL_SUMMON_ICE_WALL); + walltarget->CastSpell(walltarget, SPELL_SUMMON_ICE_WALL); walltarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); me->Attack(walltarget, false); } @@ -1018,9 +1018,9 @@ class npc_jaina_or_sylvanas_escape_hor : public CreatureScript if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) { if (_icewall && _icewall < 3) - lichking->AI()->DoCast(lichking, SPELL_SUMMON_RISE_WITCH_DOCTOR); + lichking->CastSpell(lichking, SPELL_SUMMON_RISE_WITCH_DOCTOR); else - lichking->AI()->DoCast(lichking, SPELL_SUMMON_LUMBERING_ABOMINATION); + lichking->CastSpell(lichking, SPELL_SUMMON_LUMBERING_ABOMINATION); } if (_icewall == 3) _events.ScheduleEvent(EVENT_ESCAPE_21, 16000); // last wall, really far @@ -1036,10 +1036,10 @@ class npc_jaina_or_sylvanas_escape_hor : public CreatureScript if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) { if (_icewall == 1) - lichking->AI()->DoCast(lichking, SPELL_SUMMON_LUMBERING_ABOMINATION); + lichking->CastSpell(lichking, SPELL_SUMMON_LUMBERING_ABOMINATION); else if (_icewall > 1 && _icewall < 4) { - lichking->AI()->DoCast(lichking, SPELL_SUMMON_RISE_WITCH_DOCTOR); + lichking->CastSpell(lichking, SPELL_SUMMON_RISE_WITCH_DOCTOR); _events.ScheduleEvent(EVENT_ESCAPE_22, 1000); } } @@ -1048,7 +1048,7 @@ class npc_jaina_or_sylvanas_escape_hor : public CreatureScript if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) { if (_icewall >= 2 && _icewall < 4) - lichking->AI()->DoCast(lichking, SPELL_SUMMON_LUMBERING_ABOMINATION); + lichking->CastSpell(lichking, SPELL_SUMMON_LUMBERING_ABOMINATION); } break; case EVENT_ESCAPE_23: // FINAL PART diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp index f05f2c20b12..6b81bcc46a5 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp @@ -545,7 +545,7 @@ class boss_lady_deathwhisper : public CreatureScript void Summon(uint32 entry, const Position& pos) { if (TempSummon* summon = me->SummonCreature(entry, pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000)) - summon->AI()->DoCast(summon, SPELL_TELEPORT_VISUAL); + summon->CastSpell(summon, SPELL_TELEPORT_VISUAL); } void SetGUID(uint64 guid, int32 id/* = 0*/) OVERRIDE diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 1df92618a3a..54a84158437 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -544,7 +544,7 @@ public: break; case PHASE_TWO: events.ScheduleEvent(EVENT_MOVE_TO_POINT_SURGE_P_TWO, 60*IN_MILLISECONDS, 0, _phase); - me->AI()->DoAction(ACTION_LIFT_IN_AIR); + DoAction(ACTION_LIFT_IN_AIR); break; case PHASE_THREE: events.ScheduleEvent(EVENT_ARCANE_PULSE, 7*IN_MILLISECONDS, 0, _phase); @@ -2325,7 +2325,7 @@ class spell_malygos_surge_of_power_warning_selector_25 : public SpellScriptLoade void ExecuteMainSpell() { - GetCaster()->ToCreature()->AI()->DoCastAOE(SPELL_SURGE_OF_POWER_PHASE_3_25); + GetCaster()->ToCreature()->CastSpell((Unit*)NULL, SPELL_SURGE_OF_POWER_PHASE_3_25); } void Register() OVERRIDE diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp index cfa1b704c90..ee1524564a8 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp @@ -199,17 +199,17 @@ public: if (summon->GetGUID() == uiFireMagusGUID) { - me->AI()->DoAction(ACTION_MAGUS_DEAD); + DoAction(ACTION_MAGUS_DEAD); bFireMagusDead = true; } else if (summon->GetGUID() == uiFrostMagusGUID) { - me->AI()->DoAction(ACTION_MAGUS_DEAD); + DoAction(ACTION_MAGUS_DEAD); bFrostMagusDead = true; } else if (summon->GetGUID() == uiArcaneMagusGUID) { - me->AI()->DoAction(ACTION_MAGUS_DEAD); + DoAction(ACTION_MAGUS_DEAD); bArcaneMagusDead = true; } } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp index a809eb4ddff..63d498de5eb 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp @@ -364,7 +364,7 @@ class npc_sanctum_sentry : public CreatureScript if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) { me->AddThreat(target, 100.0f); - me->AI()->AttackStart(target); + AttackStart(target); DoCast(target, SPELL_SAVAGE_POUNCE); } events.ScheduleEvent(EVENT_POUNCE, urand(12000, 17000)); @@ -430,7 +430,7 @@ class npc_feral_defender : public CreatureScript if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) { me->AddThreat(target, 100.0f); - me->AI()->AttackStart(target); + AttackStart(target); DoCast(target, SPELL_FERAL_POUNCE); } events.ScheduleEvent(EVENT_FERAL_POUNCE, urand(10000, 12000)); @@ -439,7 +439,7 @@ class npc_feral_defender : public CreatureScript if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) { me->AddThreat(target, 100.0f); - me->AI()->AttackStart(target); + AttackStart(target); DoCast(target, SPELL_FERAL_RUSH); } events.ScheduleEvent(EVENT_RUSH, urand(10000, 12000)); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp index 64ee385b7fc..7f3e6485eaf 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp @@ -1069,7 +1069,7 @@ class npc_detonating_lasher : public CreatureScript { // Switching to other target - modify aggro of new target by 20% from current target's aggro me->AddThreat(target, me->getThreatManager().getThreat(me->GetVictim(), false) * 1.2f); - me->AI()->AttackStart(target); + AttackStart(target); } changeTargetTimer = urand(5000, 10000); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp index 169a7085672..578a51fa1f8 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp @@ -455,7 +455,7 @@ class boss_hodir : public CreatureScript if (Unit* target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid())) if (Aura* BitingColdAura = target->GetAura(SPELL_BITING_COLD_TRIGGERED)) if ((target->GetTypeId() == TYPEID_PLAYER) && (BitingColdAura->GetStackAmount() > 2)) - me->AI()->SetData(DATA_GETTING_COLD_IN_HERE, 0); + SetData(DATA_GETTING_COLD_IN_HERE, 0); gettingColdInHereTimer = 1000; } else diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp index e96cfaccc56..d1ed15bf8dd 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp @@ -211,8 +211,8 @@ class boss_razorscale_controller : public CreatureScript Harpoon3->RemoveFromWorld(); if (GameObject* Harpoon4 = ObjectAccessor::GetGameObject(*me, instance->GetData64(GO_RAZOR_HARPOON_4))) Harpoon4->RemoveFromWorld(); - me->AI()->DoAction(ACTION_HARPOON_BUILD); - me->AI()->DoAction(ACTION_PLACE_BROKEN_HARPOON); + DoAction(ACTION_HARPOON_BUILD); + DoAction(ACTION_PLACE_BROKEN_HARPOON); break; case SPELL_HARPOON_SHOT_1: case SPELL_HARPOON_SHOT_2: diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp index b6438008dde..e9cf806118f 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp @@ -291,7 +291,7 @@ public: m_uiCrushTimer = 8000; m_uiPoisonedSpearTimer = 10000; m_uiWhirlwindTimer = 20000; - me->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM)); + AttackStart(SelectTarget(SELECT_TARGET_RANDOM)); } } } diff --git a/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp b/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp index 6835228ca46..746680e32e6 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp @@ -189,7 +189,7 @@ public: void JustSummoned(Creature* summon) OVERRIDE { summon->AI()->AttackStart(me->GetVictim()); - summon->AI()->DoCastAOE(SPELL_ZURAMAT_ADD_2); + summon->CastSpell((Unit*)NULL, SPELL_ZURAMAT_ADD_2); summon->SetPhaseMask(17, true); } }; diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index f7f473297ef..6ea4490c79d 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -2415,7 +2415,7 @@ public: { me->setFaction(14); if (Player* player = ObjectAccessor::GetPlayer(*me, uiPlayerGUID)) - me->AI()->AttackStart(player); + AttackStart(player); } void UpdateAI(uint32 uiDiff) OVERRIDE diff --git a/src/server/scripts/Northrend/zone_howling_fjord.cpp b/src/server/scripts/Northrend/zone_howling_fjord.cpp index 798801041f4..fd51237745e 100644 --- a/src/server/scripts/Northrend/zone_howling_fjord.cpp +++ b/src/server/scripts/Northrend/zone_howling_fjord.cpp @@ -458,10 +458,10 @@ class spell_mindless_abomination_explosion_fx_master : public SpellScriptLoader if (!caster) return; - caster->AI()->DoCast(caster, SPELL_COSMETIC_BLOOD_EXPLOSION_GREEN_LARGE); + caster->CastSpell(caster, SPELL_COSMETIC_BLOOD_EXPLOSION_GREEN_LARGE); for (uint8 i = 0; i < 10; ++i) - caster->AI()->DoCast(caster, SPELL_RANDOM_CIRCUMFERENCE_POINT_POISON); + caster->CastSpell(caster, SPELL_RANDOM_CIRCUMFERENCE_POINT_POISON); caster->DespawnOrUnsummon(4000); } diff --git a/src/server/scripts/Northrend/zone_icecrown.cpp b/src/server/scripts/Northrend/zone_icecrown.cpp index f7894c58b3e..5284803c5f2 100644 --- a/src/server/scripts/Northrend/zone_icecrown.cpp +++ b/src/server/scripts/Northrend/zone_icecrown.cpp @@ -527,7 +527,7 @@ public: { me->setRegeneratingHealth(false); DoCast(SPELL_THREAT_PULSE); - me->AI()->Talk(BANNER_SAY); + Talk(BANNER_SAY); events.ScheduleEvent(EVENT_SPAWN, 3000); } diff --git a/src/server/scripts/Northrend/zone_sholazar_basin.cpp b/src/server/scripts/Northrend/zone_sholazar_basin.cpp index 0298500e790..6e39d341c58 100644 --- a/src/server/scripts/Northrend/zone_sholazar_basin.cpp +++ b/src/server/scripts/Northrend/zone_sholazar_basin.cpp @@ -1003,7 +1003,7 @@ enum ReconnaissanceFlight VIC_SAY_6 = 6, PLANE_EMOTE = 0, - AURA_ENGINE = 52255, // Engine on Fire + SPELL_ENGINE = 52255, // Engine on Fire SPELL_LAND = 52226, // Land Flying Machine SPELL_CREDIT = 53328 // Land Flying Machine Credit @@ -1054,8 +1054,8 @@ public: pilot->AI()->Talk(VIC_SAY_6); break; case 25: - me->AI()->Talk(PLANE_EMOTE); - me->AI()->DoCast(AURA_ENGINE); + Talk(PLANE_EMOTE); + DoCast(SPELL_ENGINE); break; } } diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp index bd80de627a8..838fa44ded4 100644 --- a/src/server/scripts/Northrend/zone_storm_peaks.cpp +++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp @@ -504,7 +504,7 @@ public: me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); if (Creature* voice = ObjectAccessor::GetCreature(*me, voiceGUID)) { - voice->AI()->DoCast(voice, SPELL_RESURRECTION); + voice->CastSpell(voice, SPELL_RESURRECTION); if (Player* player = ObjectAccessor::GetPlayer(*me, playerGUID)) voice->AI()->Talk(SAY_VOICE_1, player); } @@ -546,7 +546,7 @@ public: break; case EVENT_SCRIPT_9: if (Creature* voice = ObjectAccessor::GetCreature(*me, voiceGUID)) - voice->AI()->DoCast(voice, SPELL_RESURRECTION); + voice->CastSpell(voice, SPELL_RESURRECTION); events.ScheduleEvent(EVENT_SCRIPT_10, 6000); break; case EVENT_SCRIPT_10: diff --git a/src/server/scripts/Outland/BlackTemple/black_temple.cpp b/src/server/scripts/Outland/BlackTemple/black_temple.cpp index ba8eb2194f5..c45a1a4f391 100644 --- a/src/server/scripts/Outland/BlackTemple/black_temple.cpp +++ b/src/server/scripts/Outland/BlackTemple/black_temple.cpp @@ -156,11 +156,11 @@ public: { for (std::list::const_iterator itr = bloodmage.begin(); itr != bloodmage.end(); ++itr) if (Creature* bloodmage = (Unit::GetCreature(*me, *itr))) - bloodmage->AI()->DoCast(SPELL_SUMMON_CHANNEL); + bloodmage->CastSpell((Unit*)NULL, SPELL_SUMMON_CHANNEL); for (std::list::const_iterator itr = deathshaper.begin(); itr != deathshaper.end(); ++itr) if (Creature* deathshaper = (Unit::GetCreature(*me, *itr))) - deathshaper->AI()->DoCast(SPELL_SUMMON_CHANNEL); + deathshaper->CastSpell((Unit*)NULL, SPELL_SUMMON_CHANNEL); events.ScheduleEvent(EVENT_SET_CHANNELERS, 12000); diff --git a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp index 8deac58461c..b95af29a43e 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp @@ -186,7 +186,7 @@ public: if (target && me->IsWithinDistInMap(target, me->GetAttackDistance(target))) { DoCast(target, SPELL_ATROPHY); - me->AI()->AttackStart(target); + AttackStart(target); } } diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp index 4c04c06b091..e9a8a68b116 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp @@ -135,7 +135,7 @@ class boss_kelidan_the_breaker : public CreatureScript me->SetReactState(REACT_AGGRESSIVE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE); if (killer) - me->AI()->AttackStart(killer); + AttackStart(killer); } uint64 GetChanneled(Creature* channeler1) diff --git a/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp b/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp index 1193e45e73b..205158f606e 100644 --- a/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp @@ -134,7 +134,7 @@ class boss_nazan : public CreatureScript me->SetWalk(true); me->GetMotionMaster()->Clear(); if (Unit* victim = SelectTarget(SELECT_TARGET_NEAREST, 0)) - me->AI()->AttackStart(victim); + AttackStart(victim); DoStartMovement(me->GetVictim()); Talk(EMOTE); return; diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp index a961800025d..00c4577dab6 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp @@ -435,7 +435,7 @@ class boss_alar : public CreatureScript Unit* target = NULL; target = me->SelectNearestTargetInAttackDistance(5); if (target) - me->AI()->AttackStart(target); + AttackStart(target); else { DoCast(me, SPELL_FLAME_BUFFET, true); -- cgit v1.2.3 From f47962f6707bb53a3241d23257a5bbd1b2679f87 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Mon, 31 Mar 2014 20:59:33 +0200 Subject: Core/Misc: Fix some static analysis issues Add some asserts and additional NULL checks as sanity checks. --- src/server/game/Entities/Object/Object.cpp | 1 + src/server/game/Spells/Auras/SpellAuraEffects.cpp | 1 + src/server/scripts/Commands/cs_go.cpp | 1 + .../Ulduar/Ulduar/boss_flame_leviathan.cpp | 24 ++++++++++++---------- 4 files changed, 16 insertions(+), 11 deletions(-) (limited to 'src/server/scripts/Northrend') diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 12c8d0ba2ac..69f7073ce1b 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -350,6 +350,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const // 0x20 if (flags & UPDATEFLAG_LIVING) { + ASSERT(unit); unit->BuildMovementPacket(data); *data << unit->GetSpeed(MOVE_WALK) diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 4ed742167a5..06bd12911ad 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -1824,6 +1824,7 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo if (target->GetTypeId() == TYPEID_PLAYER) { SpellShapeshiftEntry const* shapeInfo = sSpellShapeshiftStore.LookupEntry(form); + ASSERT(shapeInfo); // Learn spells for shapeshift form - no need to send action bars or add spells to spellbook for (uint8 i = 0; izone ? GetAreaEntryByAreaID(areaEntry->zone) : areaEntry; + ASSERT(zoneEntry); Map const* map = sMapMgr->CreateBaseMap(zoneEntry->mapid); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp index ee1345590f3..96d759f79fb 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp @@ -589,17 +589,19 @@ class boss_flame_leviathan_seat : public CreatureScript else if (Creature* leviathan = me->GetVehicleCreatureBase()) leviathan->AI()->Talk(SAY_PLAYER_RIDING); - if (Creature* turret = me->GetVehicleKit()->GetPassenger(SEAT_TURRET)->ToCreature()) - { - turret->setFaction(me->GetVehicleBase()->getFaction()); - turret->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable - turret->AI()->AttackStart(who); - } - if (Creature* device = me->GetVehicleKit()->GetPassenger(SEAT_DEVICE)->ToCreature()) - { - device->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); - device->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } + if (Unit* turretPassenger = me->GetVehicleKit()->GetPassenger(SEAT_TURRET)) + if (Creature* turret = turretPassenger->ToCreature()) + { + turret->setFaction(me->GetVehicleBase()->getFaction()); + turret->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable + turret->AI()->AttackStart(who); + } + if (Unit* devicePassenger = me->GetVehicleKit()->GetPassenger(SEAT_DEVICE)) + if (Creature* device = device->ToCreature()) + { + device->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); + device->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } -- cgit v1.2.3 From 10ba63cf3d93c4a3ed934b1e1d59b3f85ad942be Mon Sep 17 00:00:00 2001 From: jackpoz Date: Mon, 31 Mar 2014 21:10:29 +0200 Subject: Core/Misc: Fix typo in f47962f6707bb53a3241d23257a5bbd1b2679f87 --- src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server/scripts/Northrend') diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp index 96d759f79fb..aa0c67c30bd 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp @@ -597,7 +597,7 @@ class boss_flame_leviathan_seat : public CreatureScript turret->AI()->AttackStart(who); } if (Unit* devicePassenger = me->GetVehicleKit()->GetPassenger(SEAT_DEVICE)) - if (Creature* device = device->ToCreature()) + if (Creature* device = devicePassenger->ToCreature()) { device->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); device->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); -- cgit v1.2.3 From 0930482fa4ac8f65d64c4b99e8c1589050a8c162 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Tue, 1 Apr 2014 22:49:15 +0200 Subject: Core/Misc: Fix uninitialized values Fix Position members not being always initialized. Valgrind log: at : Position::NormalizeOrientation(float) (Object.h:388) by : Position::SetOrientation(float) (Object.h:315) by : Position::Relocate(Position const&) (Object.h:310) by : spell_ulduar_stone_grip::spell_ulduar_stone_grip_AuraScript::OnRemoveVehicle(AuraEffect const*, AuraEffectHandleModes) (boss_kologarn.cpp:592) --- src/server/game/Entities/Object/Object.h | 7 ++++++- src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp | 2 ++ src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp | 2 ++ .../Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp | 2 ++ 4 files changed, 12 insertions(+), 1 deletion(-) (limited to 'src/server/scripts/Northrend') diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 8d3b1ff9554..d55e357de1d 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -273,6 +273,11 @@ class Object struct Position { + Position(float x = 0, float y = 0, float z = 0, float o = 0) + : m_positionX(x), m_positionY(y), m_positionZ(z), m_orientation(NormalizeOrientation(o)) { } + + Position(const Position &loc) { Relocate(loc); } + struct PositionXYZStreamer { explicit PositionXYZStreamer(Position& pos) : m_pos(&pos) { } @@ -479,7 +484,7 @@ class WorldLocation : public Position public: explicit WorldLocation(uint32 _mapid = MAPID_INVALID, float _x = 0, float _y = 0, float _z = 0, float _o = 0) : m_mapId(_mapid) { Relocate(_x, _y, _z, _o); } - WorldLocation(const WorldLocation &loc) { WorldRelocate(loc); } + WorldLocation(const WorldLocation &loc) : Position(loc) { WorldRelocate(loc); } void WorldRelocate(const WorldLocation &loc) { m_mapId = loc.GetMapId(); Relocate(loc); } diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp index e0771b0ebe2..a12a400ea8e 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp @@ -208,11 +208,13 @@ class boss_ayamiss : public CreatureScript events.ScheduleEvent(EVENT_SWARMER_ATTACK, 60000); break; case EVENT_SUMMON_SWARMER: + { Position Pos; me->GetRandomPoint(SwarmerPos, 80.0f, Pos); me->SummonCreature(NPC_SWARMER, Pos); events.ScheduleEvent(EVENT_SUMMON_SWARMER, 5000); break; + } case EVENT_TRASH: DoCastVictim(SPELL_TRASH); events.ScheduleEvent(EVENT_TRASH, urand(5000, 7000)); diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 54a84158437..fd2734f55ba 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -469,6 +469,7 @@ public: DoCast(me, SPELL_VORTEX_3, true); break; case ACTION_LIFT_IN_AIR: + { Position _zToLift; me->GetPosition(&_zToLift); if (_phase == PHASE_ONE) @@ -482,6 +483,7 @@ public: me->GetMotionMaster()->MoveTakeoff(POINT_PHASE_ONE_TO_TWO_TRANSITION, _zToLift); } break; + } case ACTION_HANDLE_P_THREE_INTRO: events.CancelEventGroup(0); events.CancelEventGroup(1); diff --git a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp index b15318647a9..1135a95e92b 100644 --- a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp +++ b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp @@ -132,11 +132,13 @@ class boss_mechano_lord_capacitus : public CreatureScript events.ScheduleEvent(EVENT_POSITIVE_SHIFT, urand(45, 60) * IN_MILLISECONDS); break; case EVENT_SUMMON_NETHER_CHARGE: + { Position pos; me->GetRandomNearPosition(pos, 5.0f); me->SummonCreature(NPC_NETHER_CHARGE, pos, TEMPSUMMON_TIMED_DESPAWN, 18000); events.ScheduleEvent(EVENT_SUMMON_NETHER_CHARGE, 10 * IN_MILLISECONDS); break; + } case EVENT_BERSERK: DoCast(me, SPELL_BERSERK); break; -- cgit v1.2.3