Merge commit '44959aeedddb552c50bf9ff06a2685d216844f24' into 4.3.4

Conflicts:
	.travis.yml
	README.md
	sql/updates/world/2015_04_18_00_world.sql
	sql/updates/world/2015_04_18_05_world_335.sql
	sql/updates/world/2015_04_26_03_world_335.sql
	sql/updates/world/2015_05_09_00_world_335.sql
	src/server/game/Conditions/ConditionMgr.h
	src/server/game/Entities/GameObject/GameObject.cpp
	src/server/game/Entities/GameObject/GameObject.h
	src/server/game/Entities/Player/Player.cpp
	src/server/game/Entities/Unit/Unit.cpp
	src/server/game/Spells/SpellInfo.cpp
This commit is contained in:
Carbenium committed 2015-07-22 01:33:48 +02:00
commit 82ea8da720
61 files changed
+1019 -626

No files matched your search

+43 -11
View File
@@ -19,7 +19,9 @@
#include "Chat.h"
#include "Language.h"
#include "LFGMgr.h"
#include "ObjectMgr.h"
#include "Group.h"
#include "GroupMgr.h"
#include "Player.h"
void GetPlayerInfo(ChatHandler* handler, Player* player)
@@ -74,25 +76,55 @@ public:
static bool HandleLfgGroupInfoCommand(ChatHandler* handler, char const* args)
{
Player* target = NULL;
std::string playerName;
if (!handler->extractPlayerTarget((char*)args, &target, NULL, &playerName))
Player* playerTarget;
ObjectGuid guidTarget;
std::string nameTarget;
ObjectGuid parseGUID(HIGHGUID_PLAYER, uint32(atoul(args)));
if (sObjectMgr->GetPlayerNameByGUID(parseGUID, nameTarget))
{
playerTarget = ObjectAccessor::FindPlayer(parseGUID);
guidTarget = parseGUID;
}
else if (!handler->extractPlayerTarget((char*)args, &playerTarget, &guidTarget, &nameTarget))
return false;
Group* grp = target->GetGroup();
if (!grp)
Group* groupTarget = NULL;
if (playerTarget)
groupTarget = playerTarget->GetGroup();
else
{
handler->PSendSysMessage(LANG_LFG_NOT_IN_GROUP, playerName.c_str());
return true;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GROUP_MEMBER);
stmt->setUInt32(0, guidTarget.GetCounter());
PreparedQueryResult resultGroup = CharacterDatabase.Query(stmt);
if (resultGroup)
groupTarget = sGroupMgr->GetGroupByDbStoreId((*resultGroup)[0].GetUInt32());
}
if (!groupTarget)
{
handler->PSendSysMessage(LANG_LFG_NOT_IN_GROUP, nameTarget.c_str());
handler->SetSentErrorMessage(true);
return false;
}
ObjectGuid guid = grp->GetGUID();
ObjectGuid guid = groupTarget->GetGUID();
std::string const& state = lfg::GetStateString(sLFGMgr->GetState(guid));
handler->PSendSysMessage(LANG_LFG_GROUP_INFO, grp->isLFGGroup(),
handler->PSendSysMessage(LANG_LFG_GROUP_INFO, groupTarget->isLFGGroup(),
state.c_str(), sLFGMgr->GetDungeon(guid));
for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
GetPlayerInfo(handler, itr->GetSource());
Group::MemberSlotList const& members = groupTarget->GetMemberSlots();
for (Group::MemberSlotList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
{
Group::MemberSlot const& slot = *itr;
Player* p = ObjectAccessor::FindPlayer((*itr).guid);
if (p)
GetPlayerInfo(handler, p);
else
handler->PSendSysMessage("%s is offline.", slot.name.c_str());
}
return true;
}
+4 -4
View File
@@ -1995,7 +1995,7 @@ public:
PreparedStatement *stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_MUTE_INFO);
stmt->setUInt32(0, accountId);
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (!result)
{
handler->PSendSysMessage(LANG_COMMAND_MUTEHISTORY_EMPTY, accountName);
@@ -2006,16 +2006,16 @@ public:
do
{
Field* fields = result->Fetch();
// we have to manually set the string for mutedate
time_t sqlTime = fields[0].GetUInt32();
tm timeinfo;
char buffer[80];
// set it to string
localtime_r(&sqlTime, &timeinfo);
strftime(buffer, sizeof(buffer),"%Y-%m-%d %I:%M%p", &timeinfo);
handler->PSendSysMessage(LANG_COMMAND_MUTEHISTORY_OUTPUT, buffer, fields[1].GetUInt32(), fields[2].GetCString(), fields[3].GetCString());
} while (result->NextRow());
return true;
@@ -41,14 +41,17 @@ enum Says
enum Spells
{
SPELL_GROUND_TREMOR = 6524,
SPELL_ARCHAEDAS_AWAKEN = 10347,
SPELL_BOSS_OBJECT_VISUAL = 11206,
SPELL_BOSS_AGGRO = 10340,
SPELL_SUB_BOSS_AGGRO = 11568,
SPELL_AWAKEN_VAULT_WALKER = 10258,
SPELL_AWAKEN_EARTHEN_GUARDIAN = 10252,
SPELL_SELF_DESTRUCT = 9874
SPELL_GROUND_TREMOR = 6524,
SPELL_ARCHAEDAS_AWAKEN = 10347,
SPELL_BOSS_OBJECT_VISUAL = 11206,
SPELL_BOSS_AGGRO = 10340,
SPELL_SUB_BOSS_AGGRO = 11568,
SPELL_AWAKEN_VAULT_WALKER = 10258,
SPELL_AWAKEN_EARTHEN_GUARDIAN = 10252,
SPELL_SELF_DESTRUCT = 9874,
SPELL_FREEZE_ANIM = 16245,
SPELL_MINION_FREEZE_ANIM = 10255
};
class boss_archaedas : public CreatureScript
@@ -96,6 +99,7 @@ class boss_archaedas : public CreatureScript
me->setFaction(35);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
me->AddAura(SPELL_FREEZE_ANIM, me);
}
void ActivateMinion(ObjectGuid uiGuid, bool flag)
@@ -109,6 +113,7 @@ class boss_archaedas : public CreatureScript
minion->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
minion->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
minion->setFaction(14);
minion->RemoveAura(SPELL_MINION_FREEZE_ANIM);
}
}
@@ -258,6 +263,7 @@ class npc_archaedas_minions : public CreatureScript
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
me->RemoveAllAuras();
me->AddAura(SPELL_MINION_FREEZE_ANIM, me);
}
void EnterCombat(Unit* /*who*/) override
@@ -297,7 +303,7 @@ class npc_archaedas_minions : public CreatureScript
{
bWakingUp = false;
bAmIAwake = true;
// AttackStart(ObjectAccessor::GetUnit(*me, instance->GetGuidData(0))); // whoWokeArchaedasGUID
AttackStart(ObjectAccessor::GetUnit(*me, instance->GetGuidData(0))); // whoWokeArchaedasGUID
return; // dont want to continue until we finish the AttackStart method
}
@@ -346,6 +352,7 @@ class npc_stonekeepers : public CreatureScript
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
me->RemoveAllAuras();
me->AddAura(SPELL_MINION_FREEZE_ANIM, me);
}
void EnterCombat(Unit* /*who*/) override
@@ -28,10 +28,9 @@ EndScriptData */
enum Ironaya
{
SAY_AGGRO = 0,
SPELL_ARCINGSMASH = 8374,
SPELL_KNOCKAWAY = 10101,
SPELL_WSTOMP = 11876,
SPELL_WSTOMP = 11876
};
class boss_ironaya : public CreatureScript
@@ -66,10 +65,7 @@ class boss_ironaya : public CreatureScript
Initialize();
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
}
void EnterCombat(Unit* /*who*/) override { }
void UpdateAI(uint32 uiDiff) override
{
@@ -18,12 +18,13 @@
/* ScriptData
SDName: instance_uldaman
SD%Complete: 99
SD%Complete: 80%
SDComment: Need some cosmetics updates when archeadas door are closing (Guardians Waypoints).
SDCategory: Uldaman
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "InstanceScript.h"
#include "uldaman.h"
@@ -31,6 +32,8 @@ enum Spells
{
SPELL_ARCHAEDAS_AWAKEN = 10347,
SPELL_AWAKEN_VAULT_WALKER = 10258,
SPELL_FREEZE_ANIM = 16245,
SPELL_MINION_FREEZE_ANIM = 10255
};
enum Events
@@ -38,6 +41,13 @@ enum Events
EVENT_SUB_BOSS_AGGRO = 2228
};
enum IronayaTalk
{
SAY_AGGRO = 0
};
const Position IronayaPoint = { -231.228f, 246.6135f, -49.01617f, 0.0f };
class instance_uldaman : public InstanceMapScript
{
public:
@@ -136,9 +146,9 @@ class instance_uldaman : public InstanceMapScript
{
creature->setFaction(35);
creature->RemoveAllAuras();
//creature->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_ANIMATION_FROZEN);
creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
creature->AddAura(SPELL_MINION_FREEZE_ANIM, creature);
}
void SetDoor(ObjectGuid guid, bool open)
@@ -171,6 +181,8 @@ class instance_uldaman : public InstanceMapScript
target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
target->setFaction(14);
target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
target->RemoveAura(SPELL_MINION_FREEZE_ANIM);
return; // only want the first one we find
}
// if we get this far than all four are dead so open the door
@@ -190,11 +202,13 @@ class instance_uldaman : public InstanceMapScript
Creature* target = instance->GetCreature(*i);
if (!target || !target->IsAlive() || target->getFaction() == 14)
continue;
archaedas->CastSpell(target, SPELL_AWAKEN_VAULT_WALKER, true);
target->CastSpell(target, SPELL_ARCHAEDAS_AWAKEN, true);
target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
target->setFaction(14);
target->RemoveAura(SPELL_MINION_FREEZE_ANIM);
archaedas->CastSpell(target, SPELL_AWAKEN_VAULT_WALKER, true);
target->CastSpell(target, SPELL_ARCHAEDAS_AWAKEN, true);
return; // only want the first one we find
}
}
@@ -241,6 +255,7 @@ class instance_uldaman : public InstanceMapScript
if (ObjectAccessor::GetUnit(*archaedas, target))
{
archaedas->RemoveAura(SPELL_FREEZE_ANIM);
archaedas->CastSpell(archaedas, SPELL_ARCHAEDAS_AWAKEN, false);
whoWokeuiArchaedasGUID = target;
}
@@ -255,6 +270,12 @@ class instance_uldaman : public InstanceMapScript
ironaya->setFaction(415);
ironaya->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
ironaya->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
ironaya->GetMotionMaster()->Clear();
ironaya->GetMotionMaster()->MovePoint(0, IronayaPoint);
ironaya->SetHomePosition(IronayaPoint);
ironaya->AI()->Talk(SAY_AGGRO);
}
void RespawnMinions()
@@ -694,7 +694,7 @@ class boss_gazakroth : public CreatureScript
public:
boss_gazakroth() : CreatureScript("boss_gazakroth") { }
struct boss_gazakrothAI : public boss_hexlord_addAI
{
boss_gazakrothAI(Creature* creature) : boss_hexlord_addAI(creature)
@@ -706,7 +706,7 @@ class boss_gazakroth : public CreatureScript
{
firebolt_timer = 2 * IN_MILLISECONDS;
}
void Reset() override
{
Initialize();
@@ -50,7 +50,7 @@ enum Sylvanas
SAY_SUNSORROW_WHISPER = 0,
SOUND_CREDIT = 10896,
NPC_HIGHBORNE_LAMENTER = 21628,
NPC_HIGHBORNE_BUNNY = 21641,
NPC_AMBASSADOR_SUNSORROW = 16287,
@@ -32,8 +32,7 @@ enum Spells
SPELL_CURSE_OF_EXERTION = 52772,
SPELL_TIME_WARP = 52766, //Time slows down, reducing attack, casting and movement speed by 70% for 6 sec.
SPELL_TIME_STOP = 58848, //Stops time in a 50 yard sphere for 2 sec.
SPELL_WOUNDING_STRIKE = 52771, //Used only on the tank
H_SPELL_WOUNDING_STRIKE = 58830
SPELL_WOUNDING_STRIKE = 52771 //Used only on the tank
};
enum Yells
@@ -45,109 +44,78 @@ enum Yells
SAY_DEATH = 4
};
enum Events
{
EVENT_CURSE_OF_EXERTION = 1,
EVENT_TIME_WARP,
EVENT_TIME_STOP,
EVENT_WOUNDING_STRIKE
};
class boss_epoch : public CreatureScript
{
public:
boss_epoch() : CreatureScript("boss_epoch") { }
public:
boss_epoch() : CreatureScript("boss_epoch") { }
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<boss_epochAI>(creature);
}
struct boss_epochAI : public ScriptedAI
{
boss_epochAI(Creature* creature) : ScriptedAI(creature)
struct boss_epochAI : public BossAI
{
Initialize();
instance = creature->GetInstanceScript();
}
boss_epochAI(Creature* creature) : BossAI(creature, DATA_EPOCH) { }
void Initialize()
{
uiStep = 1;
uiStepTimer = 26000;
uiCurseOfExertionTimer = 9300;
uiTimeWarpTimer = 25300;
uiTimeStopTimer = 21300;
uiWoundingStrikeTimer = 5300;
}
uint8 uiStep;
uint32 uiStepTimer;
uint32 uiWoundingStrikeTimer;
uint32 uiTimeWarpTimer;
uint32 uiTimeStopTimer;
uint32 uiCurseOfExertionTimer;
InstanceScript* instance;
void Reset() override
{
Initialize();
instance->SetBossState(DATA_EPOCH, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
instance->SetBossState(DATA_EPOCH, IN_PROGRESS);
}
void UpdateAI(uint32 diff) override
{
//Return since we have no target
if (!UpdateVictim())
return;
if (uiCurseOfExertionTimer < diff)
void EnterCombat(Unit* /*who*/) override
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(target, SPELL_CURSE_OF_EXERTION);
uiCurseOfExertionTimer = 9300;
} else uiCurseOfExertionTimer -= diff;
Talk(SAY_AGGRO);
_EnterCombat();
if (uiWoundingStrikeTimer < diff)
events.ScheduleEvent(EVENT_CURSE_OF_EXERTION, 9300);
events.ScheduleEvent(EVENT_TIME_WARP, 25300);
events.ScheduleEvent(EVENT_TIME_STOP, 21300);
events.ScheduleEvent(EVENT_WOUNDING_STRIKE, 5300);
}
void ExecuteEvent(uint32 eventId) override
{
DoCastVictim(SPELL_WOUNDING_STRIKE);
uiWoundingStrikeTimer = 5300;
} else uiWoundingStrikeTimer -= diff;
switch (eventId)
{
case EVENT_CURSE_OF_EXERTION:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
DoCast(target, SPELL_CURSE_OF_EXERTION);
events.ScheduleEvent(EVENT_CURSE_OF_EXERTION, 9300);
break;
case EVENT_TIME_WARP:
Talk(SAY_TIME_WARP);
DoCastAOE(SPELL_TIME_WARP);
events.ScheduleEvent(EVENT_TIME_WARP, 25300);
break;
case EVENT_TIME_STOP:
DoCastAOE(SPELL_TIME_STOP);
events.ScheduleEvent(EVENT_TIME_STOP, 21300);
break;
case EVENT_WOUNDING_STRIKE:
DoCastVictim(SPELL_WOUNDING_STRIKE);
events.ScheduleEvent(EVENT_WOUNDING_STRIKE, 5300);
break;
default:
break;
}
}
if (uiTimeStopTimer < diff)
void JustDied(Unit* /*killer*/) override
{
DoCastAOE(SPELL_TIME_STOP);
uiTimeStopTimer = 21300;
} else uiTimeStopTimer -= diff;
Talk(SAY_DEATH);
_JustDied();
}
if (uiTimeWarpTimer < diff)
void KilledUnit(Unit* victim) override
{
Talk(SAY_TIME_WARP);
DoCastAOE(SPELL_TIME_WARP);
uiTimeWarpTimer = 25300;
} else uiTimeWarpTimer -= diff;
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
};
DoMeleeAttackIfReady();
}
void JustDied(Unit* /*killer*/) override
CreatureAI* GetAI(Creature* creature) const override
{
Talk(SAY_DEATH);
instance->SetBossState(DATA_EPOCH, DONE);
return GetInstanceAI<boss_epochAI>(creature);
}
void KilledUnit(Unit* victim) override
{
if (victim->GetTypeId() != TYPEID_PLAYER)
return;
Talk(SAY_SLAY);
}
};
};
void AddSC_boss_epoch()
@@ -85,12 +85,20 @@ public:
DoCast(me, SPELL_KODO_KOMBO_DESPAWN_BUFF, true);
me->UpdateEntry(NPC_TAMED_KODO);
me->CombatStop();
me->DeleteThreatList();
me->SetSpeed(MOVE_RUN, 0.6f, true);
me->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, me->GetFollowAngle());
me->setActive(true);
}
}
else if (spell->Id == SPELL_KODO_KOMBO_GOSSIP)
{
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
me->GetMotionMaster()->Clear();
me->GetMotionMaster()->MoveIdle();
me->setActive(false);
me->DespawnOrUnsummon(60000);
}
}
@@ -2412,14 +2412,14 @@ enum QuelDelarMisc
Position const QuelDelarCenterPos = { 5309.259f, 2006.390f, 718.046f, 0.0f };
Position const QuelDelarSummonPos = { 5298.473f, 1994.852f, 709.424f, 3.979351f };
Position const QuelDelarMovement[] =
{
{
{ 5292.870f, 1998.950f, 718.046f, 0.0f },
{ 5295.819f, 1991.912f, 707.707f, 0.0f },
{ 5295.301f, 1989.782f, 708.696f, 0.0f }
};
Position const UtherQuelDelarMovement[] =
{
{
{ 5336.830f, 1981.700f, 709.319f, 0.0f },
{ 5314.350f, 1993.440f, 707.726f, 0.0f }
};
@@ -128,7 +128,6 @@ enum Spells
SPELL_ARCANE_BARRAGE_DAMAGE = 63934, // the actual damage - cast by affected player by script spell
// Transition /II-III/
SPELL_SUMMOM_RED_DRAGON_BUDYY = 56070,
SPELL_RIDE_RED_DRAGON_BUDDY = 56071,
SPELL_SUMMON_RED_DRAGON_BUDDY_F_CAST = 58846, // After implicitly hit player targets they will force cast 56070 on self
SPELL_DESTROY_PLATFORM_CHANNEL = 58842,
@@ -80,7 +80,8 @@ enum InstanceSpells
SPELL_VORTEX_5 = 56263, // damage | used to enter to the vehicle
SPELL_PORTAL_OPENED = 61236,
SPELL_RIDE_RED_DRAGON_TRIGGERED = 56072,
SPELL_IRIS_OPENED = 61012 // visual when starting encounter
SPELL_IRIS_OPENED = 61012, // visual when starting encounter
SPELL_SUMMOM_RED_DRAGON_BUDDY = 56070
};
#endif
@@ -39,6 +39,12 @@ public:
SetBossNumber(MAX_ENCOUNTER);
}
void OnPlayerEnter(Player* player) override
{
if (GetBossState(DATA_MALYGOS_EVENT) == DONE)
player->CastSpell(player, SPELL_SUMMOM_RED_DRAGON_BUDDY, true);
}
bool SetBossState(uint32 type, EncounterState state) override
{
if (!InstanceScript::SetBossState(type, state))
@@ -197,7 +197,7 @@ public:
++_healthAmountModifier;
}
}
private:
uint32 _healthAmountModifier;
bool _isIntroDone;
@@ -89,7 +89,7 @@ class boss_volkhan : public CreatureScript
{
public:
boss_volkhan() : CreatureScript("boss_volkhan") { }
struct boss_volkhanAI : public BossAI
{
boss_volkhanAI(Creature* creature) : BossAI(creature, DATA_VOLKHAN)
@@ -104,7 +104,7 @@ public:
m_bCanShatterGolem = false;
m_uiDelay_Timer = 1000;
m_uiSummonPhase = 0;
GolemsShattered = 0;
GolemsShattered = 0;
m_uiHealthAmountModifier = 1;
}
@@ -330,7 +330,7 @@ public:
DespawnDwarf();
instance->SetBossState(DATA_BRANN_EVENT, NOT_STARTED);
instance->SetBossState(DATA_TRIBUNAL_OF_AGES, NOT_STARTED);
}
}
@@ -362,8 +362,10 @@ public:
break;
case 13:
Talk(SAY_EVENT_INTRO_1);
instance->SetBossState(DATA_TRIBUNAL_OF_AGES, IN_PROGRESS);
SetEscortPaused(true);
JumpToNextStep(20000);
// @todo: There should be a pause here and a gossip should start the next step.
break;
case 17:
Talk(SAY_EVENT_INTRO_2);
@@ -421,9 +423,9 @@ public:
Start();
}
void DamageTaken(Unit* /*done_by*/, uint32 & /*damage*/) override
void DamageTaken(Unit* /*done_by*/, uint32& /*damage*/) override
{
if (brannSparklinNews)
if (instance->GetBossState(DATA_TRIBUNAL_OF_AGES) == IN_PROGRESS)
brannSparklinNews = false;
}
@@ -442,9 +444,8 @@ public:
switch (uiStep)
{
case 1:
if (instance->GetBossState(DATA_BRANN_EVENT) != NOT_STARTED)
if (instance->GetBossState(DATA_TRIBUNAL_OF_AGES) != NOT_STARTED)
return;
instance->SetBossState(DATA_BRANN_EVENT, IN_PROGRESS);
bIsBattle = false;
Talk(SAY_ESCORT_START);
SetRun(true);
@@ -582,7 +583,7 @@ public:
break;
case 29:
Talk(SAY_EVENT_END_02);
instance->SetBossState(DATA_BRANN_EVENT, DONE);
instance->SetBossState(DATA_TRIBUNAL_OF_AGES, DONE);
me->CastSpell(me, SPELL_REWARD_ACHIEVEMENT, true);
JumpToNextStep(5500);
break;
@@ -715,9 +716,7 @@ public:
class achievement_brann_spankin_new : public AchievementCriteriaScript
{
public:
achievement_brann_spankin_new() : AchievementCriteriaScript("achievement_brann_spankin_new")
{
}
achievement_brann_spankin_new() : AchievementCriteriaScript("achievement_brann_spankin_new") { }
bool OnCheck(Player* /*player*/, Unit* target) override
{
@@ -28,7 +28,7 @@ enum DataTypes
// Encounter States/Boss GUIDs
DATA_KRYSTALLUS = 0,
DATA_MAIDEN_OF_GRIEF = 1,
DATA_BRANN_EVENT = 2,
DATA_TRIBUNAL_OF_AGES = 2,
DATA_SJONNIR = 3,
// Additional data
@@ -23,8 +23,8 @@
DoorData const doorData[] =
{
{ GO_SJONNIR_DOOR, DATA_BRANN_EVENT, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{ 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
{ GO_SJONNIR_DOOR, DATA_TRIBUNAL_OF_AGES, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{ 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
};
class instance_halls_of_stone : public InstanceMapScript
@@ -90,7 +90,7 @@ class instance_halls_of_stone : public InstanceMapScript
case GO_TRIBUNAL_CHEST:
case GO_TRIBUNAL_CHEST_HERO:
TribunalChestGUID = go->GetGUID();
if (GetBossState(DATA_BRANN_EVENT) == DONE)
if (GetBossState(DATA_TRIBUNAL_OF_AGES) == DONE)
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
break;
case GO_TRIBUNAL_SKY_FLOOR:
@@ -156,7 +156,7 @@ class instance_halls_of_stone : public InstanceMapScript
switch (type)
{
case DATA_BRANN_EVENT:
case DATA_TRIBUNAL_OF_AGES:
if (state == DONE)
{
if (GameObject* go = instance->GetGameObject(TribunalChestGUID))
@@ -178,7 +178,7 @@ class instance_halls_of_stone : public InstanceMapScript
switch (bossId)
{
case DATA_SJONNIR:
if (GetBossState(DATA_BRANN_EVENT) != DONE)
if (GetBossState(DATA_TRIBUNAL_OF_AGES) != DONE)
return false;
break;
default:
@@ -794,9 +794,11 @@ public:
trigger->CastSpell(trigger, spellInfoLightning, true, 0, 0, trigger->GetGUID());
// Kill all mobs registered with SetGuidData(ADD_TRASH_MOB)
for (GuidSet::const_iterator itr = trashMobs.begin(); itr != trashMobs.end(); ++itr)
for (GuidSet::const_iterator itr = trashMobs.begin(); itr != trashMobs.end();)
{
Creature* creature = instance->GetCreature(*itr);
// Increment the iterator before killing the creature because the kill will remove itr from trashMobs
++itr;
if (creature && creature->IsAlive())
trigger->Kill(creature);
}
@@ -1706,7 +1706,7 @@ public:
break;
}
creature->SetStandState(UNIT_STAND_STATE_STAND);
creature->AI()->Talk(SAY_1);
creature->AI()->Talk(SAY_1, player);
ENSURE_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID());
}
return true;
@@ -826,11 +826,11 @@ class spell_infected_worgen_bite : public SpellScriptLoader
{
public:
spell_infected_worgen_bite() : SpellScriptLoader("spell_infected_worgen_bite") { }
class spell_infected_worgen_bite_AuraScript : public AuraScript
{
PrepareAuraScript(spell_infected_worgen_bite_AuraScript);
void HandleAfterEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
@@ -841,7 +841,7 @@ class spell_infected_worgen_bite : public SpellScriptLoader
target->CastSpell(target, SPELL_WORGENS_CALL, true);
}
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_infected_worgen_bite_AuraScript::HandleAfterEffectApply, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAPPLY);
@@ -275,8 +275,8 @@ class instance_serpent_shrine : public InstanceMapScript
if (data == DONE)
{
HandleGameObject(BridgePart[0], true);
HandleGameObject(BridgePart[0], true);
HandleGameObject(BridgePart[0], true);
HandleGameObject(BridgePart[1], true);
HandleGameObject(BridgePart[2], true);
}
break;
case DATA_TRASH:
@@ -43,7 +43,7 @@ class go_main_chambers_access_panel : public GameObjectScript
}
};
ObjectData const gameObjectData[] =
ObjectData const gameObjectData[] =
{
{ GO_ACCESS_PANEL_HYDRO, DATA_ACCESS_PANEL_HYDRO },
{ GO_ACCESS_PANEL_MEK, DATA_ACCESS_PANEL_MEK },
@@ -108,6 +108,7 @@ class boss_grand_warlock_nethekurse : public CreatureScript
void Reset() override
{
_Reset();
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
Initialize();
@@ -115,9 +116,8 @@ class boss_grand_warlock_nethekurse : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DIE);
instance->SetBossState(DATA_NETHEKURSE, DONE);
}
void SetData(uint32 data, uint32 value) override
@@ -160,6 +160,7 @@ class boss_warbringer_omrogg : public CreatureScript
void Reset() override
{
_Reset();
if (Unit* LeftHead = ObjectAccessor::GetUnit(*me, LeftHeadGUID))
{
LeftHead->setDeathState(JUST_DIED);
@@ -257,14 +258,14 @@ class boss_warbringer_omrogg : public CreatureScript
Creature* LeftHead = ObjectAccessor::GetCreature(*me, LeftHeadGUID);
Creature* RightHead = ObjectAccessor::GetCreature(*me, RightHeadGUID);
_JustDied();
if (!LeftHead || !RightHead)
return;
LeftHead->AI()->Talk(YELL_DIE_L);
RightHead->AI()->SetData(SETDATA_DATA, SETDATA_YELL);
instance->SetBossState(DATA_OMROGG, DONE);
}
void UpdateAI(uint32 diff) override
@@ -35,7 +35,10 @@ enum Says
{
SAY_AGGRO = 0,
SAY_SLAY = 1,
SAY_DEATH = 2
SAY_DEATH = 2,
SAY_CALL_EXECUTIONER_A = 3,
SAY_CALL_EXECUTIONER_H = 4
};
enum Spells
@@ -84,10 +87,28 @@ class boss_warchief_kargath_bladefist : public CreatureScript
resetcheck_timer = 5000;
}
void SetData(uint32 type, uint32 data) override
{
if (type == 1)
{
switch (data)
{
case ALLIANCE:
Talk(SAY_CALL_EXECUTIONER_A);
break;
case HORDE:
Talk(SAY_CALL_EXECUTIONER_H);
break;
default:
break;
}
}
}
void Reset() override
{
removeAdds();
_Reset();
me->SetSpeed(MOVE_RUN, 2);
me->SetWalk(false);
@@ -96,10 +117,9 @@ class boss_warchief_kargath_bladefist : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEATH);
removeAdds();
instance->SetBossState(DATA_KARGATH, DONE);
}
void EnterCombat(Unit* /*who*/) override
@@ -24,9 +24,30 @@ SDCategory: Hellfire Citadel, Shattered Halls
EndScriptData */
#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"
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}
};
class instance_shattered_halls : public InstanceMapScript
{
public:
@@ -43,6 +64,43 @@ class instance_shattered_halls : public InstanceMapScript
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
LoadDoorData(doorData);
executionTimer = 0;
executed = 0;
_team = 0;
}
void OnPlayerEnter(Player* player) override
{
Aura* ex = nullptr;
if (!_team)
_team = player->GetTeam();
player->RemoveAurasDueToSpell(SPELL_EXECUTE_1);
player->RemoveAurasDueToSpell(SPELL_EXECUTE_2);
player->RemoveAurasDueToSpell(SPELL_EXECUTE_3);
if (!executionTimer || executionerGUID.IsEmpty())
return;
switch (executed)
{
case 0:
ex = player->AddAura(SPELL_EXECUTE_1, player);
break;
case 1:
ex = player->AddAura(SPELL_EXECUTE_2, player);
break;
case 2:
ex = player->AddAura(SPELL_EXECUTE_3, player);
break;
default:
break;
}
if (ex)
ex->SetDuration(executionTimer);
}
void OnGameObjectCreate(GameObject* go) override
@@ -50,21 +108,53 @@ class instance_shattered_halls : public InstanceMapScript
switch (go->GetEntry())
{
case GO_GRAND_WARLOCK_CHAMBER_DOOR_1:
nethekurseDoor1GUID = go->GetGUID();
break;
case GO_GRAND_WARLOCK_CHAMBER_DOOR_2:
nethekurseDoor2GUID = go->GetGUID();
AddDoor(go, true);
default:
break;
}
}
void OnGameObjectRemove(GameObject* go) override
{
switch (go->GetEntry())
{
case GO_GRAND_WARLOCK_CHAMBER_DOOR_1:
case GO_GRAND_WARLOCK_CHAMBER_DOOR_2:
AddDoor(go, false);
default:
break;
}
}
void OnCreatureCreate(Creature* creature) override
{
if (!_team)
{
Map::PlayerList const &players = instance->GetPlayers();
if (!players.isEmpty())
if (Player* player = players.begin()->GetSource())
_team = player->GetTeam();
}
switch (creature->GetEntry())
{
case NPC_GRAND_WARLOCK_NETHEKURSE:
nethekurseGUID = creature->GetGUID();
break;
case NPC_KARGATH_BLADEFIST:
kargathGUID = creature->GetGUID();
break;
case NPC_RANDY_WHIZZLESPROCKET:
if (_team == HORDE)
creature->UpdateEntry(NPC_DRISELLA);
break;
case NPC_SHATTERED_EXECUTIONER:
executionTimer = 55 * MINUTE * IN_MILLISECONDS;
DoCastSpellOnPlayers(SPELL_EXECUTE_1);
executionerGUID = creature->GetGUID();
SaveToDB();
break;
}
}
@@ -75,18 +165,20 @@ class instance_shattered_halls : public InstanceMapScript
switch (type)
{
case DATA_NETHEKURSE:
if (state == IN_PROGRESS)
case DATA_SHATTERED_EXECUTIONER:
if (state == DONE)
{
HandleGameObject(nethekurseDoor1GUID, false);
HandleGameObject(nethekurseDoor2GUID, false);
}
else
{
HandleGameObject(nethekurseDoor1GUID, true);
HandleGameObject(nethekurseDoor2GUID, true);
DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_1);
DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_2);
DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_3);
executionTimer = 0;
SaveToDB();
}
break;
case DATA_KARGATH:
if (Creature* executioner = instance->GetCreature(executionerGUID))
executioner->AI()->Reset();
break;
case DATA_OMROGG:
break;
}
@@ -100,24 +192,305 @@ class instance_shattered_halls : public InstanceMapScript
case NPC_GRAND_WARLOCK_NETHEKURSE:
return nethekurseGUID;
break;
case GO_GRAND_WARLOCK_CHAMBER_DOOR_1:
return nethekurseDoor1GUID;
case NPC_KARGATH_BLADEFIST:
return kargathGUID;
break;
case GO_GRAND_WARLOCK_CHAMBER_DOOR_2:
return nethekurseDoor2GUID;
case NPC_SHATTERED_EXECUTIONER:
return executionerGUID;
break;
default:
return ObjectGuid::Empty;
break;
}
return ObjectGuid::Empty;
}
void WriteSaveDataMore(std::ostringstream& data) override
{
if (!instance->IsHeroic())
return;
data << uint32(executed) << ' '
<< executionTimer << ' ';
}
void ReadSaveDataMore(std::istringstream& data) override
{
if (!instance->IsHeroic())
return;
uint32 readbuff;
data >> readbuff;
executed = uint8(readbuff);
data >> readbuff;
if (executed > VictimCount)
{
executed = VictimCount;
executionTimer = 0;
return;
}
if (!readbuff)
return;
Creature* executioner = nullptr;
instance->LoadGrid(Executioner.GetPositionX(), Executioner.GetPositionY());
if (Creature* kargath = instance->GetCreature(kargathGUID))
if (executionerGUID.IsEmpty())
executioner = kargath->SummonCreature(NPC_SHATTERED_EXECUTIONER, Executioner);
if (executioner)
for (uint8 i = executed; i < VictimCount; ++i)
executioner->SummonCreature(executionerVictims[i](GetData(DATA_TEAM_IN_INSTANCE)), executionerVictims[i].GetPos());
executionTimer = readbuff;
}
uint32 GetData(uint32 type) const override
{
switch (type)
{
case DATA_PRISONERS_EXECUTED:
return executed;
break;
case DATA_TEAM_IN_INSTANCE:
return _team;
break;
default:
return 0;
break;
}
}
void Update(uint32 diff) override
{
if (!executionTimer)
return;
if (executionTimer <= diff)
{
switch (++executed)
{
case 1:
DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_1);
DoCastSpellOnPlayers(SPELL_EXECUTE_2);
executionTimer = 10 * MINUTE * IN_MILLISECONDS;
break;
case 2:
DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_2);
DoCastSpellOnPlayers(SPELL_EXECUTE_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);
SaveToDB();
}
else
executionTimer -= diff;
}
protected:
ObjectGuid nethekurseGUID;
ObjectGuid nethekurseDoor1GUID;
ObjectGuid nethekurseDoor2GUID;
ObjectGuid kargathGUID;
ObjectGuid executionerGUID;
uint8 executed;
uint32 executionTimer;
uint32 _team;
};
};
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();
}
@@ -21,18 +21,41 @@
#define DataHeader "SH"
uint32 const EncounterCount = 3;
uint32 const EncounterCount = 4;
uint32 const VictimCount = 3;
enum DataTypes
{
DATA_NETHEKURSE = 1,
DATA_OMROGG = 2,
DATA_KARGATH = 3
DATA_NETHEKURSE = 0,
DATA_OMROGG = 1,
DATA_KARGATH = 2,
DATA_SHATTERED_EXECUTIONER = 3,
DATA_PRISONERS_EXECUTED = 4,
DATA_TEAM_IN_INSTANCE = 5
};
enum CreatureIds
{
NPC_GRAND_WARLOCK_NETHEKURSE = 16807
NPC_GRAND_WARLOCK_NETHEKURSE = 16807,
NPC_KARGATH_BLADEFIST = 16808,
NPC_SHATTERED_EXECUTIONER = 17301,
// Alliance Ids
NPC_RANDY_WHIZZLESPROCKET = 17288,
NPC_CAPTAIN_ALINA = 17290,
NPC_ALLIANCE_VICTIM_1 = 17289,
NPC_ALLIANCE_VICTIM_2 = 17292,
// Horde Ids
NPC_DRISELLA = 17294,
NPC_CAPTAIN_BONESHATTER = 17296,
NPC_HORDE_VICTIM_1 = 17295,
NPC_HORDE_VICTIM_2 = 17297
};
enum GameobjectIds
@@ -41,4 +64,33 @@ enum GameobjectIds
GO_GRAND_WARLOCK_CHAMBER_DOOR_2 = 182540
};
enum QuestIds
{
QUEST_IMPRISONED_A = 9524,
QUEST_IMPRISONED_H = 9525
};
const Position Executioner = { 152.8524f, -83.63912f, 2.021005f, 0.06981317f };
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; }
private:
const uint32 _allianceNPC;
const uint32 _hordeNPC;
const Position _spawnPos;
};
const FactionSpawnerHelper executionerVictims[VictimCount] =
{
{ NPC_CAPTAIN_ALINA, NPC_CAPTAIN_BONESHATTER, { 138.8807f, -84.22707f, 1.992269f, 0.06981317f } },
{ NPC_ALLIANCE_VICTIM_1, NPC_HORDE_VICTIM_1, { 151.2411f, -91.02930f, 2.019741f, 1.57079600f } },
{ NPC_ALLIANCE_VICTIM_2, NPC_HORDE_VICTIM_2, { 151.0459f, -77.51981f, 2.021008f, 4.74729500f } }
};
#endif
@@ -283,7 +283,7 @@ class boss_harbinger_skyriss_illusion : public CreatureScript
{
boss_harbinger_skyriss_illusionAI(Creature* creature) : ScriptedAI(creature) { }
void Reset() override
void Reset() override
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
}
@@ -24,8 +24,6 @@ SDCategory: Blade's Edge Mountains
EndScriptData */
/* ContentData
npc_bloodmaul_brutebane
npc_bloodmaul_brute
npc_nether_drake
npc_daranelle
go_legion_obelisk
@@ -43,171 +41,6 @@ EndContentData */
#include "SpellAuras.h"
#include "SpellAuraEffects.h"
/*######
## npc_bloodmaul_brutebane
######*/
enum Bloodmaul
{
NPC_OGRE_BRUTE = 19995,
NPC_QUEST_CREDIT = 21241,
GO_KEG = 184315,
QUEST_GETTING_THE_BLADESPIRE_TANKED = 10512,
QUEST_BLADESPIRE_KEGGER = 10545
};
class npc_bloodmaul_brutebane : public CreatureScript
{
public:
npc_bloodmaul_brutebane() : CreatureScript("npc_bloodmaul_brutebane") { }
struct npc_bloodmaul_brutebaneAI : public ScriptedAI
{
npc_bloodmaul_brutebaneAI(Creature* creature) : ScriptedAI(creature)
{
if (Creature* Ogre = me->FindNearestCreature(NPC_OGRE_BRUTE, 50, true))
{
Ogre->SetReactState(REACT_DEFENSIVE);
Ogre->GetMotionMaster()->MovePoint(1, me->GetPositionX()-1, me->GetPositionY()+1, me->GetPositionZ());
}
}
void UpdateAI(uint32 /*diff*/) override { }
};
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_bloodmaul_brutebaneAI(creature);
}
};
/*######
## npc_bloodmaul_brute
######*/
enum BloodmaulBrute
{
EVENT_CLEAVE = 1,
EVENT_DEBILITATING_STRIKE = 2,
SAY_AGGRO = 0,
SAY_DEATH = 1,
SAY_ENRAGE = 2,
SPELL_CLEAVE = 15496,
SPELL_DEBILITATING_STRIKE = 37577,
SPELL_ENRAGE = 8599,
QUEST_INTO_THE_SOULGRINDER = 11000
};
class npc_bloodmaul_brute : public CreatureScript
{
public:
npc_bloodmaul_brute() : CreatureScript("npc_bloodmaul_brute") { }
struct npc_bloodmaul_bruteAI : public ScriptedAI
{
npc_bloodmaul_bruteAI(Creature* creature) : ScriptedAI(creature)
{
hp30 = false;
}
void Reset() override
{
PlayerGUID.Clear();
hp30 = false;
}
void EnterCombat(Unit* /*who*/) override
{
if (urand (0, 100) < 35)
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_CLEAVE, urand(9000,12000));
events.ScheduleEvent(EVENT_DEBILITATING_STRIKE, 15000);
}
void JustDied(Unit* killer) override
{
if (killer->GetTypeId() == TYPEID_PLAYER)
if (killer->ToPlayer()->GetQuestRewardStatus(QUEST_INTO_THE_SOULGRINDER))
Talk(SAY_DEATH);
}
void MoveInLineOfSight(Unit* who) override
{
if (!who || (!who->IsAlive()))
return;
if (me->IsWithinDistInMap(who, 50.0f))
{
if (who->GetTypeId() == TYPEID_PLAYER)
if (who->ToPlayer()->GetQuestStatus(QUEST_GETTING_THE_BLADESPIRE_TANKED) == QUEST_STATUS_INCOMPLETE
|| who->ToPlayer()->GetQuestStatus(QUEST_BLADESPIRE_KEGGER) == QUEST_STATUS_INCOMPLETE)
PlayerGUID = who->GetGUID();
}
}
void MovementInform(uint32 /*type*/, uint32 id) override
{
if (id == 1)
{
if (GameObject* Keg = me->FindNearestGameObject(GO_KEG, 20))
Keg->Delete();
me->HandleEmoteCommand(7);
me->SetReactState(REACT_AGGRESSIVE);
me->GetMotionMaster()->MoveTargetedHome();
Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID);
Creature* Credit = me->FindNearestCreature(NPC_QUEST_CREDIT, 50, true);
if (player && Credit)
player->KilledMonster(Credit->GetCreatureTemplate(), Credit->GetGUID());
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_CLEAVE:
DoCast(me, SPELL_CLEAVE);
events.ScheduleEvent(EVENT_CLEAVE, urand(9000,12000));
break;
case EVENT_DEBILITATING_STRIKE:
DoCastVictim(SPELL_DEBILITATING_STRIKE);
events.ScheduleEvent(EVENT_DEBILITATING_STRIKE, urand(18000,22000));
break;
}
}
if (!hp30 && HealthBelowPct(30))
{
hp30 = true;
Talk(SAY_ENRAGE);
DoCast(me, SPELL_ENRAGE);
}
DoMeleeAttackIfReady();
}
private:
EventMap events;
ObjectGuid PlayerGUID;
bool hp30;
};
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_bloodmaul_bruteAI(creature);
}
};
/*######
## npc_nether_drake
######*/
@@ -1193,8 +1026,6 @@ class spell_oscillating_field : public SpellScriptLoader
void AddSC_blades_edge_mountains()
{
new npc_bloodmaul_brutebane();
new npc_bloodmaul_brute();
new npc_nether_drake();
new npc_daranelle();
new go_legion_obelisk();