From b000fdca70547a3e1963292e39ff9ebb596e099a Mon Sep 17 00:00:00 2001 From: joschiwald Date: Thu, 6 Feb 2014 21:23:18 +0100 Subject: Core/Entities: allow interaction with gameobject questgivers if player can take or return quests Closes #11269 Closes #8898 Closes #10204 Closes #11410 Closes #7053 Closes #6189 Closes #9474 --- src/server/scripts/Commands/cs_quest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server/scripts') diff --git a/src/server/scripts/Commands/cs_quest.cpp b/src/server/scripts/Commands/cs_quest.cpp index 01e28b0910d..369a8e87289 100644 --- a/src/server/scripts/Commands/cs_quest.cpp +++ b/src/server/scripts/Commands/cs_quest.cpp @@ -147,7 +147,7 @@ public: } } - player->RemoveActiveQuest(entry); + player->RemoveActiveQuest(entry, false); player->RemoveRewardedQuest(entry); handler->SendSysMessage(LANG_COMMAND_QUEST_REMOVED); -- cgit v1.2.3 From aaa4b3a1240b7b25a4050a7c6d3dc5184f3e581d Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sat, 8 Feb 2014 17:22:29 +0100 Subject: Scripts/Eastern Plaguelands: Fix flypath exploit Fix npc id 17209 in Eastern Plaguelands enabling taxi cheat to players just by talking to it. --- src/server/scripts/World/npc_taxi.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/server/scripts') diff --git a/src/server/scripts/World/npc_taxi.cpp b/src/server/scripts/World/npc_taxi.cpp index 730523c85f4..31617e0ef71 100644 --- a/src/server/scripts/World/npc_taxi.cpp +++ b/src/server/scripts/World/npc_taxi.cpp @@ -162,7 +162,6 @@ public: player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CRIMSONWING, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+25); break; case 17209: - player->SetTaxiCheater(true); player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WILLIAMKEILAR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 28); player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WILLIAMKEILAR2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 29); player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WILLIAMKEILAR3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 30); -- cgit v1.2.3 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 --- .../world/2014_02_09_05_world_conditions.sql | 3 + .../AzjolNerub/boss_krikthir_the_gatewatcher.cpp | 761 ++++++++++++--------- 2 files changed, 438 insertions(+), 326 deletions(-) create mode 100644 sql/updates/world/2014_02_09_05_world_conditions.sql (limited to 'src/server/scripts') diff --git a/sql/updates/world/2014_02_09_05_world_conditions.sql b/sql/updates/world/2014_02_09_05_world_conditions.sql new file mode 100644 index 00000000000..6241c62417c --- /dev/null +++ b/sql/updates/world/2014_02_09_05_world_conditions.sql @@ -0,0 +1,3 @@ +DELETE FROM `conditions` WHERE `SourceEntry` = 52446 AND `SourceTypeOrReferenceId` = 13; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `Comment`) VALUES +(13,1,52446,0,0,31,0,3,28684,0,1,0,0,"Spell Acid Splash cannot hit Krik'thir the Gatewatcher (28684)"); 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') 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') 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 b72273014f2f290f9524a3f9b1596528773da9fb Mon Sep 17 00:00:00 2001 From: joschiwald Date: Mon, 10 Feb 2014 00:14:29 +0100 Subject: Core/DB/Achievements: - fixed arena season title achievements and rewards - added mailtemplate support for `achievement_reward` table - fixed typo in GetBattleMasterBG which causes achievement reward mail expire in 1 day Ref #8777 --- .../world/2014_02_09_06_world_achievements.sql | 68 +++++++++++++++++++++ src/server/game/Achievements/AchievementMgr.cpp | 70 ++++++++++++++-------- src/server/game/Achievements/AchievementMgr.h | 1 + src/server/game/Battlegrounds/BattlegroundMgr.cpp | 26 ++++++++ src/server/game/Battlegrounds/BattlegroundMgr.h | 3 +- src/server/game/DataStores/DBCStructure.h | 6 +- src/server/game/DataStores/DBCfmt.h | 2 +- src/server/game/Globals/ObjectMgr.cpp | 1 + src/server/game/Mails/Mail.cpp | 2 + src/server/game/Maps/MapManager.cpp | 8 +-- src/server/game/Miscellaneous/SharedDefines.h | 2 +- src/server/game/World/World.cpp | 2 +- src/server/scripts/Commands/cs_character.cpp | 2 +- src/server/scripts/Commands/cs_lookup.cpp | 5 +- src/server/scripts/Commands/cs_titles.cpp | 6 +- 15 files changed, 162 insertions(+), 42 deletions(-) create mode 100644 sql/updates/world/2014_02_09_06_world_achievements.sql (limited to 'src/server/scripts') diff --git a/sql/updates/world/2014_02_09_06_world_achievements.sql b/sql/updates/world/2014_02_09_06_world_achievements.sql new file mode 100644 index 00000000000..a64799b48df --- /dev/null +++ b/sql/updates/world/2014_02_09_06_world_achievements.sql @@ -0,0 +1,68 @@ +ALTER TABLE `achievement_reward` + ADD COLUMN `mailTemplate` MEDIUMINT(8) UNSIGNED DEFAULT 0 NULL AFTER `text`; + +DELETE FROM `disables` WHERE `sourceType`=4 AND `entry`=11238; +INSERT INTO `disables` (`sourceType`, `entry`, `comment`) VALUES +(4,11238, 'Achievement: Jade Tiger'); + +DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (5597,5599,5600,6789,7408,7412,7415,7416,7418,7419,9058,9718,9719,9720,9721,10718,10878,10879,10881,10898,11238,11402,12562,12912,12999,13000,13001,13002,13003,13004,13005,13006,13007); +INSERT INTO `achievement_criteria_data` (`criteria_id`, `type`, `value1`, `value2`, `ScriptName`) VALUES +(5597, 23, 62, 0, ''), -- Merciless Gladiator Season 2 +(5599, 23, 71, 0, ''), -- Vengeful Gladiator Season 3 +(5600, 23, 80, 0, ''), -- Brutal Gladiator Season 4 +(6789, 23, 53, 0, ''), -- Champion of the Naaru +(7408, 23, 45, 0, ''), -- Challenger +(7412, 23, 42, 0, ''), -- Gladiator +(7415, 23, 43, 0, ''), -- Duelist - Duelist +(7416, 23, 42, 0, ''), -- Duelist - Gladiator +(7418, 23, 44, 0, ''), -- Rival - Rival +(7419, 23, 43, 0, ''), -- Rival - Duelist +(9058, 22, 4, 0, ''), -- 4th Anniversary +(9718, 23, 42, 0, ''), -- Rival - Gladiator +(9719, 23, 44, 0, ''), -- Challenger - Rival +(9720, 23, 43, 0, ''), -- Challenger - Duelist +(9721, 23, 42, 0, ''), -- Challenger - Gladiator +(10718, 23, 157, 0, ''), -- Deadly Gladiator Season 5 +(10878, 23, 157, 0, ''), -- Challenger - Deadly Gladiator +(10879, 23, 157, 0, ''), -- Rival - Deadly Gladiator +(10881, 23, 157, 0, ''), -- Gladiator - Deadly Gladiator +(10898, 23, 167, 0, ''), -- Furious Gladiator Season 6 +-- (11238, 0, 0, 0, ''), -- Jade Tiger +(11402, 23, 169, 0, ''), -- Relentless Gladiator Season 7 +(12562, 22, 5, 0, ''), -- 5th Anniversary +(12912, 23, 177, 0, ''), -- Wrathful Gladiator Season 8 +(12999, 23, 167, 0, ''), -- Gladiator - Furious Gladiator +(13000, 23, 169, 0, ''), -- Gladiator - Relentless Gladiator +(13001, 23, 157, 0, ''), -- Duelist - Deadly Gladiator +(13002, 23, 167, 0, ''), -- Duelist - Furious Gladiator +(13003, 23, 169, 0, ''), -- Duelist - Relentless Gladiator +(13004, 23, 167, 0, ''), -- Rival - Furious Gladiator +(13005, 23, 169, 0, ''), -- Rival - Relentless Gladiator +(13006, 23, 167, 0, ''), -- Challenger - Furious Gladiator +(13007, 23, 169, 0, ''); -- Challenger - Relentless Gladiator + +DELETE FROM `achievement_reward` WHERE `entry` IN (432,2090,2091,2092,2093); +INSERT INTO `achievement_reward` (`entry`, `title_A`, `title_H`) VALUES +( 432,53,53), -- Champion of the Naaru +(2090,45,45), -- Challenger +(2091,42,42), -- Gladiator +(2092,43,43), -- Duelist +(2093,44,44); -- Rival + +DELETE FROM `achievement_reward` WHERE `entry` IN (419,420,3336,3436,3758,4599); +INSERT INTO `achievement_reward` (`entry`, `sender`, `mailTemplate`) VALUES +( 419,18897,211), -- Vengeful Gladiator +( 420,18897,262), -- Brutal Gladiator +(3336,18897,266), -- Deadly Gladiator +(3436,18897,267), -- Furious Gladiator +(3758,18897,286), -- Relentless Gladiator +(4599,18897,287); -- Wrathful Gladiator + +DELETE FROM `mail_loot_template` WHERE `entry` IN (211,262,266,267,286,287); +INSERT INTO `mail_loot_template` (`entry`,`item`,`ChanceOrQuestChance`,`lootmode`,`groupid`,`mincountOrRef`,`maxcount`) VALUES +(211,37676,100,1,0,1,1), -- Vengeful Gladiator +(262,43516,100,1,0,1,1), -- Brutal Gladiator +(266,46708,100,1,0,1,1), -- Deadly Gladiator +(267,46171,100,1,0,1,1), -- Furious Gladiator +(286,47840,100,1,0,1,1), -- Relentless Gladiator +(287,50435,100,1,0,1,1); -- Wrathful Gladiator diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index b98ff3e4f01..a99da4050f6 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -297,7 +297,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE: if (!sCharTitlesStore.LookupEntry(known_title.title_id)) { - TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_requirement` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE (%u) have unknown title_id in value1 (%u), ignore.", + TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE (%u) have unknown title_id in value1 (%u), ignore.", criteria->ID, criteria->requiredType, dataType, known_title.title_id); return false; } @@ -400,7 +400,7 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un { TC_LOG_ERROR("achievement", "Achievement system call ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT (%u) for achievement criteria %u for non-dungeon/non-raid map %u", dataType, criteria_id, map->GetId()); - return false; + return false; } InstanceScript* instance = map->ToInstanceMap()->GetInstanceScript(); if (!instance) @@ -2082,25 +2082,30 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) // mail if (reward->sender) { - Item* item = reward->itemId ? Item::CreateItem(reward->itemId, 1, GetPlayer()) : NULL; + MailDraft draft(reward->mailTemplate); - int loc_idx = GetPlayer()->GetSession()->GetSessionDbLocaleIndex(); - - // subject and text - std::string subject = reward->subject; - std::string text = reward->text; - if (loc_idx >= 0) + if (!reward->mailTemplate) { - if (AchievementRewardLocale const* loc = sAchievementMgr->GetAchievementRewardLocale(achievement)) + // subject and text + std::string subject = reward->subject; + std::string text = reward->text; + + int locIdx = GetPlayer()->GetSession()->GetSessionDbLocaleIndex(); + if (locIdx >= 0) { - ObjectMgr::GetLocaleString(loc->subject, loc_idx, subject); - ObjectMgr::GetLocaleString(loc->text, loc_idx, text); + if (AchievementRewardLocale const* loc = sAchievementMgr->GetAchievementRewardLocale(achievement)) + { + ObjectMgr::GetLocaleString(loc->subject, locIdx, subject); + ObjectMgr::GetLocaleString(loc->text, locIdx, text); + } } - } - MailDraft draft(subject, text); + draft = MailDraft(subject, text); + } SQLTransaction trans = CharacterDatabase.BeginTransaction(); + + Item* item = reward->itemId ? Item::CreateItem(reward->itemId, 1, GetPlayer()) : NULL; if (item) { // save new item before send @@ -2441,8 +2446,8 @@ void AchievementGlobalMgr::LoadRewards() m_achievementRewards.clear(); // need for reload case - // 0 1 2 3 4 5 6 - QueryResult result = WorldDatabase.Query("SELECT entry, title_A, title_H, item, sender, subject, text FROM achievement_reward"); + // 0 1 2 3 4 5 6 7 + QueryResult result = WorldDatabase.Query("SELECT entry, title_A, title_H, item, sender, subject, text, mailTemplate FROM achievement_reward"); if (!result) { @@ -2456,20 +2461,21 @@ void AchievementGlobalMgr::LoadRewards() { Field* fields = result->Fetch(); uint32 entry = fields[0].GetUInt32(); - const AchievementEntry* pAchievement = GetAchievement(entry); - if (!pAchievement) + AchievementEntry const* achievement = GetAchievement(entry); + if (!achievement) { TC_LOG_ERROR("sql.sql", "Table `achievement_reward` has wrong achievement (Entry: %u), ignored.", entry); continue; } AchievementReward reward; - reward.titleId[0] = fields[1].GetUInt32(); - reward.titleId[1] = fields[2].GetUInt32(); - reward.itemId = fields[3].GetUInt32(); - reward.sender = fields[4].GetUInt32(); - reward.subject = fields[5].GetString(); - reward.text = fields[6].GetString(); + reward.titleId[0] = fields[1].GetUInt32(); + reward.titleId[1] = fields[2].GetUInt32(); + reward.itemId = fields[3].GetUInt32(); + reward.sender = fields[4].GetUInt32(); + reward.subject = fields[5].GetString(); + reward.text = fields[6].GetString(); + reward.mailTemplate = fields[7].GetUInt32(); // must be title or mail at least if (!reward.titleId[0] && !reward.titleId[1] && !reward.sender) @@ -2478,7 +2484,7 @@ void AchievementGlobalMgr::LoadRewards() continue; } - if (pAchievement->requiredFaction == ACHIEVEMENT_FACTION_ANY && ((reward.titleId[0] == 0) != (reward.titleId[1] == 0))) + if (achievement->requiredFaction == ACHIEVEMENT_FACTION_ANY && (!reward.titleId[0] ^ !reward.titleId[1])) TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) has title (A: %u H: %u) for only one team.", entry, reward.titleId[0], reward.titleId[1]); if (reward.titleId[0]) @@ -2520,6 +2526,20 @@ void AchievementGlobalMgr::LoadRewards() if (!reward.text.empty()) TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) does not have sender data but has mail text.", entry); + + if (reward.mailTemplate) + TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) does not have sender data but has mailTemplate.", entry); + } + + if (reward.mailTemplate) + { + if (!sMailTemplateStore.LookupEntry(reward.mailTemplate)) + { + TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) has invalid mailTemplate (%u).", entry, reward.mailTemplate); + reward.mailTemplate = 0; + } + else if (!reward.subject.empty() || !reward.text.empty()) + TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) has mailTemplate (%u) and mail subject/text.", entry, reward.mailTemplate); } if (reward.itemId) diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h index c4216b2ee74..0a3e711e2ef 100644 --- a/src/server/game/Achievements/AchievementMgr.h +++ b/src/server/game/Achievements/AchievementMgr.h @@ -233,6 +233,7 @@ struct AchievementReward uint32 sender; std::string subject; std::string text; + uint32 mailTemplate; }; typedef UNORDERED_MAP AchievementRewards; diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index 9d7a67ee0dc..ab69c950ff4 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -1082,6 +1082,17 @@ void BattlegroundMgr::LoadBattleMastersEntry() Field* fields = result->Fetch(); uint32 entry = fields[0].GetUInt32(); + if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(entry)) + { + if ((cInfo->npcflag & UNIT_NPC_FLAG_BATTLEMASTER) == 0) + TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) listed in `battlemaster_entry` is not a battlemaster.", entry); + } + else + { + TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) listed in `battlemaster_entry` does not exist.", entry); + continue; + } + uint32 bgTypeId = fields[1].GetUInt32(); if (!sBattlemasterListStore.LookupEntry(bgTypeId)) { @@ -1093,9 +1104,24 @@ void BattlegroundMgr::LoadBattleMastersEntry() } while (result->NextRow()); + CheckBattleMasters(); + TC_LOG_INFO("server.loading", ">> Loaded %u battlemaster entries in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } +void BattlegroundMgr::CheckBattleMasters() +{ + CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates(); + for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr) + { + if ((itr->second.npcflag & UNIT_NPC_FLAG_BATTLEMASTER) && mBattleMastersMap.find(itr->second.Entry) == mBattleMastersMap.end()) + { + TC_LOG_ERROR("sql.sql", "CreatureTemplate (Entry: %u) has UNIT_NPC_FLAG_BATTLEMASTER but no data in `battlemaster_entry` table. Removing flag!", itr->second.Entry); + const_cast(&itr->second)->npcflag &= ~UNIT_NPC_FLAG_BATTLEMASTER; + } + } +} + HolidayIds BattlegroundMgr::BGTypeToWeekendHolidayId(BattlegroundTypeId bgTypeId) { switch (bgTypeId) diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h index f10614baafc..42803620e27 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.h +++ b/src/server/game/Battlegrounds/BattlegroundMgr.h @@ -126,12 +126,13 @@ class BattlegroundMgr uint32 GetRatingDiscardTimer() const; void InitAutomaticArenaPointDistribution(); void LoadBattleMastersEntry(); + void CheckBattleMasters(); BattlegroundTypeId GetBattleMasterBG(uint32 entry) const { BattleMastersMap::const_iterator itr = mBattleMastersMap.find(entry); if (itr != mBattleMastersMap.end()) return itr->second; - return BATTLEGROUND_WS; + return BATTLEGROUND_TYPE_NONE; } private: diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 7fb82ac8e03..d1db4fb634d 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -651,9 +651,9 @@ struct CharTitlesEntry { uint32 ID; // 0, title ids, for example in Quest::GetCharTitleId() //uint32 unk1; // 1 flags? - char* name[16]; // 2-17 + char* nameMale[16]; // 2-17 // 18 string flag, unused - //char* name2[16]; // 19-34, unused + char* nameFemale[16]; // 19-34 // 35 string flag, unused uint32 bit_index; // 36 used in PLAYER_CHOSEN_TITLE and 1<IsGameMaster() ? 90 * DAY : 30 * DAY; + } time_t expire_time = deliver_time + expire_delay; diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index 2e10fdc374b..d8c8889da67 100644 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -122,7 +122,7 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck) { MapEntry const* entry = sMapStore.LookupEntry(mapid); if (!entry) - return false; + return false; if (!entry->IsDungeon()) return true; @@ -220,12 +220,12 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck) // players are only allowed to enter 5 instances per hour if (entry->IsDungeon() && (!player->GetGroup() || (player->GetGroup() && !player->GetGroup()->isLFGGroup()))) { - uint32 instaceIdToCheck = 0; + uint32 instanceIdToCheck = 0; if (InstanceSave* save = player->GetInstanceSave(mapid, entry->IsRaid())) - instaceIdToCheck = save->GetInstanceId(); + instanceIdToCheck = save->GetInstanceId(); // instanceId can never be 0 - will not be found - if (!player->CheckInstanceCount(instaceIdToCheck) && !player->isDead()) + if (!player->CheckInstanceCount(instanceIdToCheck) && !player->isDead()) { player->SendTransferAborted(mapid, TRANSFER_ABORT_TOO_MANY_INSTANCES); return false; diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index e5d3a5312de..961a896a8f7 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -3324,7 +3324,7 @@ enum BattlegroundTypeId BATTLEGROUND_DS = 10, // Dalaran Sewers BATTLEGROUND_RV = 11, // Ring of Valor BATTLEGROUND_IC = 30, // Isle of Conquest - BATTLEGROUND_RB = 32 // Random Battleground + BATTLEGROUND_RB = 32 // Random Battleground }; #define MAX_BATTLEGROUND_TYPE_ID 33 diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index af2fb90ea1b..af84a16aa0b 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1633,7 +1633,7 @@ void World::SetInitialWorldSettings() sObjectMgr->LoadGameObjectForQuests(); TC_LOG_INFO("server.loading", "Loading BattleMasters..."); - sBattlegroundMgr->LoadBattleMastersEntry(); + sBattlegroundMgr->LoadBattleMastersEntry(); // must be after load CreatureTemplate TC_LOG_INFO("server.loading", "Loading GameTeleports..."); sObjectMgr->LoadGameTele(); diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp index f9ef827e8c3..87bb1fefdd2 100644 --- a/src/server/scripts/Commands/cs_character.cpp +++ b/src/server/scripts/Commands/cs_character.cpp @@ -277,7 +277,7 @@ public: if (titleInfo && target->HasTitle(titleInfo)) { - std::string name = titleInfo->name[loc]; + std::string name = target->getGender() == GENDER_MALE ? titleInfo->nameMale[loc] : titleInfo->nameFemale[loc]; if (name.empty()) continue; diff --git a/src/server/scripts/Commands/cs_lookup.cpp b/src/server/scripts/Commands/cs_lookup.cpp index f2b4f54363b..57cf2cba260 100644 --- a/src/server/scripts/Commands/cs_lookup.cpp +++ b/src/server/scripts/Commands/cs_lookup.cpp @@ -1183,8 +1183,9 @@ public: CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id); if (titleInfo) { + /// @todo: implement female support int locale = handler->GetSessionDbcLocale(); - std::string name = titleInfo->name[locale]; + std::string name = titleInfo->nameMale[locale]; if (name.empty()) continue; @@ -1196,7 +1197,7 @@ public: if (locale == handler->GetSessionDbcLocale()) continue; - name = titleInfo->name[locale]; + name = titleInfo->nameMale[locale]; if (name.empty()) continue; diff --git a/src/server/scripts/Commands/cs_titles.cpp b/src/server/scripts/Commands/cs_titles.cpp index 20bffdbb792..3d429deb3ef 100644 --- a/src/server/scripts/Commands/cs_titles.cpp +++ b/src/server/scripts/Commands/cs_titles.cpp @@ -96,7 +96,7 @@ public: target->SetTitle(titleInfo); // to be sure that title now known target->SetUInt32Value(PLAYER_CHOSEN_TITLE, titleInfo->bit_index); - handler->PSendSysMessage(LANG_TITLE_CURRENT_RES, id, titleInfo->name[handler->GetSessionDbcLocale()], tNameLink.c_str()); + handler->PSendSysMessage(LANG_TITLE_CURRENT_RES, id, target->getGender() == GENDER_MALE ? titleInfo->nameMale[handler->GetSessionDbcLocale()] : titleInfo->nameFemale[handler->GetSessionDbcLocale()], tNameLink.c_str()); return true; } @@ -139,7 +139,7 @@ public: std::string tNameLink = handler->GetNameLink(target); char titleNameStr[80]; - snprintf(titleNameStr, 80, titleInfo->name[handler->GetSessionDbcLocale()], target->GetName().c_str()); + snprintf(titleNameStr, 80, target->getGender() == GENDER_MALE ? titleInfo->nameMale[handler->GetSessionDbcLocale()] : titleInfo->nameFemale[handler->GetSessionDbcLocale()], target->GetName().c_str()); target->SetTitle(titleInfo); handler->PSendSysMessage(LANG_TITLE_ADD_RES, id, titleNameStr, tNameLink.c_str()); @@ -187,7 +187,7 @@ public: std::string tNameLink = handler->GetNameLink(target); char titleNameStr[80]; - snprintf(titleNameStr, 80, titleInfo->name[handler->GetSessionDbcLocale()], target->GetName().c_str()); + snprintf(titleNameStr, 80, target->getGender() == GENDER_MALE ? titleInfo->nameMale[handler->GetSessionDbcLocale()] : titleInfo->nameFemale[handler->GetSessionDbcLocale()], target->GetName().c_str()); handler->PSendSysMessage(LANG_TITLE_REMOVE_RES, id, titleNameStr, tNameLink.c_str()); -- 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') 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 61890bce7cf5abb2fbf536e07da233ff7d4cedb0 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Wed, 26 Feb 2014 21:44:51 +0100 Subject: Scripts/Onyxia Lair: Fix debug assertions about iterators --- .../Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp | 23 ++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'src/server/scripts') diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp b/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp index e028fab67e5..678a79c51ad 100644 --- a/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp +++ b/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp @@ -212,13 +212,24 @@ public: { if (eruptTimer <= diff) { - uint32 treeHeight = 0; - do + uint64 frontGuid = FloorEruptionGUIDQueue.front(); + std::map::iterator itr = FloorEruptionGUID[1].find(frontGuid); + if (itr != FloorEruptionGUID[1].end()) { - treeHeight = (*FloorEruptionGUID[1].find(FloorEruptionGUIDQueue.front())).second; - FloorEruption(FloorEruptionGUIDQueue.front()); - FloorEruptionGUIDQueue.pop(); - } while (!FloorEruptionGUIDQueue.empty() && (*FloorEruptionGUID[1].find(FloorEruptionGUIDQueue.front())).second == treeHeight); + uint32 treeHeight = itr->second; + + do + { + FloorEruption(frontGuid); + FloorEruptionGUIDQueue.pop(); + if (FloorEruptionGUIDQueue.empty()) + break; + + frontGuid = FloorEruptionGUIDQueue.front(); + itr = FloorEruptionGUID[1].find(frontGuid); + } while (itr != FloorEruptionGUID[1].end() && itr->second == treeHeight); + } + eruptTimer = 1000; } else -- cgit v1.2.3 From 3a40d8a88790209238142c46341b3c76cc1a2454 Mon Sep 17 00:00:00 2001 From: joschiwald Date: Sun, 2 Mar 2014 00:00:39 +0100 Subject: Core/Player: delete queststatus (weekly/monthly/seasonal) on deleting character thx @Expecto - also rename some prepared statements Closes #11658 --- src/server/game/Battlegrounds/ArenaTeamMgr.cpp | 2 +- src/server/game/Entities/Pet/Pet.cpp | 4 +- src/server/game/Entities/Player/Player.cpp | 59 ++++++++++++++-------- src/server/game/Handlers/CharacterHandler.cpp | 8 +-- src/server/game/Handlers/PetHandler.cpp | 2 +- src/server/game/World/World.cpp | 10 ++-- src/server/scripts/Commands/cs_character.cpp | 2 +- .../Database/Implementation/CharacterDatabase.cpp | 56 ++++++++++---------- .../Database/Implementation/CharacterDatabase.h | 54 ++++++++++---------- 9 files changed, 108 insertions(+), 89 deletions(-) (limited to 'src/server/scripts') diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp index dba891c96db..347db73f991 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp @@ -162,7 +162,7 @@ void ArenaTeamMgr::DistributeArenaPoints() player->ModifyArenaPoints(playerItr->second, &trans); else // Update database { - stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ARENA_POINTS); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_CHAR_ARENA_POINTS); stmt->setUInt32(0, playerItr->second); stmt->setUInt32(1, playerItr->first); trans->Append(stmt); diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index a887e85e77e..1d7db005a0b 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -279,7 +279,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c { SQLTransaction trans = CharacterDatabase.BeginTransaction(); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID); stmt->setUInt8(0, uint8(PET_SAVE_NOT_IN_SLOT)); stmt->setUInt32(1, ownerid); stmt->setUInt8(2, uint8(PET_SAVE_AS_CURRENT)); @@ -430,7 +430,7 @@ void Pet::SavePetToDB(PetSaveMode mode) // prevent duplicate using slot (except PET_SAVE_NOT_IN_SLOT) if (mode <= PET_SAVE_LAST_STABLE_SLOT) { - stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_PET_SLOT_BY_SLOT); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_SLOT_BY_SLOT); stmt->setUInt8(0, uint8(PET_SAVE_NOT_IN_SLOT)); stmt->setUInt32(1, ownerLowGUID); stmt->setUInt8(2, uint8(mode)); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index fed808dc3b3..6e3ff34668f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4971,7 +4971,19 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC stmt->setUInt32(0, guid); trans->Append(stmt); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS_DAILY); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_DAILY); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_WEEKLY); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_MONTHLY); + stmt->setUInt32(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_SEASONAL); stmt->setUInt32(0, guid); trans->Append(stmt); @@ -7317,7 +7329,7 @@ void Player::ModifyHonorPoints(int32 value, SQLTransaction* trans /*=NULL*/) if (trans && !trans->null()) { - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_HONOR_POINTS); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_HONOR_POINTS); stmt->setUInt32(0, newValue); stmt->setUInt32(1, GetGUIDLow()); (*trans)->Append(stmt); @@ -7333,7 +7345,7 @@ void Player::ModifyArenaPoints(int32 value, SQLTransaction* trans /*=NULL*/) if (trans && !trans->null()) { - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_ARENA_POINTS); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ARENA_POINTS); stmt->setUInt32(0, newValue); stmt->setUInt32(1, GetGUIDLow()); (*trans)->Append(stmt); @@ -19403,7 +19415,7 @@ void Player::SaveInventoryAndGoldToDB(SQLTransaction& trans) void Player::SaveGoldToDB(SQLTransaction& trans) { - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_MONEY); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_MONEY); stmt->setUInt32(0, GetMoney()); stmt->setUInt32(1, GetGUIDLow()); trans->Append(stmt); @@ -19790,14 +19802,15 @@ void Player::_SaveDailyQuestStatus(SQLTransaction& trans) // save last daily quest time for all quests: we need only mostly reset time for reset check anyway // we don't need transactions here. - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_QUEST_STATUS_DAILY_CHAR); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_DAILY); stmt->setUInt32(0, GetGUIDLow()); trans->Append(stmt); + for (uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx) { if (GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx)) { - stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_DAILYQUESTSTATUS); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_QUESTSTATUS_DAILY); stmt->setUInt32(0, GetGUIDLow()); stmt->setUInt32(1, GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx)); stmt->setUInt64(2, uint64(m_lastDailyQuestTime)); @@ -19809,7 +19822,7 @@ void Player::_SaveDailyQuestStatus(SQLTransaction& trans) { for (DFQuestsDoneList::iterator itr = m_DFQuests.begin(); itr != m_DFQuests.end(); ++itr) { - stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_DAILYQUESTSTATUS); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_QUESTSTATUS_DAILY); stmt->setUInt32(0, GetGUIDLow()); stmt->setUInt32(1, (*itr)); stmt->setUInt64(2, uint64(m_lastDailyQuestTime)); @@ -19824,17 +19837,17 @@ void Player::_SaveWeeklyQuestStatus(SQLTransaction& trans) return; // we don't need transactions here. - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_QUEST_STATUS_WEEKLY_CHAR); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_WEEKLY); stmt->setUInt32(0, GetGUIDLow()); trans->Append(stmt); for (QuestSet::const_iterator iter = m_weeklyquests.begin(); iter != m_weeklyquests.end(); ++iter) { - uint32 quest_id = *iter; + uint32 questId = *iter; - stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_WEEKLYQUESTSTATUS); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_QUESTSTATUS_WEEKLY); stmt->setUInt32(0, GetGUIDLow()); - stmt->setUInt32(1, quest_id); + stmt->setUInt32(1, questId); trans->Append(stmt); } @@ -19847,21 +19860,22 @@ void Player::_SaveSeasonalQuestStatus(SQLTransaction& trans) return; // we don't need transactions here. - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_QUEST_STATUS_SEASONAL_CHAR); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_SEASONAL); stmt->setUInt32(0, GetGUIDLow()); trans->Append(stmt); for (SeasonalEventQuestMap::const_iterator iter = m_seasonalquests.begin(); iter != m_seasonalquests.end(); ++iter) { - uint16 event_id = iter->first; + uint16 eventId = iter->first; + for (SeasonalQuestSet::const_iterator itr = iter->second.begin(); itr != iter->second.end(); ++itr) { - uint32 quest_id = (*itr); + uint32 questId = *itr; - stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_SEASONALQUESTSTATUS); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_QUESTSTATUS_SEASONAL); stmt->setUInt32(0, GetGUIDLow()); - stmt->setUInt32(1, quest_id); - stmt->setUInt32(2, event_id); + stmt->setUInt32(1, questId); + stmt->setUInt32(2, eventId); trans->Append(stmt); } } @@ -19875,16 +19889,17 @@ void Player::_SaveMonthlyQuestStatus(SQLTransaction& trans) return; // we don't need transactions here. - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_QUEST_STATUS_MONTHLY_CHAR); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_MONTHLY); stmt->setUInt32(0, GetGUIDLow()); trans->Append(stmt); for (QuestSet::const_iterator iter = m_monthlyquests.begin(); iter != m_monthlyquests.end(); ++iter) { - uint32 quest_id = *iter; - stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_MONTHLYQUESTSTATUS); + uint32 questId = *iter; + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_QUESTSTATUS_MONTHLY); stmt->setUInt32(0, GetGUIDLow()); - stmt->setUInt32(1, quest_id); + stmt->setUInt32(1, questId); trans->Append(stmt); } @@ -19930,7 +19945,7 @@ void Player::_SaveSkills(SQLTransaction& trans) break; case SKILL_CHANGED: - stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_SKILLS); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_SKILLS); stmt->setUInt16(0, value); stmt->setUInt16(1, max); stmt->setUInt32(2, GetGUIDLow()); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 333d4d893cd..f9a5ec2d53b 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -92,19 +92,19 @@ bool LoginQueryHolder::Initialize() stmt->setUInt32(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS, stmt); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_DAILYQUESTSTATUS); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_DAILY); stmt->setUInt32(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_DAILY_QUEST_STATUS, stmt); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_WEEKLYQUESTSTATUS); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_WEEKLY); stmt->setUInt32(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_WEEKLY_QUEST_STATUS, stmt); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_MONTHLYQUESTSTATUS); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_MONTHLY); stmt->setUInt32(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_MONTHLY_QUEST_STATUS, stmt); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_SEASONALQUESTSTATUS); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_SEASONAL); stmt->setUInt32(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_SEASONAL_QUEST_STATUS, stmt); diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 550cb74cffa..5258c890ac6 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -647,7 +647,7 @@ void WorldSession::HandlePetRename(WorldPacket& recvData) stmt->setUInt32(0, pet->GetCharmInfo()->GetPetNumber()); trans->Append(stmt); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_CHAR_PET_DECLINEDNAME); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_PET_DECLINEDNAME); stmt->setUInt32(0, _player->GetGUIDLow()); for (uint8 i = 0; i < 5; i++) diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index af84a16aa0b..729dfac6497 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -2867,7 +2867,7 @@ void World::ResetDailyQuests() { TC_LOG_INFO("misc", "Daily quests reset for all characters."); - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_QUEST_STATUS_DAILY); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_DAILY); CharacterDatabase.Execute(stmt); for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) @@ -2901,7 +2901,7 @@ void World::ResetWeeklyQuests() { TC_LOG_INFO("misc", "Weekly quests reset for all characters."); - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_QUEST_STATUS_WEEKLY); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_WEEKLY); CharacterDatabase.Execute(stmt); for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) @@ -2919,7 +2919,7 @@ void World::ResetMonthlyQuests() { TC_LOG_INFO("misc", "Monthly quests reset for all characters."); - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_QUEST_STATUS_MONTHLY); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_MONTHLY); CharacterDatabase.Execute(stmt); for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) @@ -2961,7 +2961,9 @@ void World::ResetMonthlyQuests() void World::ResetEventSeasonalQuests(uint16 event_id) { - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_QUEST_STATUS_SEASONAL); + TC_LOG_INFO("misc", "Seasonal quests reset for all characters."); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_SEASONAL_BY_EVENT); stmt->setUInt16(0, event_id); CharacterDatabase.Execute(stmt); diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp index 87bb1fefdd2..2278a00a9f0 100644 --- a/src/server/scripts/Commands/cs_character.cpp +++ b/src/server/scripts/Commands/cs_character.cpp @@ -217,7 +217,7 @@ public: return; } - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_RESTORE_DELETE_INFO); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_RESTORE_DELETE_INFO); stmt->setString(0, delInfo.name); stmt->setUInt32(1, delInfo.accountId); stmt->setUInt32(2, delInfo.lowGuid); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index aa7c2e96fba..b6590317b8c 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -59,18 +59,10 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_CHARACTER_NAME_DATA, "SELECT race, class, gender, level FROM characters WHERE guid = ?", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_CHAR_POSITION_XYZ, "SELECT map, position_x, position_y, position_z FROM characters WHERE guid = ?", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_CHAR_POSITION, "SELECT position_x, position_y, position_z, orientation, map, taxi_path FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_DEL_QUEST_STATUS_DAILY, "DELETE FROM character_queststatus_daily", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_QUEST_STATUS_WEEKLY, "DELETE FROM character_queststatus_weekly", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_QUEST_STATUS_MONTHLY, "DELETE FROM character_queststatus_monthly", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_QUEST_STATUS_SEASONAL, "DELETE FROM character_queststatus_seasonal WHERE event = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_QUEST_STATUS_DAILY_CHAR, "DELETE FROM character_queststatus_daily WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_QUEST_STATUS_WEEKLY_CHAR, "DELETE FROM character_queststatus_weekly WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_QUEST_STATUS_MONTHLY_CHAR, "DELETE FROM character_queststatus_monthly WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_QUEST_STATUS_SEASONAL_CHAR, "DELETE FROM character_queststatus_seasonal WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_BATTLEGROUND_RANDOM, "DELETE FROM character_battleground_random", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_BATTLEGROUND_RANDOM, "INSERT INTO character_battleground_random (guid) VALUES (?)", CONNECTION_ASYNC); - // Start LoginQueryHolder content PrepareStatement(CHAR_SEL_CHARACTER, "SELECT guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, " "position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, " "resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, " @@ -85,14 +77,24 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_CHARACTER_SPELL, "SELECT spell, active, disabled FROM character_spell WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS, "SELECT quest, status, explored, timer, mobcount1, mobcount2, mobcount3, mobcount4, " "itemcount1, itemcount2, itemcount3, itemcount4, playercount FROM character_queststatus WHERE guid = ? AND status <> 0", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_DAILYQUESTSTATUS, "SELECT quest, time FROM character_queststatus_daily WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_WEEKLYQUESTSTATUS, "SELECT quest FROM character_queststatus_weekly WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_MONTHLYQUESTSTATUS, "SELECT quest FROM character_queststatus_monthly WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_SEASONALQUESTSTATUS, "SELECT quest, event FROM character_queststatus_seasonal WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHARACTER_DAILYQUESTSTATUS, "INSERT INTO character_queststatus_daily (guid, quest, time) VALUES (?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHARACTER_WEEKLYQUESTSTATUS, "INSERT INTO character_queststatus_weekly (guid, quest) VALUES (?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHARACTER_MONTHLYQUESTSTATUS, "INSERT INTO character_queststatus_monthly (guid, quest) VALUES (?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHARACTER_SEASONALQUESTSTATUS, "INSERT INTO character_queststatus_seasonal (guid, quest, event) VALUES (?, ?, ?)", CONNECTION_ASYNC); + + PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_DAILY, "SELECT quest, time FROM character_queststatus_daily WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_WEEKLY, "SELECT quest FROM character_queststatus_weekly WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_MONTHLY, "SELECT quest FROM character_queststatus_monthly WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_SEASONAL, "SELECT quest, event FROM character_queststatus_seasonal WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_DAILY, "DELETE FROM character_queststatus_daily WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_WEEKLY, "DELETE FROM character_queststatus_weekly WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_MONTHLY, "DELETE FROM character_queststatus_monthly WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_SEASONAL, "DELETE FROM character_queststatus_seasonal WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_INS_CHARACTER_QUESTSTATUS_DAILY, "INSERT INTO character_queststatus_daily (guid, quest, time) VALUES (?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_INS_CHARACTER_QUESTSTATUS_WEEKLY, "INSERT INTO character_queststatus_weekly (guid, quest) VALUES (?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_INS_CHARACTER_QUESTSTATUS_MONTHLY, "INSERT INTO character_queststatus_monthly (guid, quest) VALUES (?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_INS_CHARACTER_QUESTSTATUS_SEASONAL, "INSERT INTO character_queststatus_seasonal (guid, quest, event) VALUES (?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_DAILY, "DELETE FROM character_queststatus_daily", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_WEEKLY, "DELETE FROM character_queststatus_weekly", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_MONTHLY, "DELETE FROM character_queststatus_monthly", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_SEASONAL_BY_EVENT, "DELETE FROM character_queststatus_seasonal WHERE event = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_CHARACTER_REPUTATION, "SELECT faction, standing, flags FROM character_reputation WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_INVENTORY, "SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, bag, slot, " "item, itemEntry FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid WHERE ci.guid = ? ORDER BY bag, slot", CONNECTION_ASYNC); @@ -120,7 +122,6 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_CHARACTER_BANNED, "SELECT guid FROM character_banned WHERE guid = ? AND active = 1", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUSREW, "SELECT quest FROM character_queststatus_rewarded WHERE guid = ? AND active = 1", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES, "SELECT instanceId, releaseTime FROM account_instance_times WHERE accountId = ?", CONNECTION_ASYNC); - // End LoginQueryHolder content PrepareStatement(CHAR_SEL_CHARACTER_ACTIONS_SPEC, "SELECT button, action, type FROM character_action WHERE guid = ? AND spec = ? ORDER BY button", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_MAILITEMS, "SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, item_guid, itemEntry, owner_guid FROM mail_items mi JOIN item_instance ii ON mi.item_guid = ii.guid WHERE mail_id = ?", CONNECTION_SYNCH); @@ -389,7 +390,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_DEL_INVALID_SPELL_TALENTS, "DELETE FROM character_talent WHERE spell = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_INVALID_SPELL_SPELLS, "DELETE FROM character_spell WHERE spell = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_DELETE_INFO, "UPDATE characters SET deleteInfos_Name = name, deleteInfos_Account = account, deleteDate = UNIX_TIMESTAMP(), name = '', account = 0 WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UDP_RESTORE_DELETE_INFO, "UPDATE characters SET name = ?, account = ?, deleteDate = NULL, deleteInfos_Name = NULL, deleteInfos_Account = NULL WHERE deleteDate IS NOT NULL AND guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_UPD_RESTORE_DELETE_INFO, "UPDATE characters SET name = ?, account = ?, deleteDate = NULL, deleteInfos_Name = NULL, deleteInfos_Account = NULL WHERE deleteDate IS NOT NULL AND guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_ZONE, "UPDATE characters SET zone = ? WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_LEVEL, "UPDATE characters SET level = ?, xp = 0 WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA, "DELETE FROM character_achievement_progress WHERE criteria = ?", CONNECTION_ASYNC); @@ -463,7 +464,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS, "INSERT INTO character_achievement_progress (guid, criteria, counter, date) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_REPUTATION_BY_FACTION, "DELETE FROM character_reputation WHERE guid = ? AND faction = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_CHAR_REPUTATION_BY_FACTION, "INSERT INTO character_reputation (guid, faction, standing, flags) VALUES (?, ?, ? , ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = (arenaPoints + ?) WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_UPD_ADD_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = (arenaPoints + ?) WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_ITEM_REFUND_INSTANCE, "DELETE FROM item_refund_instance WHERE item_guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_ITEM_REFUND_INSTANCE, "INSERT INTO item_refund_instance (item_guid, player_guid, paidMoney, paidExtendedCost) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_GROUP, "DELETE FROM groups WHERE guid = ?", CONNECTION_ASYNC); @@ -515,12 +516,11 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_DEL_GUILD_EVENTLOG_BY_PLAYER, "DELETE FROM guild_eventlog WHERE PlayerGuid1 = ? OR PlayerGuid2 = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_GUILD_BANK_EVENTLOG_BY_PLAYER, "DELETE FROM guild_bank_eventlog WHERE PlayerGuid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_GLYPHS, "DELETE FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_QUESTSTATUS_DAILY, "DELETE FROM character_queststatus_daily WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_TALENT, "DELETE FROM character_talent WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_SKILLS, "DELETE FROM character_skills WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UDP_CHAR_HONOR_POINTS, "UPDATE characters SET totalHonorPoints = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UDP_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UDP_CHAR_MONEY, "UPDATE characters SET money = ? WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_UPD_CHAR_HONOR_POINTS, "UPDATE characters SET totalHonorPoints = ? WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_UPD_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = ? WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_UPD_CHAR_MONEY, "UPDATE characters SET money = ? WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_CHAR_ACTION, "INSERT INTO character_action (guid, spec, button, action, type) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_CHAR_ACTION, "UPDATE character_action SET action = ?, type = ? WHERE guid = ? AND button = ? AND spec = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_ACTION_BY_BUTTON_SPEC, "DELETE FROM character_action WHERE guid = ? and button = ? and spec = ?", CONNECTION_ASYNC); @@ -536,7 +536,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST, "UPDATE character_queststatus_rewarded SET active = 0 WHERE quest = ? AND guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_SKILL_BY_SKILL, "DELETE FROM character_skills WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_CHAR_SKILLS, "INSERT INTO character_skills (guid, skill, value, max) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UDP_CHAR_SKILLS, "UPDATE character_skills SET value = ?, max = ? WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_UPD_CHAR_SKILLS, "UPDATE character_skills SET value = ?, max = ? WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_CHAR_SPELL, "INSERT INTO character_spell (guid, spell, active, disabled) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_STATS, "DELETE FROM character_stats WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_CHAR_STATS, "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, maxpower6, maxpower7, strength, agility, stamina, intellect, spirit, " @@ -576,7 +576,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_CHAR_PETS, "SELECT id FROM character_pet WHERE owner = ?", CONNECTION_SYNCH); PrepareStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME_BY_OWNER, "DELETE FROM character_pet_declinedname WHERE owner = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME, "DELETE FROM character_pet_declinedname WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_ADD_CHAR_PET_DECLINEDNAME, "INSERT INTO character_pet_declinedname (id, owner, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_INS_CHAR_PET_DECLINEDNAME, "INSERT INTO character_pet_declinedname (id, owner, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_PET_AURA, "SELECT caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges FROM pet_aura WHERE guid = ?", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_PET_SPELL, "SELECT spell, active FROM pet_spell WHERE guid = ?", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_PET_SPELL_COOLDOWN, "SELECT spell, time FROM pet_spell_cooldown WHERE guid = ?", CONNECTION_SYNCH); @@ -595,8 +595,8 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND slot = ?", CONNECTION_SYNCH); PrepareStatement(CHAR_DEL_CHAR_PET_BY_OWNER, "DELETE FROM character_pet WHERE owner = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_CHAR_PET_NAME, "UPDATE character_pet SET name = ?, renamed = 1 WHERE owner = ? AND id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UDP_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID, "UPDATE character_pet SET slot = ? WHERE owner = ? AND slot = ? AND id <> ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UDP_CHAR_PET_SLOT_BY_SLOT, "UPDATE character_pet SET slot = ? WHERE owner = ? AND slot = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_UPD_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID, "UPDATE character_pet SET slot = ? WHERE owner = ? AND slot = ? AND id <> ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_UPD_CHAR_PET_SLOT_BY_SLOT, "UPDATE character_pet SET slot = ? WHERE owner = ? AND slot = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_CHAR_PET_SLOT_BY_ID, "UPDATE character_pet SET slot = ? WHERE owner = ? AND id = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_PET_BY_ID, "DELETE FROM character_pet WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_PET_BY_SLOT, "DELETE FROM character_pet WHERE owner = ? AND (slot = ? OR slot > ?)", CONNECTION_ASYNC); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index 6768e4a197f..98d7fe231f1 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -71,14 +71,7 @@ enum CharacterDatabaseStatements CHAR_SEL_CHARACTER_NAME_DATA, CHAR_SEL_CHAR_POSITION_XYZ, CHAR_SEL_CHAR_POSITION, - CHAR_DEL_QUEST_STATUS_DAILY, - CHAR_DEL_QUEST_STATUS_WEEKLY, - CHAR_DEL_QUEST_STATUS_MONTHLY, - CHAR_DEL_QUEST_STATUS_SEASONAL, - CHAR_DEL_QUEST_STATUS_DAILY_CHAR, - CHAR_DEL_QUEST_STATUS_WEEKLY_CHAR, - CHAR_DEL_QUEST_STATUS_MONTHLY_CHAR, - CHAR_DEL_QUEST_STATUS_SEASONAL_CHAR, + CHAR_DEL_BATTLEGROUND_RANDOM, CHAR_INS_BATTLEGROUND_RANDOM, @@ -88,14 +81,24 @@ enum CharacterDatabaseStatements CHAR_SEL_CHARACTER_AURAS, CHAR_SEL_CHARACTER_SPELL, CHAR_SEL_CHARACTER_QUESTSTATUS, - CHAR_SEL_CHARACTER_DAILYQUESTSTATUS, - CHAR_SEL_CHARACTER_WEEKLYQUESTSTATUS, - CHAR_SEL_CHARACTER_MONTHLYQUESTSTATUS, - CHAR_SEL_CHARACTER_SEASONALQUESTSTATUS, - CHAR_INS_CHARACTER_DAILYQUESTSTATUS, - CHAR_INS_CHARACTER_WEEKLYQUESTSTATUS, - CHAR_INS_CHARACTER_MONTHLYQUESTSTATUS, - CHAR_INS_CHARACTER_SEASONALQUESTSTATUS, + + CHAR_SEL_CHARACTER_QUESTSTATUS_DAILY, + CHAR_SEL_CHARACTER_QUESTSTATUS_WEEKLY, + CHAR_SEL_CHARACTER_QUESTSTATUS_MONTHLY, + CHAR_SEL_CHARACTER_QUESTSTATUS_SEASONAL, + CHAR_DEL_CHARACTER_QUESTSTATUS_DAILY, + CHAR_DEL_CHARACTER_QUESTSTATUS_WEEKLY, + CHAR_DEL_CHARACTER_QUESTSTATUS_MONTHLY, + CHAR_DEL_CHARACTER_QUESTSTATUS_SEASONAL, + CHAR_INS_CHARACTER_QUESTSTATUS_DAILY, + CHAR_INS_CHARACTER_QUESTSTATUS_WEEKLY, + CHAR_INS_CHARACTER_QUESTSTATUS_MONTHLY, + CHAR_INS_CHARACTER_QUESTSTATUS_SEASONAL, + CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_DAILY, + CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_WEEKLY, + CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_MONTHLY, + CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_SEASONAL_BY_EVENT, + CHAR_SEL_CHARACTER_REPUTATION, CHAR_SEL_CHARACTER_INVENTORY, CHAR_SEL_CHARACTER_ACTIONS, @@ -326,7 +329,7 @@ enum CharacterDatabaseStatements CHAR_DEL_INVALID_SPELL_SPELLS, CHAR_DEL_INVALID_SPELL_TALENTS, CHAR_UPD_DELETE_INFO, - CHAR_UDP_RESTORE_DELETE_INFO, + CHAR_UPD_RESTORE_DELETE_INFO, CHAR_UPD_ZONE, CHAR_UPD_LEVEL, CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA, @@ -399,7 +402,7 @@ enum CharacterDatabaseStatements CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS, CHAR_DEL_CHAR_REPUTATION_BY_FACTION, CHAR_INS_CHAR_REPUTATION_BY_FACTION, - CHAR_UPD_CHAR_ARENA_POINTS, + CHAR_UPD_ADD_CHAR_ARENA_POINTS, CHAR_DEL_ITEM_REFUND_INSTANCE, CHAR_INS_ITEM_REFUND_INSTANCE, CHAR_DEL_GROUP, @@ -451,12 +454,11 @@ enum CharacterDatabaseStatements CHAR_DEL_GUILD_EVENTLOG_BY_PLAYER, CHAR_DEL_GUILD_BANK_EVENTLOG_BY_PLAYER, CHAR_DEL_CHAR_GLYPHS, - CHAR_DEL_CHAR_QUESTSTATUS_DAILY, CHAR_DEL_CHAR_TALENT, CHAR_DEL_CHAR_SKILLS, - CHAR_UDP_CHAR_HONOR_POINTS, - CHAR_UDP_CHAR_ARENA_POINTS, - CHAR_UDP_CHAR_MONEY, + CHAR_UPD_CHAR_HONOR_POINTS, + CHAR_UPD_CHAR_ARENA_POINTS, + CHAR_UPD_CHAR_MONEY, CHAR_INS_CHAR_ACTION, CHAR_UPD_CHAR_ACTION, CHAR_DEL_CHAR_ACTION_BY_BUTTON_SPEC, @@ -472,7 +474,7 @@ enum CharacterDatabaseStatements CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST, CHAR_DEL_CHAR_SKILL_BY_SKILL, CHAR_INS_CHAR_SKILLS, - CHAR_UDP_CHAR_SKILLS, + CHAR_UPD_CHAR_SKILLS, CHAR_INS_CHAR_SPELL, CHAR_DEL_CHAR_STATS, CHAR_INS_CHAR_STATS, @@ -516,10 +518,10 @@ enum CharacterDatabaseStatements CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT_2, CHAR_SEL_CHAR_PET_BY_SLOT, CHAR_DEL_CHAR_PET_DECLINEDNAME, - CHAR_ADD_CHAR_PET_DECLINEDNAME, + CHAR_INS_CHAR_PET_DECLINEDNAME, CHAR_UPD_CHAR_PET_NAME, - CHAR_UDP_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID, - CHAR_UDP_CHAR_PET_SLOT_BY_SLOT, + CHAR_UPD_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID, + CHAR_UPD_CHAR_PET_SLOT_BY_SLOT, CHAR_UPD_CHAR_PET_SLOT_BY_ID, CHAR_DEL_CHAR_PET_BY_ID, CHAR_DEL_CHAR_PET_BY_SLOT, -- cgit v1.2.3 From d3575972709e0b3df87781ddfec51d8836f13257 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sun, 9 Mar 2014 17:09:15 +0100 Subject: Scripts/Commands: Fix crash in ".kick" command Fix a NULL dereference exception happening when using .kick command caused by a strtok(NULL) call without a previous call to the string to be tokenized. Issue added in 101cad1f2872a87be925b74b9d17760381bb9808 --- src/server/scripts/Commands/cs_misc.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/server/scripts') diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 6de8a155d01..d0c21168c80 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -809,10 +809,13 @@ public: if (handler->HasLowerSecurity(target, 0)) return false; - char const* kickReason = strtok(NULL, "\r"); std::string kickReasonStr = "No reason"; - if (kickReason != NULL) - kickReasonStr = kickReason; + if (*args != '\0') + { + char const* kickReason = strtok(NULL, "\r"); + if (kickReason != NULL) + kickReasonStr = kickReason; + } if (sWorld->getBoolConfig(CONFIG_SHOW_KICK_IN_WORLD)) sWorld->SendWorldText(LANG_COMMAND_KICKMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), playerName.c_str(), kickReasonStr.c_str()); -- 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') 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 3b247f6bca38c5b0c9bfee5c57d346869542236f Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sat, 15 Mar 2014 19:45:44 +0100 Subject: Scripts/ZulGurub/Jeklik: Add missing "break" --- src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/server/scripts') diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp index 336599f2cc5..5d4bafb5f94 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp @@ -152,9 +152,11 @@ class boss_jeklik : public CreatureScript case EVENT_SONIC_BURST: DoCastVictim(SPELL_SONICBURST); events.ScheduleEvent(EVENT_SONIC_BURST, urand(8000, 13000), 0, PHASE_ONE); + break; case EVENT_SCREECH: DoCastVictim(SPELL_SCREECH); events.ScheduleEvent(EVENT_SCREECH, urand(18000, 26000), 0, PHASE_ONE); + break; case EVENT_SPAWN_BATS: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) for (uint8 i = 0; i < 6; ++i) -- 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') 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') 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 5f7e0f6929ea70fa97565c4bb38c0d63d40fc43a Mon Sep 17 00:00:00 2001 From: untaught Date: Sun, 16 Mar 2014 08:47:27 +0200 Subject: Instance Script/Stratholme: Correct logic in Baron Run event and add SAI for Ysida Harmon --- sql/updates/world/2014_03_16_02_world_sai.sql | 7 +++++++ .../Stratholme/instance_stratholme.cpp | 20 ++++++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 sql/updates/world/2014_03_16_02_world_sai.sql (limited to 'src/server/scripts') diff --git a/sql/updates/world/2014_03_16_02_world_sai.sql b/sql/updates/world/2014_03_16_02_world_sai.sql new file mode 100644 index 00000000000..775c6aa1d0c --- /dev/null +++ b/sql/updates/world/2014_03_16_02_world_sai.sql @@ -0,0 +1,7 @@ +UPDATE `creature_template` SET `ainame`='SmartAI' WHERE `entry`=16031; +DELETE FROM `smart_scripts` WHERE `entryorguid`=16031 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(16031,0,0,0,11,0,100,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Ysida Harmon - On Respawn - Say Line 0'); +DELETE FROM `creature_text` WHERE `entry`=16031; +INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`) VALUES +(16031,0,0,'You did it... you''ve slain Baron Rivendare! The Argent Dawn shall hear of your valiant deeds!',12,0,0,0,0,0,''); diff --git a/src/server/scripts/EasternKingdoms/Stratholme/instance_stratholme.cpp b/src/server/scripts/EasternKingdoms/Stratholme/instance_stratholme.cpp index d8518085b26..9ceaf8cb85b 100644 --- a/src/server/scripts/EasternKingdoms/Stratholme/instance_stratholme.cpp +++ b/src/server/scripts/EasternKingdoms/Stratholme/instance_stratholme.cpp @@ -310,6 +310,15 @@ class instance_stratholme : public InstanceMapScript { HandleGameObject(ziggurat4GUID, false); HandleGameObject(ziggurat5GUID, false); + } + if (data == DONE || data == NOT_STARTED) + { + HandleGameObject(ziggurat4GUID, true); + HandleGameObject(ziggurat5GUID, true); + } + if (data == DONE) + { + HandleGameObject(portGauntletGUID, true); if (GetData(TYPE_BARON_RUN) == IN_PROGRESS) { DoRemoveAurasDueToSpellOnPlayers(SPELL_BARON_ULTIMATUM); @@ -318,18 +327,13 @@ class instance_stratholme : public InstanceMapScript for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) if (Player* player = itr->GetSource()) if (player->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE) + { player->AreaExploredOrEventHappens(QUEST_DEAD_MAN_PLEA); - + player->KilledMonsterCredit(NPC_YSIDA); + } SetData(TYPE_BARON_RUN, DONE); } } - if (data == DONE || data == NOT_STARTED) - { - HandleGameObject(ziggurat4GUID, true); - HandleGameObject(ziggurat5GUID, true); - } - if (data == DONE) - HandleGameObject(portGauntletGUID, true); EncounterState[5] = data; break; case TYPE_SH_AELMAR: -- 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') 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 c31ffd774e0cf845b980d18f3a26b46150de1e4c Mon Sep 17 00:00:00 2001 From: untaught Date: Tue, 18 Mar 2014 08:31:23 +0200 Subject: Core/Scripts: Move 'The Defias Traitor' script to SAI --- sql/updates/world/2014_03_18_00_world_sai.sql | 62 ++++++++++++++++++ .../scripts/EasternKingdoms/zone_westfall.cpp | 75 +--------------------- 2 files changed, 63 insertions(+), 74 deletions(-) create mode 100644 sql/updates/world/2014_03_18_00_world_sai.sql (limited to 'src/server/scripts') diff --git a/sql/updates/world/2014_03_18_00_world_sai.sql b/sql/updates/world/2014_03_18_00_world_sai.sql new file mode 100644 index 00000000000..126abb57f8c --- /dev/null +++ b/sql/updates/world/2014_03_18_00_world_sai.sql @@ -0,0 +1,62 @@ +UPDATE `creature_template` SET `ainame`='SmartAI', `scriptname`='' WHERE `entry`=467; +DELETE FROM `smart_scripts` WHERE `entryorguid`=467 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(467,0,0,1,19,0,100,0,155,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'The Defias Traitor - On Accepted Quest ''The Defias Brotherhood'' - Say Line 0'), +(467,0,1,2,61,0,100,0,0,0,0,0,64,1,0,0,0,0,0,7,0,0,0,0,0,0,0,'The Defias Traitor - Link With Previous - Store Target List'), +(467,0,2,3,61,0,100,0,0,0,0,0,83,2,0,0,0,0,0,1,0,0,0,0,0,0,0,'The Defias Traitor - Link With Previous - Remove npcflag ''Quest Giver'), +(467,0,3,0,61,0,100,0,0,0,0,0,53,1,467,0,0,0,2,7,0,0,0,0,0,0,0,'The Defias Traitor - Link WIth Previous - Start WP'), +(467,0,4,0,40,0,100,0,36,467,0,0,59,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'The Defias Traitor - On WP Reached 36 - Disable run'), +(467,0,5,0,40,0,100,0,37,467,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,'The Defias Traitor - On WP Reached 37 - Say Line 1'), +(467,0,6,7,40,0,100,0,45,467,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,'The Defias Traitor - On WP Reached 45 - Say Line 2'), +(467,0,7,8,61,0,100,0,0,0,0,0,15,155,0,0,0,0,0,12,1,0,0,0,0,0,0,'The Defias Traitor - Link With Previous - Area Explored Or Event Happens'), +(467,0,8,0,61,0,100,1,0,0,0,0,41,3000,0,0,0,0,0,1,0,0,0,0,0,0,0,'The Defias Traitor - Link WIth Previous - Despawn'), +(467,0,9,0,4,0,100,0,0,0,0,0,1,3,0,0,0,0,0,1,0,0,0,0,0,0,0,'The Defias Traitor - On Aggro - Say Line 3'); + +DELETE FROM `script_waypoint` WHERE `entry`=467; +DELETE FROM `waypoints` WHERE `entry`=467; +INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `point_comment`) VALUES +(467,1,-10508.4,1068,55.21,''), +(467,2,-10518.3,1074.84,53.96,''), +(467,3,-10534.8,1081.92,49.88,''), +(467,4,-10546.5,1084.88,50.13,''), +(467,5,-10555.3,1084.45,45.75,''), +(467,6,-10566.6,1083.53,42.1,''), +(467,7,-10575.8,1082.34,39.46,''), +(467,8,-10585.7,1081.08,37.77,''), +(467,9,-10600.1,1078.19,36.23,''), +(467,10,-10608.7,1076.08,35.88,''), +(467,11,-10621.3,1073,35.4,''), +(467,12,-10638.1,1060.18,33.61,''), +(467,13,-10655.9,1038.99,33.48,''), +(467,14,-10664.7,1030.54,32.7,''), +(467,15,-10708.7,1033.86,33.32,''), +(467,16,-10754.4,1017.93,32.79,''), +(467,17,-10802.3,1018.01,32.16,''), +(467,18,-10832.6,1009.04,32.71,''), +(467,19,-10866.6,1006.51,31.71,''), +(467,20,-10880,1005.1,32.84,''), +(467,21,-10892.5,1001.32,34.46,''), +(467,22,-10906.1,997.11,36.15,''), +(467,23,-10922.3,1002.23,35.74,''), +(467,24,-10936.3,1023.38,36.52,''), +(467,25,-10933.3,1052.61,35.85,''), +(467,26,-10940.2,1077.66,36.49,''), +(467,27,-10957.1,1099.33,36.83,''), +(467,28,-10956.5,1119.9,36.73,''), +(467,29,-10939.3,1150.75,37.42,''), +(467,30,-10915.1,1202.09,36.55,''), +(467,31,-10892.6,1257.03,33.37,''), +(467,32,-10891.9,1306.66,35.45,''), +(467,33,-10896.2,1327.86,37.77,''), +(467,34,-10906,1368.05,40.91,''), +(467,35,-10910.2,1389.33,42.62,''), +(467,36,-10915.4,1417.72,42.93,''), +(467,37,-10926.4,1421.18,43.04,'walk here and say'), +(467,38,-10952.3,1421.74,43.4,''), +(467,39,-10980,1411.38,42.79,''), +(467,40,-11006.1,1420.47,43.26,''), +(467,41,-11022,1450.59,43.09,''), +(467,42,-11025.4,1491.59,43.15,''), +(467,43,-11036.1,1508.32,43.28,''), +(467,44,-11060.7,1526.72,43.19,''), +(467,45,-11072.8,1527.77,43.2,'say and quest credit'); diff --git a/src/server/scripts/EasternKingdoms/zone_westfall.cpp b/src/server/scripts/EasternKingdoms/zone_westfall.cpp index 350ceead706..d01806028c6 100644 --- a/src/server/scripts/EasternKingdoms/zone_westfall.cpp +++ b/src/server/scripts/EasternKingdoms/zone_westfall.cpp @@ -19,13 +19,12 @@ /* ScriptData SDName: Westfall SD%Complete: 90 -SDComment: Quest support: 155, 1651 +SDComment: Quest support: 1651 SDCategory: Westfall EndScriptData */ /* ContentData npc_daphne_stilwell -npc_defias_traitor EndContentData */ #include "ScriptMgr.h" @@ -202,79 +201,7 @@ public: }; }; -/*###### -## npc_defias_traitor -######*/ -enum DefiasSays -{ - SAY_START = 0, - SAY_PROGRESS = 1, - SAY_END = 2, - SAY_AGGRO = 3 -}; - - -#define QUEST_DEFIAS_BROTHERHOOD 155 - -class npc_defias_traitor : public CreatureScript -{ -public: - npc_defias_traitor() : CreatureScript("npc_defias_traitor") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) OVERRIDE - { - if (quest->GetQuestId() == QUEST_DEFIAS_BROTHERHOOD) - { - if (npc_escortAI* pEscortAI = CAST_AI(npc_defias_traitor::npc_defias_traitorAI, creature->AI())) - pEscortAI->Start(true, true, player->GetGUID()); - - creature->AI()->Talk(SAY_START, player); - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new npc_defias_traitorAI(creature); - } - - struct npc_defias_traitorAI : public npc_escortAI - { - npc_defias_traitorAI(Creature* creature) : npc_escortAI(creature) { Reset(); } - - void WaypointReached(uint32 waypointId) OVERRIDE - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 35: - SetRun(false); - break; - case 36: - Talk(SAY_PROGRESS, player); - break; - case 44: - Talk(SAY_END, player); - player->GroupEventHappens(QUEST_DEFIAS_BROTHERHOOD, me); - break; - } - } - - void EnterCombat(Unit* who) OVERRIDE - { - Talk(SAY_AGGRO, who); - } - - void Reset() OVERRIDE { } - }; -}; - void AddSC_westfall() { new npc_daphne_stilwell(); - new npc_defias_traitor(); } -- 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') 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 38c33f687c458813d0264d442d46d5aa94acf947 Mon Sep 17 00:00:00 2001 From: untaught Date: Wed, 19 Mar 2014 12:12:59 +0200 Subject: Core/Scripts: Move condition for 'npc_skorn_whitecloud' gossip menu option to DB and remove 'npc_skorn_whitecloud' script --- .../world/2014_03_19_00_world_conditions.sql | 4 +++ src/server/scripts/Kalimdor/zone_mulgore.cpp | 37 ---------------------- 2 files changed, 4 insertions(+), 37 deletions(-) create mode 100644 sql/updates/world/2014_03_19_00_world_conditions.sql (limited to 'src/server/scripts') diff --git a/sql/updates/world/2014_03_19_00_world_conditions.sql b/sql/updates/world/2014_03_19_00_world_conditions.sql new file mode 100644 index 00000000000..fdbb175017d --- /dev/null +++ b/sql/updates/world/2014_03_19_00_world_conditions.sql @@ -0,0 +1,4 @@ +UPDATE `creature_template` SET `scriptname`='' WHERE `entry`=3052; +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=24 AND `SourceEntry`=0; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(15,24,0,0,0,8,0,770,0,0,1,0,0,'','Show gossip menu option if player has no quest ''The Demon Scarred Cloak'' rewarded'); diff --git a/src/server/scripts/Kalimdor/zone_mulgore.cpp b/src/server/scripts/Kalimdor/zone_mulgore.cpp index f70460ec7b6..f8cc21da209 100644 --- a/src/server/scripts/Kalimdor/zone_mulgore.cpp +++ b/src/server/scripts/Kalimdor/zone_mulgore.cpp @@ -24,7 +24,6 @@ SDCategory: Mulgore EndScriptData */ /* ContentData -npc_skorn_whitecloud npc_kyle_frenzied npc_plains_vision EndContentData */ @@ -35,41 +34,6 @@ EndContentData */ #include "Player.h" #include "SpellInfo.h" -/*###### -# npc_skorn_whitecloud -######*/ - -#define GOSSIP_SW "Tell me a story, Skorn." - -class npc_skorn_whitecloud : public CreatureScript -{ -public: - npc_skorn_whitecloud() : CreatureScript("npc_skorn_whitecloud") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF) - player->SEND_GOSSIP_MENU(523, creature->GetGUID()); - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) OVERRIDE - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (!player->GetQuestRewardStatus(770)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SW, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(522, creature->GetGUID()); - - return true; - } - -}; - /*##### # npc_kyle_frenzied ######*/ @@ -321,7 +285,6 @@ public: void AddSC_mulgore() { - new npc_skorn_whitecloud(); new npc_kyle_frenzied(); new npc_plains_vision(); } -- cgit v1.2.3 From f59eabdf8f5af522a0d49546eadef8343cd9e9ef Mon Sep 17 00:00:00 2001 From: untaught Date: Wed, 19 Mar 2014 18:43:39 +0200 Subject: Core/Scripts: Move condition for 'npc_marin_noggenfogger' gossip menu option to DB and remove 'npc_marin_noggenfogger' script --- .../world/2014_03_19_01_world_conditions.sql | 9 ++++++ src/server/scripts/Kalimdor/zone_tanaris.cpp | 37 +--------------------- 2 files changed, 10 insertions(+), 36 deletions(-) create mode 100644 sql/updates/world/2014_03_19_01_world_conditions.sql (limited to 'src/server/scripts') diff --git a/sql/updates/world/2014_03_19_01_world_conditions.sql b/sql/updates/world/2014_03_19_01_world_conditions.sql new file mode 100644 index 00000000000..8e983892eab --- /dev/null +++ b/sql/updates/world/2014_03_19_01_world_conditions.sql @@ -0,0 +1,9 @@ +UPDATE `creature_template` SET `scriptname`='' WHERE `entry`=7564; + +DELETE FROM `gossip_menu_option` WHERE `menu_id`=922; +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 +(922,0,1,'I''d like to browse your goods.',3,128,0,0,0,0,NULL); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=922 AND `SourceEntry`=0; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(15,922,0,0,0,8,0,2662,0,0,0,0,0,'','Show gossip menu option if only player has ''Noggenfogger Elixir'' quest rewarded'); diff --git a/src/server/scripts/Kalimdor/zone_tanaris.cpp b/src/server/scripts/Kalimdor/zone_tanaris.cpp index 204a2960611..3ced3c7115d 100644 --- a/src/server/scripts/Kalimdor/zone_tanaris.cpp +++ b/src/server/scripts/Kalimdor/zone_tanaris.cpp @@ -19,14 +19,13 @@ /* ScriptData SDName: Tanaris SD%Complete: 80 -SDComment: Quest support: 648, 1560, 2954, 4005, 10277, 10279(Special flight path). Noggenfogger vendor +SDComment: Quest support: 648, 1560, 2954, 4005, 10277, 10279(Special flight path). SDCategory: Tanaris EndScriptData */ /* ContentData npc_aquementas npc_custodian_of_time -npc_marin_noggenfogger npc_steward_of_time npc_stone_watcher_of_norgannon npc_OOX17 @@ -281,39 +280,6 @@ public: }; -/*###### -## npc_marin_noggenfogger -######*/ - -class npc_marin_noggenfogger : public CreatureScript -{ -public: - npc_marin_noggenfogger() : CreatureScript("npc_marin_noggenfogger") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(creature->GetGUID()); - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) OVERRIDE - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (creature->IsVendor() && player->GetQuestRewardStatus(2662)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - -}; - /*###### ## npc_steward_of_time ######*/ @@ -681,7 +647,6 @@ void AddSC_tanaris() { new npc_aquementas(); new npc_custodian_of_time(); - new npc_marin_noggenfogger(); new npc_steward_of_time(); new npc_stone_watcher_of_norgannon(); new npc_OOX17(); -- cgit v1.2.3 From 8a9bfbba481dc61a229a04e0ad618911b9cd360f Mon Sep 17 00:00:00 2001 From: untaught Date: Thu, 20 Mar 2014 20:29:06 +0200 Subject: Core/Scripts: Move 'npc_deathly_usher' scripts to SAI. --- sql/updates/world/2014_03_20_01_world_sai.sql | 4 +++ .../scripts/EasternKingdoms/zone_blasted_lands.cpp | 33 +--------------------- 2 files changed, 5 insertions(+), 32 deletions(-) create mode 100644 sql/updates/world/2014_03_20_01_world_sai.sql (limited to 'src/server/scripts') diff --git a/sql/updates/world/2014_03_20_01_world_sai.sql b/sql/updates/world/2014_03_20_01_world_sai.sql new file mode 100644 index 00000000000..8b8e318b524 --- /dev/null +++ b/sql/updates/world/2014_03_20_01_world_sai.sql @@ -0,0 +1,4 @@ +UPDATE `creature_template` SET `ainame`='SmartAI', `scriptname`='' WHERE `entry`=8816; +DELETE FROM `smart_scripts` WHERE `entryorguid`=8816 AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(8816,0,0,0,62,0,100,0,1541,0,0,0,11,12885,2,0,0,0,0,7,0,0,0,0,0,0,0,'On Gossip Option Selected - Cast ''Teleport to Razelikh'''); diff --git a/src/server/scripts/EasternKingdoms/zone_blasted_lands.cpp b/src/server/scripts/EasternKingdoms/zone_blasted_lands.cpp index 3fcd3c093b7..bc09983fee1 100644 --- a/src/server/scripts/EasternKingdoms/zone_blasted_lands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_blasted_lands.cpp @@ -17,11 +17,7 @@ /* Blasted_Lands -Quest support: 3628. Teleporter to Rise of the Defiler. -*/ - -/* -npc_deathly_usher +Quest support: 3628. */ #include "ScriptMgr.h" @@ -31,10 +27,6 @@ npc_deathly_usher #include "Player.h" #include "Group.h" -/*###### -## npc_deathly_usher -######*/ - enum DeathlyUsher { SPELL_TELEPORT_SINGLE = 12885, @@ -42,28 +34,6 @@ enum DeathlyUsher SPELL_TELEPORT_GROUP = 27686 }; -class npc_deathly_usher : public CreatureScript -{ -public: - npc_deathly_usher() : CreatureScript("npc_deathly_usher") { } - - struct npc_deathly_usherAI : public ScriptedAI - { - npc_deathly_usherAI(Creature* creature) : ScriptedAI(creature) { } - - void sGossipSelect(Player* player, uint32 /*sender*/, uint32 /*action*/) OVERRIDE - { - player->CLOSE_GOSSIP_MENU(); - me->CastSpell(player, SPELL_TELEPORT_GROUP, true); - } - }; - - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new npc_deathly_usherAI(creature); - } -}; - /*##### # spell_razelikh_teleport_group #####*/ @@ -113,6 +83,5 @@ class spell_razelikh_teleport_group : public SpellScriptLoader void AddSC_blasted_lands() { - new npc_deathly_usher(); new spell_razelikh_teleport_group(); } -- cgit v1.2.3 From 4c27c83efa811d128d4f2cbeb34afe6fcdacd5d8 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Thu, 20 Mar 2014 21:34:05 +0100 Subject: Core/Misc: Fix some static analysis issues --- src/server/game/Conditions/ConditionMgr.cpp | 2 +- src/server/game/Entities/Object/Object.cpp | 8 ++++---- src/server/game/Entities/Unit/Unit.h | 6 ++++++ src/server/scripts/Commands/cs_misc.cpp | 4 ++-- src/tools/vmap4_extractor/mpq_libmpq04.h | 5 ++++- 5 files changed, 17 insertions(+), 8 deletions(-) (limited to 'src/server/scripts') diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index e76ba18f1e2..c3ef88fef05 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -1994,7 +1994,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) } case CONDITION_UNIT_STATE: { - if (cond->ConditionValue1 > uint32(UNIT_STATE_ALL_STATE)) + if (!(cond->ConditionValue1 & UNIT_STATE_ALL_STATE_SUPPORTED)) { TC_LOG_ERROR("sql.sql", "UnitState condition has non existing UnitState in value1 (%u), skipped", cond->ConditionValue1); return false; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 822ea049252..4993f0f500a 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -739,7 +739,7 @@ void Object::SetByteValue(uint16 index, uint8 offset, uint8 value) { ASSERT(index < m_valuesCount || PrintIndexError(index, true)); - if (offset > 4) + if (offset > 3) { TC_LOG_ERROR("misc", "Object::SetByteValue: wrong offset %u", offset); return; @@ -763,7 +763,7 @@ void Object::SetUInt16Value(uint16 index, uint8 offset, uint16 value) { ASSERT(index < m_valuesCount || PrintIndexError(index, true)); - if (offset > 2) + if (offset > 1) { TC_LOG_ERROR("misc", "Object::SetUInt16Value: wrong offset %u", offset); return; @@ -903,7 +903,7 @@ void Object::SetByteFlag(uint16 index, uint8 offset, uint8 newFlag) { ASSERT(index < m_valuesCount || PrintIndexError(index, true)); - if (offset > 4) + if (offset > 3) { TC_LOG_ERROR("misc", "Object::SetByteFlag: wrong offset %u", offset); return; @@ -926,7 +926,7 @@ void Object::RemoveByteFlag(uint16 index, uint8 offset, uint8 oldFlag) { ASSERT(index < m_valuesCount || PrintIndexError(index, true)); - if (offset > 4) + if (offset > 3) { TC_LOG_ERROR("misc", "Object::RemoveByteFlag: wrong offset %u", offset); return; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 751bfcb8126..6b6d844472a 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -513,6 +513,12 @@ enum UnitState UNIT_STATE_CHASE_MOVE = 0x04000000, UNIT_STATE_FOLLOW_MOVE = 0x08000000, UNIT_STATE_IGNORE_PATHFINDING = 0x10000000, // do not use pathfinding in any MovementGenerator + UNIT_STATE_ALL_STATE_SUPPORTED = UNIT_STATE_DIED | UNIT_STATE_MELEE_ATTACKING | UNIT_STATE_STUNNED | UNIT_STATE_ROAMING | UNIT_STATE_CHASE + | UNIT_STATE_FLEEING | UNIT_STATE_IN_FLIGHT | UNIT_STATE_FOLLOW | UNIT_STATE_ROOT | UNIT_STATE_CONFUSED + | UNIT_STATE_DISTRACTED | UNIT_STATE_ISOLATED | UNIT_STATE_ATTACK_PLAYER | UNIT_STATE_CASTING + | UNIT_STATE_POSSESSED | UNIT_STATE_CHARGING | UNIT_STATE_JUMPING | UNIT_STATE_MOVE | UNIT_STATE_ROTATING + | UNIT_STATE_EVADE | UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE + | UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE | UNIT_STATE_IGNORE_PATHFINDING, UNIT_STATE_UNATTACKABLE = UNIT_STATE_IN_FLIGHT, // for real move using movegen check and stop (except unstoppable flight) UNIT_STATE_MOVING = UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE | UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE, diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index d0c21168c80..cae2f5e511d 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1018,7 +1018,6 @@ public: int32 area = GetAreaFlagByAreaID(atoi((char*)args)); int32 offset = area / 32; - uint32 val = uint32((1 << (area % 32))); if (area<0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) { @@ -1027,6 +1026,7 @@ public: return false; } + uint32 val = uint32((1 << (area % 32))); uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields | val))); @@ -1049,7 +1049,6 @@ public: int32 area = GetAreaFlagByAreaID(atoi((char*)args)); int32 offset = area / 32; - uint32 val = uint32((1 << (area % 32))); if (area < 0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) { @@ -1058,6 +1057,7 @@ public: return false; } + uint32 val = uint32((1 << (area % 32))); uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields ^ val))); diff --git a/src/tools/vmap4_extractor/mpq_libmpq04.h b/src/tools/vmap4_extractor/mpq_libmpq04.h index d045abe307a..46cb50fb003 100644 --- a/src/tools/vmap4_extractor/mpq_libmpq04.h +++ b/src/tools/vmap4_extractor/mpq_libmpq04.h @@ -36,7 +36,7 @@ public: mpq_archive_s *mpq_a; MPQArchive(const char* filename); - void close(); + ~MPQArchive() { close(); } void GetFileListTo(vector& filelist) { uint32_t filenum; @@ -65,6 +65,9 @@ public: delete[] buffer; } + +private: + void close(); }; typedef std::deque ArchiveSet; -- 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') 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 e40d4e6f1680128e3bf7cc4ca0c1c7dbf1074deb Mon Sep 17 00:00:00 2001 From: MitchesD Date: Fri, 21 Mar 2014 23:35:19 +0100 Subject: Scripts/Spells: fix logic fail in q9874 --- sql/updates/world/2014_03_22_00_world_creature_template.sql | 1 + src/server/scripts/Spells/spell_quest.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 sql/updates/world/2014_03_22_00_world_creature_template.sql (limited to 'src/server/scripts') diff --git a/sql/updates/world/2014_03_22_00_world_creature_template.sql b/sql/updates/world/2014_03_22_00_world_creature_template.sql new file mode 100644 index 00000000000..21409b157c2 --- /dev/null +++ b/sql/updates/world/2014_03_22_00_world_creature_template.sql @@ -0,0 +1 @@ +UPDATE `creature_template` SET `ScriptName`='' WHERE `entry`=18240; diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index cdf32bd94d5..d1b32570795 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -903,7 +903,7 @@ class spell_q12659_ahunaes_knife : public SpellScriptLoader enum StoppingTheSpread { NPC_VILLAGER_KILL_CREDIT = 18240, - SPELL_FLAMES = 39199, + SPELL_FLAMES = 39199 }; class spell_q9874_liquid_fire : public SpellScriptLoader @@ -926,7 +926,7 @@ class spell_q9874_liquid_fire : public SpellScriptLoader { Player* caster = GetCaster()->ToPlayer(); if (Creature* target = GetHitCreature()) - if (target && target->HasAura(SPELL_FLAMES)) + if (target && !target->HasAura(SPELL_FLAMES)) { caster->KilledMonsterCredit(NPC_VILLAGER_KILL_CREDIT, 0); target->CastSpell(target, SPELL_FLAMES, true); -- 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') 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') 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 d9d088421d1ffdc29445c59ccaac520550f06c0c Mon Sep 17 00:00:00 2001 From: MitchesD Date: Sat, 22 Mar 2014 22:30:20 +0100 Subject: Scripts/ZulAman/Halazzi: convert text to create_text and fixed despawn of cat --- .../world/2014_03_22_02_world_creature_text.sql | 12 +++ .../EasternKingdoms/ZulAman/boss_halazzi.cpp | 99 +++++++--------------- 2 files changed, 43 insertions(+), 68 deletions(-) create mode 100644 sql/updates/world/2014_03_22_02_world_creature_text.sql (limited to 'src/server/scripts') diff --git a/sql/updates/world/2014_03_22_02_world_creature_text.sql b/sql/updates/world/2014_03_22_02_world_creature_text.sql new file mode 100644 index 00000000000..89014367a71 --- /dev/null +++ b/sql/updates/world/2014_03_22_02_world_creature_text.sql @@ -0,0 +1,12 @@ +SET @ENTRY := 23557; +DELETE FROM `creature_text` WHERE `entry`=@ENTRY; +INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`) VALUES +(@ENTRY, 0, 0, "Get on your knees and bow to da fang and claw!", 14, 0, 100, 0, 0, 12020, "Halazzi - Aggro"), +(@ENTRY, 1, 0, "You gonna leave in pieces!", 14, 0, 100, 0, 0, 0, "Halazzi - Saber"), +(@ENTRY, 1, 1, "Me gonna carve ya now!", 14, 0, 100, 0, 0, 0, "Halazzi - Saber"), +(@ENTRY, 2, 0, "Me gonna carve ya now!", 14, 0, 100, 0, 0, 12021, "Halazzi - Split"), +(@ENTRY, 3, 0, "Spirit, come back to me!", 14, 0, 100, 0, 0, 12022, "Halazzi - Merge"), +(@ENTRY, 4, 0, "You cant fight the power!", 14, 0, 100, 0, 0, 12026, "Halazzi - Killed unit"), +(@ENTRY, 4, 1, "You gonna fail!", 14, 0, 100, 0, 0, 12027, "Halazzi - Killed unit"), +(@ENTRY, 5, 0, "Chaga... choka'jinn.", 14, 0, 100, 0, 0, 12028, "Halazzi - Death"), +(@ENTRY, 6, 0, "Whatch you be doing? Pissin' yourselves...", 14, 0, 100, 0, 0, 12025, "Halazzi - Death"); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp index 4e354b47be5..0c8eb663c9a 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp @@ -16,35 +16,11 @@ * with this program. If not, see . */ -/* ScriptData -SDName: boss_Halazzi -SD%Complete: 80 -SDComment: -SDCategory: Zul'Aman -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "zulaman.h" #include "SpellInfo.h" -#define YELL_AGGRO "Get on your knees and bow to da fang and claw!" -#define SOUND_AGGRO 12020 -#define YELL_SABER_ONE "You gonna leave in pieces!" -#define YELL_SABER_TWO "Me gonna carve ya now!" -#define YELL_SPLIT "Me gonna carve ya now!" -#define SOUND_SPLIT 12021 -#define YELL_MERGE "Spirit, come back to me!" -#define SOUND_MERGE 12022 -#define YELL_KILL_ONE "You cant fight the power!" -#define SOUND_KILL_ONE 12026 -#define YELL_KILL_TWO "You gonna fail!" -#define SOUND_KILL_TWO 12027 -#define YELL_DEATH "Chaga... choka'jinn." -#define SOUND_DEATH 12028 -#define YELL_BERSERK "Whatch you be doing? Pissin' yourselves..." -#define SOUND_BERSERK 12025 - enum Spells { SPELL_DUAL_WIELD = 29651, @@ -78,23 +54,32 @@ enum PhaseHalazzi PHASE_ENRAGE = 5 }; +enum Yells +{ + SAY_AGGRO = 0, + SAY_SABER = 1, + SAY_SPLIT = 2, + SAY_MERGE = 3, + SAY_KILL = 4, + SAY_DEATH = 5, + SAY_BERSERK = 6 +}; + class boss_halazzi : public CreatureScript { public: - - boss_halazzi() - : CreatureScript("boss_halazzi") - { - } + boss_halazzi() : CreatureScript("boss_halazzi") { } struct boss_halazziAI : public ScriptedAI { - boss_halazziAI(Creature* creature) : ScriptedAI(creature) + boss_halazziAI(Creature* creature) : ScriptedAI(creature), summons(me) { instance = creature->GetInstanceScript(); } InstanceScript* instance; + SummonList summons; + PhaseHalazzi Phase; uint32 FrenzyTimer; uint32 SaberlashTimer; @@ -102,16 +87,14 @@ class boss_halazzi : public CreatureScript uint32 TotemTimer; uint32 CheckTimer; uint32 BerserkTimer; - uint32 TransformCount; - PhaseHalazzi Phase; - uint64 LynxGUID; void Reset() OVERRIDE { instance->SetData(DATA_HALAZZIEVENT, NOT_STARTED); + summons.DespawnAll(); LynxGUID = 0; TransformCount = 0; @@ -127,10 +110,7 @@ class boss_halazzi : public CreatureScript void EnterCombat(Unit* /*who*/) OVERRIDE { instance->SetData(DATA_HALAZZIEVENT, IN_PROGRESS); - - me->MonsterYell(YELL_AGGRO, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_AGGRO); - + Talk(SAY_AGGRO); EnterPhase(PHASE_LYNX); } @@ -139,6 +119,7 @@ class boss_halazzi : public CreatureScript summon->AI()->AttackStart(me->GetVictim()); if (summon->GetEntry() == NPC_SPIRIT_LYNX) LynxGUID = summon->GetGUID(); + summons.Summon(summon); } void DamageTaken(Unit* /*done_by*/, uint32 &damage) OVERRIDE @@ -155,7 +136,8 @@ class boss_halazzi : public CreatureScript void AttackStart(Unit* who) OVERRIDE { - if (Phase != PHASE_MERGE) ScriptedAI::AttackStart(who); + if (Phase != PHASE_MERGE) + ScriptedAI::AttackStart(who); } void EnterPhase(PhaseHalazzi NextPhase) @@ -180,8 +162,7 @@ class boss_halazzi : public CreatureScript TotemTimer = 12000; break; case PHASE_SPLIT: - me->MonsterYell(YELL_SPLIT, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_SPLIT); + Talk(SAY_SPLIT); DoCast(me, SPELL_TRANSFORM_SPLIT, true); break; case PHASE_HUMAN: @@ -195,8 +176,7 @@ class boss_halazzi : public CreatureScript case PHASE_MERGE: if (Unit* pLynx = Unit::GetUnit(*me, LynxGUID)) { - me->MonsterYell(YELL_MERGE, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_MERGE); + Talk(SAY_MERGE); pLynx->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); pLynx->GetMotionMaster()->Clear(); pLynx->GetMotionMaster()->MoveFollow(me, 0, 0); @@ -211,15 +191,14 @@ class boss_halazzi : public CreatureScript Phase = NextPhase; } - void UpdateAI(uint32 diff) OVERRIDE + void UpdateAI(uint32 diff) OVERRIDE { if (!UpdateVictim()) return; if (BerserkTimer <= diff) { - me->MonsterYell(YELL_BERSERK, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_BERSERK); + Talk(SAY_BERSERK); DoCast(me, SPELL_BERSERK, true); BerserkTimer = 60000; } else BerserkTimer -= diff; @@ -313,28 +292,18 @@ class boss_halazzi : public CreatureScript DoMeleeAttackIfReady(); } - void KilledUnit(Unit* /*victim*/) OVERRIDE + void KilledUnit(Unit* victim) OVERRIDE { - switch (urand(0, 1)) - { - case 0: - me->MonsterYell(YELL_KILL_ONE, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_KILL_ONE); - break; - - case 1: - me->MonsterYell(YELL_KILL_TWO, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_KILL_TWO); - break; - } + if (victim->GetTypeId() != TYPEID_PLAYER) + return; + + Talk(SAY_KILL); } void JustDied(Unit* /*killer*/) OVERRIDE { instance->SetData(DATA_HALAZZIEVENT, DONE); - - me->MonsterYell(YELL_DEATH, LANG_UNIVERSAL, NULL); - DoPlaySoundToSet(me, SOUND_DEATH); + Talk(SAY_DEATH); } }; @@ -348,11 +317,7 @@ class boss_halazzi : public CreatureScript class npc_halazzi_lynx : public CreatureScript { public: - - npc_halazzi_lynx() - : CreatureScript("npc_halazzi_lynx") - { - } + npc_halazzi_lynx() : CreatureScript("npc_halazzi_lynx") { } struct npc_halazzi_lynxAI : public ScriptedAI { @@ -414,5 +379,3 @@ void AddSC_boss_halazzi() new boss_halazzi(); new npc_halazzi_lynx(); } - - -- 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') 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') 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') 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') 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') 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') 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') 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') 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') 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') 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') 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 From 29610b250dd5017f068264d9b1a37748c9f30feb Mon Sep 17 00:00:00 2001 From: joschiwald Date: Sat, 5 Apr 2014 00:37:07 +0200 Subject: Core/Spells: fixed Throw Shield Visual and Clone Weapon --- .../2014_04_05_00_world_spell_script_names.sql | 7 ++++ src/server/game/Spells/SpellEffects.cpp | 3 -- src/server/scripts/Spells/spell_generic.cpp | 45 ++++++++++++++++++---- 3 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 sql/updates/world/2014_04_05_00_world_spell_script_names.sql (limited to 'src/server/scripts') diff --git a/sql/updates/world/2014_04_05_00_world_spell_script_names.sql b/sql/updates/world/2014_04_05_00_world_spell_script_names.sql new file mode 100644 index 00000000000..f5abac98e78 --- /dev/null +++ b/sql/updates/world/2014_04_05_00_world_spell_script_names.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` IN (41213, 43416, 69222, 73076, 45204); +INSERT INTO `spell_script_names` (`spell_id` ,`ScriptName`) VALUES +(41213, 'spell_gen_throw_shield'), +(43416, 'spell_gen_throw_shield'), +(69222, 'spell_gen_throw_shield'), +(73076, 'spell_gen_throw_shield'), +(45204, 'spell_gen_clone'); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 609c9ba05be..28bc659050a 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3595,9 +3595,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) } return; } - case 45204: // Clone Me! - m_caster->CastSpell(unitTarget, damage, true); - break; case 55693: // Remove Collapsing Cave Aura if (!unitTarget) return; diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 68c16a1b2d6..65aa22c776d 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -711,7 +711,7 @@ class spell_gen_clone : public SpellScriptLoader void HandleScriptEffect(SpellEffIndex effIndex) { PreventHitDefaultEffect(effIndex); - GetHitUnit()->CastSpell(GetCaster(), GetEffectValue(), true); + GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true); } void Register() OVERRIDE @@ -751,10 +751,7 @@ class spell_gen_clone_weapon : public SpellScriptLoader void HandleScriptEffect(SpellEffIndex effIndex) { PreventHitDefaultEffect(effIndex); - Unit* caster = GetCaster(); - - if (Unit* target = GetHitUnit()) - caster->CastSpell(target, GetEffectValue(), true); + GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true); } void Register() OVERRIDE @@ -778,8 +775,6 @@ class spell_gen_clone_weapon_aura : public SpellScriptLoader { PrepareAuraScript(spell_gen_clone_weapon_auraScript); - uint32 prevItem; - bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE { if (!sSpellMgr->GetSpellInfo(SPELL_COPY_WEAPON_AURA) || @@ -792,6 +787,12 @@ class spell_gen_clone_weapon_aura : public SpellScriptLoader return true; } + bool Load() OVERRIDE + { + prevItem = 0; + return true; + } + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Unit* caster = GetCaster(); @@ -877,6 +878,8 @@ class spell_gen_clone_weapon_aura : public SpellScriptLoader OnEffectRemove += AuraEffectRemoveFn(spell_gen_clone_weapon_auraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); } + private: + uint32 prevItem; }; AuraScript* GetAuraScript() const OVERRIDE @@ -3282,6 +3285,33 @@ class spell_gen_summon_tournament_mount : public SpellScriptLoader } }; +// 41213, 43416, 69222, 73076 - Throw Shield +class spell_gen_throw_shield : public SpellScriptLoader +{ + public: + spell_gen_throw_shield() : SpellScriptLoader("spell_gen_throw_shield") { } + + class spell_gen_throw_shield_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_throw_shield_SpellScript); + + void HandleScriptEffect(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true); + } + + void Register() OVERRIDE + { + OnEffectHitTarget += SpellEffectFn(spell_gen_throw_shield_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_gen_throw_shield_SpellScript(); + } +}; enum MountedDuelSpells { @@ -3773,6 +3803,7 @@ void AddSC_generic_spell_scripts() new spell_gen_summon_elemental("spell_gen_summon_fire_elemental", SPELL_SUMMON_FIRE_ELEMENTAL); new spell_gen_summon_elemental("spell_gen_summon_earth_elemental", SPELL_SUMMON_EARTH_ELEMENTAL); new spell_gen_summon_tournament_mount(); + new spell_gen_throw_shield(); new spell_gen_tournament_duel(); new spell_gen_tournament_pennant(); new spell_pvp_trinket_wotf_shared_cd(); -- cgit v1.2.3