diff options
Diffstat (limited to 'src')
15 files changed, 475 insertions, 315 deletions
diff --git a/src/server/game/Entities/Object/Position.cpp b/src/server/game/Entities/Object/Position.cpp index e31b913a25a..530e51cd8f5 100644 --- a/src/server/game/Entities/Object/Position.cpp +++ b/src/server/game/Entities/Object/Position.cpp @@ -17,6 +17,8 @@ #include "Position.h" #include "ByteBuffer.h" +#include "G3D/g3dmath.h" +#include "GridDefines.h" bool Position::operator==(Position const &a) { diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp index 97e3880161a..f91fc1985d5 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -367,7 +367,7 @@ void FlightPathMovementGenerator::InitEndGridInfo() _endMapId = (*i_path)[nodeCount - 1].MapID; //! MapId of last node _preloadTargetNode = nodeCount - 3; _endGridX = (*i_path)[nodeCount - 1].LocX; - _endGridY = (*i_path)[nodeCount - 1].LocZ; + _endGridY = (*i_path)[nodeCount - 1].LocY; } void FlightPathMovementGenerator::PreloadEndGrid() diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 8be5da91c32..f0ee013bcc2 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -622,6 +622,7 @@ void AddSC_instance_magtheridons_lair(); void AddSC_boss_grand_warlock_nethekurse(); //HC Shattered Halls void AddSC_boss_warbringer_omrogg(); void AddSC_boss_warchief_kargath_bladefist(); +void AddSC_shattered_halls(); void AddSC_instance_shattered_halls(); void AddSC_boss_watchkeeper_gargolmar(); //HC Ramparts void AddSC_boss_omor_the_unscarred(); @@ -1152,6 +1153,7 @@ void AddOutlandScripts() AddSC_boss_grand_warlock_nethekurse(); //HC Shattered Halls AddSC_boss_warbringer_omrogg(); AddSC_boss_warchief_kargath_bladefist(); + AddSC_shattered_halls(); AddSC_instance_shattered_halls(); AddSC_boss_watchkeeper_gargolmar(); //HC Ramparts AddSC_boss_omor_the_unscarred(); diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp index b16993f28a3..09e3be690b1 100644 --- a/src/server/game/Spells/SpellHistory.cpp +++ b/src/server/game/Spells/SpellHistory.cpp @@ -22,6 +22,7 @@ #include "SpellInfo.h" #include "Spell.h" #include "World.h" +#include "Opcodes.h" SpellHistory::Clock::duration const SpellHistory::InfinityCooldownDelay = std::chrono::duration_cast<SpellHistory::Clock::duration>(std::chrono::seconds(MONTH)); SpellHistory::Clock::duration const SpellHistory::InfinityCooldownDelayCheck = std::chrono::duration_cast<SpellHistory::Clock::duration>(std::chrono::seconds(MONTH / 2)); @@ -627,6 +628,7 @@ void SpellHistory::BuildCooldownPacket(WorldPacket& data, uint8 flags, uint32 sp void SpellHistory::BuildCooldownPacket(WorldPacket& data, uint8 flags, PacketCooldowns const& cooldowns) const { data.Initialize(SMSG_SPELL_COOLDOWN, 8 + 1 + (4 + 4) * cooldowns.size()); + data << uint64(_owner->GetGUID()); data << uint8(flags); for (auto const& cooldown : cooldowns) { diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 191850516d4..13290320084 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2955,7 +2955,7 @@ void SpellMgr::LoadSpellInfoCorrections() switch (spellInfo->Id) { case 63026: // Force Cast (HACK: Target shouldn't be changed) - case 63171: // Force Cast (HACK: Target shouldn't be changed; summon position should be untied from spell destination) + case 63137: // Force Cast (HACK: Target shouldn't be changed; summon position should be untied from spell destination) spellInfo->Effects[0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB); break; case 53096: // Quetz'lun's Judgment @@ -3134,6 +3134,7 @@ void SpellMgr::LoadSpellInfoCorrections() case 64823: // Item - Druid T8 Balance 4P Bonus case 34477: // Misdirection case 44401: // Missile Barrage + case 18820: // Insight spellInfo->ProcCharges = 1; break; case 44544: // Fingers of Frost diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 63082808e03..d7a580800bc 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -1060,8 +1060,8 @@ class spell_putricide_ooze_eruption_searcher : public SpellScriptLoader uint32 adhesiveId = sSpellMgr->GetSpellIdForDifficulty(SPELL_VOLATILE_OOZE_ADHESIVE, GetCaster()); if (GetHitUnit()->HasAura(adhesiveId)) { - GetCaster()->CastSpell(GetHitUnit(), SPELL_OOZE_ERUPTION, true); GetHitUnit()->RemoveAurasDueToSpell(adhesiveId, GetCaster()->GetGUID(), 0, AURA_REMOVE_BY_ENEMY_SPELL); + GetCaster()->CastSpell(GetHitUnit(), SPELL_OOZE_ERUPTION, true); } } diff --git a/src/server/scripts/Outland/CMakeLists.txt b/src/server/scripts/Outland/CMakeLists.txt index 24658dbc21f..42621b76941 100644 --- a/src/server/scripts/Outland/CMakeLists.txt +++ b/src/server/scripts/Outland/CMakeLists.txt @@ -27,6 +27,7 @@ set(scripts_STAT_SRCS Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp + Outland/HellfireCitadel/ShatteredHalls/shattered_halls.cpp Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp Outland/HellfireCitadel/ShatteredHalls/boss_warbringer_omrogg.cpp Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp index 21ed710f4d8..7f2e08b39ca 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp @@ -87,11 +87,11 @@ class boss_warchief_kargath_bladefist : public CreatureScript resetcheck_timer = 5000; } - void SetData(uint32 type, uint32 data) override + void DoAction(int32 action) override { - if (type == 1) + if (action == ACTION_EXECUTIONER_TAUNT) { - switch (data) + switch (instance->GetData(DATA_TEAM_IN_INSTANCE)) { case ALLIANCE: Talk(SAY_CALL_EXECUTIONER_A); diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp index 6939b15585a..5cfae286f9b 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp @@ -32,20 +32,11 @@ EndScriptData */ #include "SpellAuras.h" #include "shattered_halls.h" -enum Spells -{ - SPELL_CLEAVE = 15284, - - SPELL_EXECUTE_1 = 39288, - SPELL_EXECUTE_2, - SPELL_EXECUTE_3 -}; - DoorData const doorData[] = { - {GO_GRAND_WARLOCK_CHAMBER_DOOR_1, DATA_NETHEKURSE, DOOR_TYPE_PASSAGE, BOUNDARY_S }, - {GO_GRAND_WARLOCK_CHAMBER_DOOR_2, DATA_NETHEKURSE, DOOR_TYPE_PASSAGE, BOUNDARY_N }, - {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE} + { GO_GRAND_WARLOCK_CHAMBER_DOOR_1, DATA_NETHEKURSE, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { GO_GRAND_WARLOCK_CHAMBER_DOOR_2, DATA_NETHEKURSE, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } }; class instance_shattered_halls : public InstanceMapScript @@ -77,9 +68,7 @@ class instance_shattered_halls : public InstanceMapScript if (!_team) _team = player->GetTeam(); - player->RemoveAurasDueToSpell(SPELL_EXECUTE_1); - player->RemoveAurasDueToSpell(SPELL_EXECUTE_2); - player->RemoveAurasDueToSpell(SPELL_EXECUTE_3); + player->CastSpell(player, SPELL_REMOVE_KARGATH_EXECUTIONER, true); if (!executionTimer || executionerGUID.IsEmpty()) return; @@ -87,13 +76,13 @@ class instance_shattered_halls : public InstanceMapScript switch (executed) { case 0: - ex = player->AddAura(SPELL_EXECUTE_1, player); + ex = player->AddAura(SPELL_KARGATH_EXECUTIONER_1, player); break; case 1: - ex = player->AddAura(SPELL_EXECUTE_2, player); + ex = player->AddAura(SPELL_KARGATH_EXECUTIONER_2, player); break; case 2: - ex = player->AddAura(SPELL_EXECUTE_3, player); + ex = player->AddAura(SPELL_KARGATH_EXECUTIONER_3, player); break; default: break; @@ -151,10 +140,22 @@ class instance_shattered_halls : public InstanceMapScript break; case NPC_SHATTERED_EXECUTIONER: executionTimer = 55 * MINUTE * IN_MILLISECONDS; - DoCastSpellOnPlayers(SPELL_EXECUTE_1); + DoCastSpellOnPlayers(SPELL_KARGATH_EXECUTIONER_1); executionerGUID = creature->GetGUID(); SaveToDB(); break; + case NPC_CAPTAIN_ALINA: + case NPC_CAPTAIN_BONESHATTER: + victimsGUID[0] = creature->GetGUID(); + break; + case NPC_ALLIANCE_VICTIM_1: + case NPC_HORDE_VICTIM_1: + victimsGUID[1] = creature->GetGUID(); + break; + case NPC_ALLIANCE_VICTIM_2: + case NPC_HORDE_VICTIM_2: + victimsGUID[2] = creature->GetGUID(); + break; } } @@ -168,16 +169,14 @@ class instance_shattered_halls : public InstanceMapScript case DATA_SHATTERED_EXECUTIONER: if (state == DONE) { - DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_1); - DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_2); - DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_3); + DoCastSpellOnPlayers(SPELL_REMOVE_KARGATH_EXECUTIONER); executionTimer = 0; SaveToDB(); } break; case DATA_KARGATH: if (Creature* executioner = instance->GetCreature(executionerGUID)) - executioner->AI()->Reset(); + executioner->AI()->Reset(); // trigger removal of IMMUNE_TO_PC flag break; case DATA_OMROGG: break; @@ -191,16 +190,16 @@ class instance_shattered_halls : public InstanceMapScript { case NPC_GRAND_WARLOCK_NETHEKURSE: return nethekurseGUID; - break; case NPC_KARGATH_BLADEFIST: return kargathGUID; - break; case NPC_SHATTERED_EXECUTIONER: return executionerGUID; - break; + case DATA_FIRST_PRISONER: + case DATA_SECOND_PRISONER: + case DATA_THIRD_PRISONER: + return victimsGUID[data - DATA_FIRST_PRISONER]; default: return ObjectGuid::Empty; - break; } } @@ -253,13 +252,10 @@ class instance_shattered_halls : public InstanceMapScript { case DATA_PRISONERS_EXECUTED: return executed; - break; case DATA_TEAM_IN_INSTANCE: return _team; - break; default: return 0; - break; } } @@ -269,27 +265,25 @@ class instance_shattered_halls : public InstanceMapScript return; if (executionTimer <= diff) - { + { + DoCastSpellOnPlayers(SPELL_REMOVE_KARGATH_EXECUTIONER); switch (++executed) { case 1: - DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_1); - DoCastSpellOnPlayers(SPELL_EXECUTE_2); + DoCastSpellOnPlayers(SPELL_KARGATH_EXECUTIONER_2); executionTimer = 10 * MINUTE * IN_MILLISECONDS; break; case 2: - DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_2); - DoCastSpellOnPlayers(SPELL_EXECUTE_3); + DoCastSpellOnPlayers(SPELL_KARGATH_EXECUTIONER_3); executionTimer = 15 * MINUTE * IN_MILLISECONDS; break; default: - DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_3); executionTimer = 0; break; } if (Creature* executioner = instance->GetCreature(executionerGUID)) - executioner->AI()->SetData(1, executed); + executioner->AI()->SetData(DATA_PRISONERS_EXECUTED, executed); SaveToDB(); } @@ -297,10 +291,11 @@ class instance_shattered_halls : public InstanceMapScript executionTimer -= diff; } - protected: + private: ObjectGuid nethekurseGUID; ObjectGuid kargathGUID; ObjectGuid executionerGUID; + ObjectGuid victimsGUID[3]; uint8 executed; uint32 executionTimer; @@ -308,189 +303,7 @@ class instance_shattered_halls : public InstanceMapScript }; }; -class at_nethekurse_exit : public AreaTriggerScript -{ - public: - at_nethekurse_exit() : AreaTriggerScript("at_nethekurse_exit") { }; - - bool OnTrigger(Player* player, AreaTriggerEntry const*) override - { - if (InstanceScript* is = player->GetInstanceScript()) - { - if (is->instance->IsHeroic()) - { - Creature* executioner = nullptr; - - is->instance->LoadGrid(Executioner.GetPositionX(), Executioner.GetPositionY()); - if (Creature* kargath = ObjectAccessor::GetCreature(*player, is->GetGuidData(NPC_KARGATH_BLADEFIST))) - { - if (is->GetGuidData(NPC_SHATTERED_EXECUTIONER).IsEmpty()) - { - executioner = kargath->SummonCreature(NPC_SHATTERED_EXECUTIONER, Executioner); - kargath->AI()->SetData(1, is->GetData(DATA_TEAM_IN_INSTANCE)); - } - } - - if (executioner) - for (uint8 i = 0; i < VictimCount; ++i) - executioner->SummonCreature(executionerVictims[i](is->GetData(DATA_TEAM_IN_INSTANCE)), executionerVictims[i].GetPos()); - } - } - - return false; - } -}; - -class boss_shattered_executioner : public CreatureScript -{ - public: - boss_shattered_executioner() : CreatureScript("boss_shattered_executioner") { } - - struct boss_shattered_executionerAI : public BossAI - { - boss_shattered_executionerAI(Creature* creature) : BossAI(creature, DATA_SHATTERED_EXECUTIONER) - { - Initialize(); - }; - - void Initialize() - { - cleaveTimer = 500; - me->ResetLootMode(); - switch (instance->GetData(DATA_PRISONERS_EXECUTED)) - { - case 0: - me->AddLootMode(LOOT_MODE_HARD_MODE_3); - case 1: - me->AddLootMode(LOOT_MODE_HARD_MODE_2); - case 2: - me->AddLootMode(LOOT_MODE_HARD_MODE_1); - } - } - - void Reset() override - { - _Reset(); - if (instance->GetBossState(DATA_KARGATH) == DONE) - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - else - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - - Initialize(); - } - - void JustSummoned(Creature*) override { } - - void JustDied(Unit*) override - { - _JustDied(); - Map::PlayerList const &players = instance->instance->GetPlayers(); - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - { - Player* pl = itr->GetSource(); - uint32 qId = pl->GetTeam() == ALLIANCE ? QUEST_IMPRISONED_A : QUEST_IMPRISONED_H; - if (pl->GetQuestStatus(qId) != QUEST_STATUS_NONE && pl->GetQuestStatus(qId) != QUEST_STATUS_FAILED) - pl->CompleteQuest(qId); - } - } - - void SetData(uint32 type, uint32 data) override - { - if (type == 1) - { - uint32 entry = executionerVictims[data - 1](instance->GetData(DATA_TEAM_IN_INSTANCE)); - if (Creature* victim = me->FindNearestCreature(entry, 30.0f, true)) - me->Kill(victim); - - if (data == 1) - { - Map::PlayerList const &players = instance->instance->GetPlayers(); - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - { - Player* pl = itr->GetSource(); - uint32 qId = pl->GetTeam() == ALLIANCE ? QUEST_IMPRISONED_A : QUEST_IMPRISONED_H; - if (pl->GetQuestStatus(qId) == QUEST_STATUS_INCOMPLETE) - pl->FailQuest(qId); - } - } - - switch (data) - { - case 3: - me->RemoveLootMode(LOOT_MODE_HARD_MODE_1); - case 2: - me->RemoveLootMode(LOOT_MODE_HARD_MODE_2); - case 1: - me->RemoveLootMode(LOOT_MODE_HARD_MODE_3); - default: - break; - } - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (cleaveTimer <= diff) - { - DoCast(SPELL_CLEAVE); - cleaveTimer = urand(5000, 7000); - } - else - cleaveTimer -= diff; - - DoMeleeAttackIfReady(); - } - private: - uint32 cleaveTimer; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_shattered_executionerAI>(creature); - } -}; - -class spell_kargath_executioner : public SpellScriptLoader -{ - public: - spell_kargath_executioner() : SpellScriptLoader("spell_kargath_executioner") { } - - class spell_kargath_executioner_AuraScript : public AuraScript - { - PrepareAuraScript(spell_kargath_executioner_AuraScript); - - bool AreaCheck(Unit* target) - { - if (target->GetMap()->GetId() != 540) - return false; - - return true; - } - - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } - - void Register() override - { - DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_kargath_executioner_AuraScript::AreaCheck); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_kargath_executioner_AuraScript(); - } -}; - void AddSC_instance_shattered_halls() { new instance_shattered_halls(); - new at_nethekurse_exit(); - new boss_shattered_executioner(); - new spell_kargath_executioner(); } diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.cpp new file mode 100644 index 00000000000..81c1283768b --- /dev/null +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "InstanceScript.h" +#include "Player.h" +#include "SpellAuras.h" +#include "shattered_halls.h" + +class at_nethekurse_exit : public AreaTriggerScript +{ + public: + at_nethekurse_exit() : AreaTriggerScript("at_nethekurse_exit") { }; + + bool OnTrigger(Player* player, AreaTriggerEntry const*) override + { + if (InstanceScript* is = player->GetInstanceScript()) + { + if (is->instance->IsHeroic()) + { + Creature* executioner = nullptr; + + is->instance->LoadGrid(Executioner.GetPositionX(), Executioner.GetPositionY()); + if (Creature* kargath = ObjectAccessor::GetCreature(*player, is->GetGuidData(NPC_KARGATH_BLADEFIST))) + { + if (is->GetGuidData(NPC_SHATTERED_EXECUTIONER).IsEmpty()) + { + executioner = kargath->SummonCreature(NPC_SHATTERED_EXECUTIONER, Executioner); + kargath->AI()->DoAction(ACTION_EXECUTIONER_TAUNT); + } + } + + if (executioner) + for (uint8 i = 0; i < VictimCount; ++i) + executioner->SummonCreature(executionerVictims[i](is->GetData(DATA_TEAM_IN_INSTANCE)), executionerVictims[i].GetPos()); + } + } + + return false; + } +}; + +enum Spells +{ + SPELL_CLEAVE = 15284 +}; + +class boss_shattered_executioner : public CreatureScript +{ + public: + boss_shattered_executioner() : CreatureScript("boss_shattered_executioner") { } + + struct boss_shattered_executionerAI : public BossAI + { + boss_shattered_executionerAI(Creature* creature) : BossAI(creature, DATA_SHATTERED_EXECUTIONER) + { + Initialize(); + }; + + void Initialize() + { + cleaveTimer = 500; + } + + void Reset() override + { + _Reset(); + + // _Reset() resets the loot mode, so we add them again, if any + switch (instance->GetData(DATA_PRISONERS_EXECUTED)) + { + case 0: + me->AddLootMode(LOOT_MODE_HARD_MODE_3); + case 1: + me->AddLootMode(LOOT_MODE_HARD_MODE_2); + case 2: + me->AddLootMode(LOOT_MODE_HARD_MODE_1); + default: + break; + } + + if (instance->GetBossState(DATA_KARGATH) == DONE) + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + else + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + + Initialize(); + } + + void JustSummoned(Creature*) override { } // avoid despawn of prisoners on death/reset + + void JustDied(Unit*) override + { + _JustDied(); + + if (instance->GetData(DATA_PRISONERS_EXECUTED) > 0) + return; + + Map::PlayerList const &players = instance->instance->GetPlayers(); + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { + Player* pl = itr->GetSource(); + uint32 qId = pl->GetTeam() == ALLIANCE ? QUEST_IMPRISONED_A : QUEST_IMPRISONED_H; + if (pl->GetQuestStatus(qId) == QUEST_STATUS_INCOMPLETE) + pl->CompleteQuest(qId); + } + } + + void SetData(uint32 type, uint32 data) override + { + if (type == DATA_PRISONERS_EXECUTED && data <= 3) + { + if (Creature* victim = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FIRST_PRISONER + data - 1))) + me->Kill(victim); + + if (data == 1) + { + Map::PlayerList const &players = instance->instance->GetPlayers(); + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { + Player* pl = itr->GetSource(); + uint32 qId = pl->GetTeam() == ALLIANCE ? QUEST_IMPRISONED_A : QUEST_IMPRISONED_H; + if (pl->GetQuestStatus(qId) == QUEST_STATUS_INCOMPLETE) + pl->FailQuest(qId); + } + } + + switch (data) + { + case 3: + me->RemoveLootMode(LOOT_MODE_HARD_MODE_1); + case 2: + me->RemoveLootMode(LOOT_MODE_HARD_MODE_2); + case 1: + me->RemoveLootMode(LOOT_MODE_HARD_MODE_3); + default: + break; + } + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + if (cleaveTimer <= diff) + { + DoCast(SPELL_CLEAVE); + cleaveTimer = urand(5000, 7000); + } + else + cleaveTimer -= diff; + + DoMeleeAttackIfReady(); + } + private: + uint32 cleaveTimer; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<boss_shattered_executionerAI>(creature); + } +}; + +class spell_kargath_executioner : public SpellScriptLoader +{ + public: + spell_kargath_executioner() : SpellScriptLoader("spell_kargath_executioner") { } + + class spell_kargath_executioner_AuraScript : public AuraScript + { + PrepareAuraScript(spell_kargath_executioner_AuraScript); + + bool AreaCheck(Unit* target) + { + if (target->GetMap()->GetId() != 540) + return false; + + return true; + } + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void Register() override + { + DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_kargath_executioner_AuraScript::AreaCheck); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_kargath_executioner_AuraScript(); + } +}; + +class spell_remove_kargath_executioner : public SpellScriptLoader +{ + public: + spell_remove_kargath_executioner() : SpellScriptLoader("spell_remove_kargath_executioner") { } + + class spell_remove_kargath_executioner_SpellScript : public SpellScript + { + PrepareSpellScript(spell_remove_kargath_executioner_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* target = GetCaster(); + + target->RemoveAurasDueToSpell(SPELL_KARGATH_EXECUTIONER_1); + target->RemoveAurasDueToSpell(SPELL_KARGATH_EXECUTIONER_2); + target->RemoveAurasDueToSpell(SPELL_KARGATH_EXECUTIONER_3); + } + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_remove_kargath_executioner_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_remove_kargath_executioner_SpellScript(); + } +}; + +void AddSC_shattered_halls() +{ + new at_nethekurse_exit(); + new boss_shattered_executioner(); + new spell_kargath_executioner(); + new spell_remove_kargath_executioner(); +} diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h index adc07bec2ff..894cc9c40a6 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h @@ -33,7 +33,11 @@ enum DataTypes DATA_SHATTERED_EXECUTIONER = 3, DATA_PRISONERS_EXECUTED = 4, - DATA_TEAM_IN_INSTANCE = 5 + DATA_TEAM_IN_INSTANCE = 5, + + DATA_FIRST_PRISONER, + DATA_SECOND_PRISONER, + DATA_THIRD_PRISONER }; enum CreatureIds @@ -70,6 +74,20 @@ enum QuestIds QUEST_IMPRISONED_H = 9525 }; +enum InstanceSpells +{ + SPELL_KARGATH_EXECUTIONER_1 = 39288, + SPELL_KARGATH_EXECUTIONER_2 = 39289, + SPELL_KARGATH_EXECUTIONER_3 = 39290, + + SPELL_REMOVE_KARGATH_EXECUTIONER = 39291 +}; + +enum Actions +{ + ACTION_EXECUTIONER_TAUNT = 1 +}; + const Position Executioner = { 152.8524f, -83.63912f, 2.021005f, 0.06981317f }; struct FactionSpawnerHelper @@ -77,7 +95,7 @@ struct FactionSpawnerHelper FactionSpawnerHelper(uint32 allianceEntry, uint32 hordeEntry, const Position& pos) : _allianceNPC(allianceEntry), _hordeNPC(hordeEntry), _spawnPos(pos) { } inline uint32 operator()(uint32 teamID) const { return teamID == ALLIANCE ? _allianceNPC : _hordeNPC; } - inline const Position GetPos() const { return _spawnPos; } + inline Position const& GetPos() const { return _spawnPos; } private: const uint32 _allianceNPC; diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index d98ef2ec799..0ec8bfc3a9c 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -208,22 +208,23 @@ class spell_q6124_6129_apply_salve : public SpellScriptLoader if (GetCastItem()) if (Creature* creatureTarget = GetHitCreature()) { - uint32 uiNewEntry = 0; + uint32 newEntry = 0; switch (caster->GetTeam()) { case HORDE: if (creatureTarget->GetEntry() == NPC_SICKLY_GAZELLE) - uiNewEntry = NPC_CURED_GAZELLE; + newEntry = NPC_CURED_GAZELLE; break; case ALLIANCE: if (creatureTarget->GetEntry() == NPC_SICKLY_DEER) - uiNewEntry = NPC_CURED_DEER; + newEntry = NPC_CURED_DEER; break; } - if (uiNewEntry) + if (newEntry) { - creatureTarget->UpdateEntry(uiNewEntry); + creatureTarget->UpdateEntry(newEntry); creatureTarget->DespawnOrUnsummon(DESPAWN_TIME); + caster->KilledMonsterCredit(newEntry); } } } diff --git a/src/server/shared/Debugging/WheatyExceptionReport.cpp b/src/server/shared/Debugging/WheatyExceptionReport.cpp index f8f641a9ea7..e50cf42e439 100644 --- a/src/server/shared/Debugging/WheatyExceptionReport.cpp +++ b/src/server/shared/Debugging/WheatyExceptionReport.cpp @@ -61,6 +61,7 @@ HANDLE WheatyExceptionReport::m_hDumpFile; HANDLE WheatyExceptionReport::m_hProcess; SymbolPairs WheatyExceptionReport::symbols; std::stack<SymbolDetail> WheatyExceptionReport::symbolDetails; +bool WheatyExceptionReport::stackOverflowException; // Declare global instance of class WheatyExceptionReport g_WheatyExceptionReport; @@ -72,6 +73,7 @@ WheatyExceptionReport::WheatyExceptionReport() // Constructor // Install the unhandled exception filter function m_previousFilter = SetUnhandledExceptionFilter(WheatyUnhandledExceptionFilter); m_hProcess = GetCurrentProcess(); + stackOverflowException = false; if (!IsDebuggerPresent()) { _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); @@ -97,6 +99,9 @@ WheatyExceptionReport::~WheatyExceptionReport() LONG WINAPI WheatyExceptionReport::WheatyUnhandledExceptionFilter( PEXCEPTION_POINTERS pExceptionInfo) { + if (pExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_STACK_OVERFLOW) + stackOverflowException = true; + TCHAR module_folder_name[MAX_PATH]; GetModuleFileName(0, module_folder_name, MAX_PATH); TCHAR* pos = _tcsrchr(module_folder_name, '\\'); @@ -419,107 +424,114 @@ void WheatyExceptionReport::printTracesForAllThreads(bool bWriteVariables) void WheatyExceptionReport::GenerateExceptionReport( PEXCEPTION_POINTERS pExceptionInfo) { - SYSTEMTIME systime; - GetLocalTime(&systime); - - // Start out with a banner - _tprintf(_T("Revision: %s\r\n"), _FULLVERSION); - _tprintf(_T("Date %u:%u:%u. Time %u:%u \r\n"), systime.wDay, systime.wMonth, systime.wYear, systime.wHour, systime.wMinute); - PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord; - - PrintSystemInfo(); - // First print information about the type of fault - _tprintf(_T("\r\n//=====================================================\r\n")); - _tprintf(_T("Exception code: %08X %s\r\n"), - pExceptionRecord->ExceptionCode, - GetExceptionString(pExceptionRecord->ExceptionCode)); - - // Now print information about where the fault occured - TCHAR szFaultingModule[MAX_PATH]; - DWORD section; - DWORD_PTR offset; - GetLogicalAddress(pExceptionRecord->ExceptionAddress, - szFaultingModule, - sizeof(szFaultingModule), - section, offset); + __try + { + SYSTEMTIME systime; + GetLocalTime(&systime); + + // Start out with a banner + _tprintf(_T("Revision: %s\r\n"), _FULLVERSION); + _tprintf(_T("Date %u:%u:%u. Time %u:%u \r\n"), systime.wDay, systime.wMonth, systime.wYear, systime.wHour, systime.wMinute); + PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord; + + PrintSystemInfo(); + // First print information about the type of fault + _tprintf(_T("\r\n//=====================================================\r\n")); + _tprintf(_T("Exception code: %08X %s\r\n"), + pExceptionRecord->ExceptionCode, + GetExceptionString(pExceptionRecord->ExceptionCode)); + + // Now print information about where the fault occured + TCHAR szFaultingModule[MAX_PATH]; + DWORD section; + DWORD_PTR offset; + GetLogicalAddress(pExceptionRecord->ExceptionAddress, + szFaultingModule, + sizeof(szFaultingModule), + section, offset); #ifdef _M_IX86 - _tprintf(_T("Fault address: %08X %02X:%08X %s\r\n"), - pExceptionRecord->ExceptionAddress, - section, offset, szFaultingModule); + _tprintf(_T("Fault address: %08X %02X:%08X %s\r\n"), + pExceptionRecord->ExceptionAddress, + section, offset, szFaultingModule); #endif #ifdef _M_X64 - _tprintf(_T("Fault address: %016I64X %02X:%016I64X %s\r\n"), - pExceptionRecord->ExceptionAddress, - section, offset, szFaultingModule); + _tprintf(_T("Fault address: %016I64X %02X:%016I64X %s\r\n"), + pExceptionRecord->ExceptionAddress, + section, offset, szFaultingModule); #endif - PCONTEXT pCtx = pExceptionInfo->ContextRecord; + PCONTEXT pCtx = pExceptionInfo->ContextRecord; - // Show the registers - #ifdef _M_IX86 // X86 Only! - _tprintf(_T("\r\nRegisters:\r\n")); + // Show the registers +#ifdef _M_IX86 // X86 Only! + _tprintf(_T("\r\nRegisters:\r\n")); - _tprintf(_T("EAX:%08X\r\nEBX:%08X\r\nECX:%08X\r\nEDX:%08X\r\nESI:%08X\r\nEDI:%08X\r\n") - , pCtx->Eax, pCtx->Ebx, pCtx->Ecx, pCtx->Edx, - pCtx->Esi, pCtx->Edi); + _tprintf(_T("EAX:%08X\r\nEBX:%08X\r\nECX:%08X\r\nEDX:%08X\r\nESI:%08X\r\nEDI:%08X\r\n") + , pCtx->Eax, pCtx->Ebx, pCtx->Ecx, pCtx->Edx, + pCtx->Esi, pCtx->Edi); - _tprintf(_T("CS:EIP:%04X:%08X\r\n"), pCtx->SegCs, pCtx->Eip); - _tprintf(_T("SS:ESP:%04X:%08X EBP:%08X\r\n"), - pCtx->SegSs, pCtx->Esp, pCtx->Ebp); - _tprintf(_T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"), - pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs); - _tprintf(_T("Flags:%08X\r\n"), pCtx->EFlags); - #endif + _tprintf(_T("CS:EIP:%04X:%08X\r\n"), pCtx->SegCs, pCtx->Eip); + _tprintf(_T("SS:ESP:%04X:%08X EBP:%08X\r\n"), + pCtx->SegSs, pCtx->Esp, pCtx->Ebp); + _tprintf(_T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"), + pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs); + _tprintf(_T("Flags:%08X\r\n"), pCtx->EFlags); +#endif - #ifdef _M_X64 - _tprintf(_T("\r\nRegisters:\r\n")); - _tprintf(_T("RAX:%016I64X\r\nRBX:%016I64X\r\nRCX:%016I64X\r\nRDX:%016I64X\r\nRSI:%016I64X\r\nRDI:%016I64X\r\n") - _T("R8: %016I64X\r\nR9: %016I64X\r\nR10:%016I64X\r\nR11:%016I64X\r\nR12:%016I64X\r\nR13:%016I64X\r\nR14:%016I64X\r\nR15:%016I64X\r\n") - , pCtx->Rax, pCtx->Rbx, pCtx->Rcx, pCtx->Rdx, - pCtx->Rsi, pCtx->Rdi, pCtx->R9, pCtx->R10, pCtx->R11, pCtx->R12, pCtx->R13, pCtx->R14, pCtx->R15); - _tprintf(_T("CS:RIP:%04X:%016I64X\r\n"), pCtx->SegCs, pCtx->Rip); - _tprintf(_T("SS:RSP:%04X:%016X RBP:%08X\r\n"), - pCtx->SegSs, pCtx->Rsp, pCtx->Rbp); - _tprintf(_T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"), - pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs); - _tprintf(_T("Flags:%08X\r\n"), pCtx->EFlags); - #endif +#ifdef _M_X64 + _tprintf(_T("\r\nRegisters:\r\n")); + _tprintf(_T("RAX:%016I64X\r\nRBX:%016I64X\r\nRCX:%016I64X\r\nRDX:%016I64X\r\nRSI:%016I64X\r\nRDI:%016I64X\r\n") + _T("R8: %016I64X\r\nR9: %016I64X\r\nR10:%016I64X\r\nR11:%016I64X\r\nR12:%016I64X\r\nR13:%016I64X\r\nR14:%016I64X\r\nR15:%016I64X\r\n") + , pCtx->Rax, pCtx->Rbx, pCtx->Rcx, pCtx->Rdx, + pCtx->Rsi, pCtx->Rdi, pCtx->R9, pCtx->R10, pCtx->R11, pCtx->R12, pCtx->R13, pCtx->R14, pCtx->R15); + _tprintf(_T("CS:RIP:%04X:%016I64X\r\n"), pCtx->SegCs, pCtx->Rip); + _tprintf(_T("SS:RSP:%04X:%016X RBP:%08X\r\n"), + pCtx->SegSs, pCtx->Rsp, pCtx->Rbp); + _tprintf(_T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"), + pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs); + _tprintf(_T("Flags:%08X\r\n"), pCtx->EFlags); +#endif - SymSetOptions(SYMOPT_DEFERRED_LOADS); + SymSetOptions(SYMOPT_DEFERRED_LOADS); - // Initialize DbgHelp - if (!SymInitialize(GetCurrentProcess(), 0, TRUE)) - { - _tprintf(_T("\n\rCRITICAL ERROR.\n\r Couldn't initialize the symbol handler for process.\n\rError [%s].\n\r\n\r"), - ErrorMessage(GetLastError())); - } + // Initialize DbgHelp + if (!SymInitialize(GetCurrentProcess(), 0, TRUE)) + { + _tprintf(_T("\n\rCRITICAL ERROR.\n\r Couldn't initialize the symbol handler for process.\n\rError [%s].\n\r\n\r"), + ErrorMessage(GetLastError())); + } - CONTEXT trashableContext = *pCtx; + CONTEXT trashableContext = *pCtx; - WriteStackDetails(&trashableContext, false, NULL); - printTracesForAllThreads(false); + WriteStackDetails(&trashableContext, false, NULL); + printTracesForAllThreads(false); -// #ifdef _M_IX86 // X86 Only! + // #ifdef _M_IX86 // X86 Only! - _tprintf(_T("========================\r\n")); - _tprintf(_T("Local Variables And Parameters\r\n")); + _tprintf(_T("========================\r\n")); + _tprintf(_T("Local Variables And Parameters\r\n")); - trashableContext = *pCtx; - WriteStackDetails(&trashableContext, true, NULL); - printTracesForAllThreads(true); + trashableContext = *pCtx; + WriteStackDetails(&trashableContext, true, NULL); + printTracesForAllThreads(true); - /*_tprintf(_T("========================\r\n")); - _tprintf(_T("Global Variables\r\n")); + /*_tprintf(_T("========================\r\n")); + _tprintf(_T("Global Variables\r\n")); - SymEnumSymbols(GetCurrentProcess(), + SymEnumSymbols(GetCurrentProcess(), (UINT_PTR)GetModuleHandle(szFaultingModule), 0, EnumerateSymbolsCallback, 0);*/ - // #endif // X86 Only! + // #endif // X86 Only! - SymCleanup(GetCurrentProcess()); + SymCleanup(GetCurrentProcess()); - _tprintf(_T("\r\n")); + _tprintf(_T("\r\n")); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + _tprintf(_T("Error writing the crash log\r\n")); + } } //====================================================================== @@ -1313,16 +1325,43 @@ DWORD_PTR WheatyExceptionReport::DereferenceUnsafePointer(DWORD_PTR address) //============================================================================ int __cdecl WheatyExceptionReport::_tprintf(const TCHAR * format, ...) { - TCHAR szBuff[WER_LARGE_BUFFER_SIZE]; int retValue; - DWORD cbWritten; va_list argptr; - va_start(argptr, format); + if (stackOverflowException) + { + retValue = heapprintf(format, argptr); + va_end(argptr); + } + else + { + retValue = stackprintf(format, argptr); + va_end(argptr); + } + + return retValue; +} + +int __cdecl WheatyExceptionReport::stackprintf(const TCHAR * format, va_list argptr) +{ + int retValue; + DWORD cbWritten; + + TCHAR szBuff[WER_LARGE_BUFFER_SIZE]; retValue = vsprintf(szBuff, format, argptr); - va_end(argptr); + WriteFile(m_hReportFile, szBuff, retValue * sizeof(TCHAR), &cbWritten, 0); + return retValue; +} + +int __cdecl WheatyExceptionReport::heapprintf(const TCHAR * format, va_list argptr) +{ + int retValue; + DWORD cbWritten; + TCHAR* szBuff = (TCHAR*)malloc(sizeof(TCHAR) * WER_LARGE_BUFFER_SIZE); + retValue = vsprintf(szBuff, format, argptr); WriteFile(m_hReportFile, szBuff, retValue * sizeof(TCHAR), &cbWritten, 0); + free(szBuff); return retValue; } diff --git a/src/server/shared/Debugging/WheatyExceptionReport.h b/src/server/shared/Debugging/WheatyExceptionReport.h index b7731daaa2b..101b6187f2b 100644 --- a/src/server/shared/Debugging/WheatyExceptionReport.h +++ b/src/server/shared/Debugging/WheatyExceptionReport.h @@ -178,6 +178,8 @@ class WheatyExceptionReport static DWORD_PTR DereferenceUnsafePointer(DWORD_PTR address); static int __cdecl _tprintf(const TCHAR * format, ...); + static int __cdecl stackprintf(const TCHAR * format, va_list argptr); + static int __cdecl heapprintf(const TCHAR * format, va_list argptr); static bool StoreSymbol(DWORD type , DWORD_PTR offset); static void ClearSymbols(); @@ -191,6 +193,7 @@ class WheatyExceptionReport static HANDLE m_hProcess; static SymbolPairs symbols; static std::stack<SymbolDetail> symbolDetails; + static bool stackOverflowException; static char* PushSymbolDetail(char* pszCurrBuffer); static char* PopSymbolDetail(char* pszCurrBuffer); diff --git a/src/server/shared/Updater/DBUpdater.cpp b/src/server/shared/Updater/DBUpdater.cpp index e5c571e4517..20ded669cec 100644 --- a/src/server/shared/Updater/DBUpdater.cpp +++ b/src/server/shared/Updater/DBUpdater.cpp @@ -349,8 +349,27 @@ void DBUpdater<T>::ApplyFile(DatabaseWorkerPool<T>& pool, std::string const& hos args.push_back("-h" + host); args.push_back("-u" + user); args.push_back("-p" + password); + + // Check if we want to connect through ip or socket (Unix only) +#ifdef _WIN32 + args.push_back("-P" + port_or_socket); +#else + + if (!std::isdigit(port_or_socket[0])) + { + // We can't check here if host == "." because is named localhost if socket option is enabled + args.push_back("-P0"); + args.push_back("--protocol=SOCKET"); + args.push_back("-S" + port_or_socket); + } + else + // generic case + args.push_back("-P" + port_or_socket); + +#endif + // Set the default charset to utf8 args.push_back("--default-character-set=utf8"); |