Core/Unit: Standardize SetFacingTo and SetFacingToObject behavior while moving. Both now fail while moving unless arg2 bool is true
This commit is contained in:
1 parent
7c477a023e
commit
8a402b9f6b
21 files changed
+871
-31
No files matched your search
@@ -0,0 +1,3 @@
|
||||
-- uint8 -> uint16 for chain ID
|
||||
ALTER TABLE `script_spline_chain_meta` MODIFY COLUMN `chainId` SMALLINT UNSIGNED NOT NULL;
|
||||
ALTER TABLE `script_spline_chain_waypoints` MODIFY COLUMN `chainId` SMALLINT UNSIGNED NOT NULL;
|
||||
@@ -162,7 +162,7 @@ void CreatureAI::TriggerAlert(Unit const* who) const
|
||||
me->SendAIReaction(AI_REACTION_ALERT);
|
||||
|
||||
// Face the unit (stealthed player) and set distracted state for 5 seconds
|
||||
me->SetFacingTo(me->GetAngle(who->GetPositionX(), who->GetPositionY()));
|
||||
me->SetFacingTo(me->GetAngle(who->GetPositionX(), who->GetPositionY()), true);
|
||||
me->StopMoving();
|
||||
me->GetMotionMaster()->MoveDistract(5 * IN_MILLISECONDS);
|
||||
}
|
||||
|
||||
@@ -2788,10 +2788,10 @@ void Creature::FocusTarget(Spell const* focusSpell, WorldObject const* target)
|
||||
bool canTurnDuringCast = !focusSpell->GetSpellInfo()->HasAttribute(SPELL_ATTR5_DONT_TURN_DURING_CAST);
|
||||
// Face the target - we need to do this before the unit state is modified for no-turn spells
|
||||
if (target)
|
||||
SetFacingTo(GetAngle(target));
|
||||
SetFacingToObject(target);
|
||||
else if (!canTurnDuringCast)
|
||||
if (Unit* victim = GetVictim())
|
||||
SetFacingTo(GetAngle(victim)); // ensure orientation is correct at beginning of cast
|
||||
SetFacingToObject(victim); // ensure orientation is correct at beginning of cast
|
||||
|
||||
if (!canTurnDuringCast)
|
||||
AddUnitState(UNIT_STATE_CANNOT_TURN);
|
||||
@@ -2837,7 +2837,7 @@ void Creature::ReleaseFocus(Spell const* focusSpell, bool withDelay)
|
||||
if (m_suppressedTarget)
|
||||
{
|
||||
if (WorldObject const* objTarget = ObjectAccessor::GetWorldObject(*this, m_suppressedTarget))
|
||||
SetFacingTo(GetAngle(objTarget));
|
||||
SetFacingToObject(objTarget);
|
||||
}
|
||||
else
|
||||
SetFacingTo(m_suppressedOrientation);
|
||||
|
||||
@@ -16511,8 +16511,11 @@ void Unit::SetInFront(WorldObject const* target)
|
||||
SetOrientation(GetAngle(target));
|
||||
}
|
||||
|
||||
void Unit::SetFacingTo(float ori)
|
||||
void Unit::SetFacingTo(float ori, bool force)
|
||||
{
|
||||
if (!force && !IsStopped())
|
||||
return;
|
||||
|
||||
Movement::MoveSplineInit init(this);
|
||||
init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset(), false);
|
||||
if (GetTransport())
|
||||
@@ -16521,10 +16524,10 @@ void Unit::SetFacingTo(float ori)
|
||||
init.Launch();
|
||||
}
|
||||
|
||||
void Unit::SetFacingToObject(WorldObject const* object)
|
||||
void Unit::SetFacingToObject(WorldObject const* object, bool force)
|
||||
{
|
||||
// never face when already moving
|
||||
if (!IsStopped())
|
||||
// do not face when already moving
|
||||
if (!force && !IsStopped())
|
||||
return;
|
||||
|
||||
/// @todo figure out under what conditions creature will move towards object instead of facing it where it currently is.
|
||||
|
||||
@@ -1625,8 +1625,8 @@ class TC_GAME_API Unit : public WorldObject
|
||||
bool SetHover(bool enable, bool packetOnly = false);
|
||||
|
||||
void SetInFront(WorldObject const* target);
|
||||
void SetFacingTo(float ori);
|
||||
void SetFacingToObject(WorldObject const* object);
|
||||
void SetFacingTo(float ori, bool force = false);
|
||||
void SetFacingToObject(WorldObject const* object, bool force = false);
|
||||
|
||||
void SendChangeCurrentVictimOpcode(HostileReference* pHostileReference);
|
||||
void SendClearThreatListOpcode();
|
||||
|
||||
@@ -470,7 +470,7 @@ void MotionMaster::MoveSmoothPath(uint32 pointId, Movement::PointsArray const& p
|
||||
//MovePoint(EVENT_CHARGE_PREPATH, pos, false);
|
||||
}
|
||||
|
||||
void MotionMaster::MoveAlongSplineChain(uint32 pointId, uint32 dbChainId, bool walk)
|
||||
void MotionMaster::MoveAlongSplineChain(uint32 pointId, uint16 dbChainId, bool walk)
|
||||
{
|
||||
Creature* owner = _owner->ToCreature();
|
||||
if (!owner)
|
||||
|
||||
@@ -200,7 +200,7 @@ class TC_GAME_API MotionMaster //: private std::stack<MovementGenerator *>
|
||||
void MoveSmoothPath(uint32 pointId, G3D::Vector3 const* pathPoints, size_t pathSize, bool walk);
|
||||
void MoveSmoothPath(uint32 pointId, Movement::PointsArray const& points, bool walk);
|
||||
// Walk along spline chain stored in DB (script_spline_chain_meta and script_spline_chain_waypoints)
|
||||
void MoveAlongSplineChain(uint32 pointId, uint32 dbChainId, bool walk);
|
||||
void MoveAlongSplineChain(uint32 pointId, uint16 dbChainId, bool walk);
|
||||
void MoveAlongSplineChain(uint32 pointId, SplineChain const& chain, bool walk);
|
||||
void ResumeSplineChain(SplineChainResumeInfo const& info);
|
||||
void MoveFall(uint32 id = 0);
|
||||
|
||||
@@ -106,7 +106,8 @@ void SystemMgr::LoadScriptSplineChains()
|
||||
{
|
||||
Field* fieldsMeta = resultMeta->Fetch();
|
||||
uint32 entry = fieldsMeta[0].GetUInt32();
|
||||
uint8 chainId = fieldsMeta[1].GetUInt8(), splineId = fieldsMeta[2].GetUInt8();
|
||||
uint16 chainId = fieldsMeta[1].GetUInt16();
|
||||
uint8 splineId = fieldsMeta[2].GetUInt8();
|
||||
SplineChain& chain = m_mSplineChainsMap[{entry,chainId}];
|
||||
|
||||
if (splineId != chain.size())
|
||||
@@ -127,7 +128,8 @@ void SystemMgr::LoadScriptSplineChains()
|
||||
{
|
||||
Field* fieldsWP = resultWP->Fetch();
|
||||
uint32 entry = fieldsWP[0].GetUInt32();
|
||||
uint8 chainId = fieldsWP[1].GetUInt8(), splineId = fieldsWP[2].GetUInt8(), wpId = fieldsWP[3].GetUInt8();
|
||||
uint16 chainId = fieldsWP[1].GetUInt16();
|
||||
uint8 splineId = fieldsWP[2].GetUInt8(), wpId = fieldsWP[3].GetUInt8();
|
||||
float posX = fieldsWP[4].GetFloat(), posY = fieldsWP[5].GetFloat(), posZ = fieldsWP[6].GetFloat();
|
||||
auto it = m_mSplineChainsMap.find({entry,chainId});
|
||||
if (it == m_mSplineChainsMap.end())
|
||||
|
||||
@@ -73,9 +73,9 @@ class TC_GAME_API SystemMgr
|
||||
return &itr->second;
|
||||
}
|
||||
|
||||
SplineChain const* GetSplineChain(uint32 entry, uint8 id) const
|
||||
SplineChain const* GetSplineChain(uint32 entry, uint16 chainId) const
|
||||
{
|
||||
auto it = m_mSplineChainsMap.find({ entry, id });
|
||||
auto it = m_mSplineChainsMap.find({ entry, chainId });
|
||||
if (it == m_mSplineChainsMap.end())
|
||||
return nullptr;
|
||||
return &it->second;
|
||||
@@ -85,7 +85,7 @@ class TC_GAME_API SystemMgr
|
||||
|
||||
protected:
|
||||
PointMoveMap m_mPointMoveMap; //coordinates for waypoints
|
||||
typedef std::pair<uint32, uint8> ChainKeyType; // creature entry + chain ID
|
||||
typedef std::pair<uint32, uint16> ChainKeyType; // creature entry + chain ID
|
||||
std::unordered_map<ChainKeyType, SplineChain> m_mSplineChainsMap; // spline chains
|
||||
};
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ public:
|
||||
{
|
||||
case 4:
|
||||
SetEscortPaused(true);
|
||||
me->SetFacingTo(1.775791f);
|
||||
me->SetFacingTo(1.775791f, true);
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
Talk(SAY_MORRIDUNE_2);
|
||||
break;
|
||||
|
||||
@@ -246,7 +246,7 @@ public:
|
||||
me->SetCanFly(true);
|
||||
me->SetDisableGravity(true);
|
||||
me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
|
||||
me->SetFacingTo(me->GetOrientation() + float(M_PI));
|
||||
me->SetFacingTo(me->GetOrientation() + float(M_PI), true);
|
||||
if (Creature * trigger = me->SummonCreature(NPC_TRIGGER, MiddleRoomLocation, TEMPSUMMON_CORPSE_DESPAWN))
|
||||
triggerGUID = trigger->GetGUID();
|
||||
me->GetMotionMaster()->MoveTakeoff(11, Phase2Floating);
|
||||
|
||||
@@ -0,0 +1,830 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Orgrimmar
|
||||
SD%Complete: 100
|
||||
SDComment: Quest support: 2460, 6566
|
||||
SDCategory: Orgrimmar
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_shenthul
|
||||
npc_thrall_warchief
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "Player.h"
|
||||
#include "Cell.h"
|
||||
#include "CellImpl.h"
|
||||
#include "GridNotifiers.h"
|
||||
|
||||
/*######
|
||||
## npc_shenthul
|
||||
######*/
|
||||
|
||||
enum Shenthul
|
||||
{
|
||||
QUEST_SHATTERED_SALUTE = 2460
|
||||
};
|
||||
|
||||
class npc_shenthul : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_shenthul() : CreatureScript("npc_shenthul") { }
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_SHATTERED_SALUTE)
|
||||
{
|
||||
ENSURE_AI(npc_shenthul::npc_shenthulAI, creature->AI())->CanTalk = true;
|
||||
ENSURE_AI(npc_shenthul::npc_shenthulAI, creature->AI())->PlayerGUID = player->GetGUID();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_shenthulAI(creature);
|
||||
}
|
||||
|
||||
struct npc_shenthulAI : public ScriptedAI
|
||||
{
|
||||
npc_shenthulAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
CanTalk = false;
|
||||
CanEmote = false;
|
||||
SaluteTimer = 6000;
|
||||
ResetTimer = 0;
|
||||
PlayerGUID.Clear();
|
||||
}
|
||||
|
||||
bool CanTalk;
|
||||
bool CanEmote;
|
||||
uint32 SaluteTimer;
|
||||
uint32 ResetTimer;
|
||||
ObjectGuid PlayerGUID;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override { }
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (CanEmote)
|
||||
{
|
||||
if (ResetTimer <= diff)
|
||||
{
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID))
|
||||
{
|
||||
if (player->GetTypeId() == TYPEID_PLAYER && player->GetQuestStatus(QUEST_SHATTERED_SALUTE) == QUEST_STATUS_INCOMPLETE)
|
||||
player->FailQuest(QUEST_SHATTERED_SALUTE);
|
||||
}
|
||||
Reset();
|
||||
} else ResetTimer -= diff;
|
||||
}
|
||||
|
||||
if (CanTalk && !CanEmote)
|
||||
{
|
||||
if (SaluteTimer <= diff)
|
||||
{
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
|
||||
CanEmote = true;
|
||||
ResetTimer = 60000;
|
||||
} else SaluteTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void ReceiveEmote(Player* player, uint32 emote) override
|
||||
{
|
||||
if (emote == TEXT_EMOTE_SALUTE && player->GetQuestStatus(QUEST_SHATTERED_SALUTE) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
if (CanEmote)
|
||||
{
|
||||
player->AreaExploredOrEventHappens(QUEST_SHATTERED_SALUTE);
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_thrall_warchief
|
||||
######*/
|
||||
|
||||
enum ThrallWarchief
|
||||
{
|
||||
GOSSIP_MENU_OPTION_ID_ALL = 0,
|
||||
|
||||
OPTION_PLEASE_SHARE_YOUR = 3664,
|
||||
OPTION_WHAT_DISCOVERIES = 3665,
|
||||
OPTION_USURPER = 3666,
|
||||
OPTION_WITH_ALL_DUE_RESPECT = 3667,
|
||||
OPTION_I_I_DID_NOT_THINK_OF = 3668,
|
||||
OPTION_I_LIVE_ONLY_TO_SERVE = 3669,
|
||||
OPTION_OF_COURSE_WARCHIEF = 3670,
|
||||
|
||||
GOSSIP_MEMBERS_OF_THE_HORDE = 4477,
|
||||
GOSSIP_THE_SHATTERED_HAND = 5733,
|
||||
GOSSIP_IT_WOULD_APPEAR_AS = 5734,
|
||||
GOSSIP_THE_BROOD_MOTHER = 5735,
|
||||
GOSSIP_SO_MUCH_TO_LEARN = 5736,
|
||||
GOSSIP_I_DO_NOT_FAULT_YOU = 5737,
|
||||
GOSSIP_NOW_PAY_ATTENTION = 5738,
|
||||
|
||||
QUEST_WHAT_THE_WIND_CARRIES = 6566,
|
||||
|
||||
SPELL_CHAIN_LIGHTNING = 16033,
|
||||
SPELL_SHOCK = 16034
|
||||
};
|
||||
|
||||
/// @todo verify abilities/timers
|
||||
class npc_thrall_warchief : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_thrall_warchief() : CreatureScript("npc_thrall_warchief") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
|
||||
{
|
||||
ClearGossipMenuFor(player);
|
||||
switch (action)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF+1:
|
||||
AddGossipItemFor(player, OPTION_WHAT_DISCOVERIES, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
|
||||
SendGossipMenuFor(player, GOSSIP_THE_SHATTERED_HAND, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+2:
|
||||
AddGossipItemFor(player, OPTION_USURPER, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
|
||||
SendGossipMenuFor(player, GOSSIP_IT_WOULD_APPEAR_AS, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+3:
|
||||
AddGossipItemFor(player, OPTION_WITH_ALL_DUE_RESPECT, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
|
||||
SendGossipMenuFor(player, GOSSIP_THE_BROOD_MOTHER, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+4:
|
||||
AddGossipItemFor(player, OPTION_I_I_DID_NOT_THINK_OF, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5);
|
||||
SendGossipMenuFor(player, GOSSIP_SO_MUCH_TO_LEARN, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+5:
|
||||
AddGossipItemFor(player, OPTION_I_LIVE_ONLY_TO_SERVE, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6);
|
||||
SendGossipMenuFor(player, GOSSIP_I_DO_NOT_FAULT_YOU, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+6:
|
||||
AddGossipItemFor(player, OPTION_OF_COURSE_WARCHIEF, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7);
|
||||
SendGossipMenuFor(player, GOSSIP_NOW_PAY_ATTENTION, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+7:
|
||||
CloseGossipMenuFor(player);
|
||||
player->AreaExploredOrEventHappens(QUEST_WHAT_THE_WIND_CARRIES);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature) override
|
||||
{
|
||||
if (creature->IsQuestGiver())
|
||||
player->PrepareQuestMenu(creature->GetGUID());
|
||||
|
||||
if (player->GetQuestStatus(QUEST_WHAT_THE_WIND_CARRIES) == QUEST_STATUS_INCOMPLETE)
|
||||
AddGossipItemFor(player, OPTION_PLEASE_SHARE_YOUR, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
|
||||
SendGossipMenuFor(player, GOSSIP_MEMBERS_OF_THE_HORDE, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_thrall_warchiefAI(creature);
|
||||
}
|
||||
|
||||
struct npc_thrall_warchiefAI : public ScriptedAI
|
||||
{
|
||||
npc_thrall_warchiefAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
ChainLightningTimer = 2000;
|
||||
ShockTimer = 8000;
|
||||
}
|
||||
|
||||
uint32 ChainLightningTimer;
|
||||
uint32 ShockTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override { }
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (ChainLightningTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_CHAIN_LIGHTNING);
|
||||
ChainLightningTimer = 9000;
|
||||
} else ChainLightningTimer -= diff;
|
||||
|
||||
if (ShockTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SHOCK);
|
||||
ShockTimer = 15000;
|
||||
} else ShockTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/* --------- Herald of War ------------- */
|
||||
enum CitizenEntries
|
||||
{
|
||||
NPC_GRYSHKA = 31433,
|
||||
NPC_OLVIA = 31425,
|
||||
NPC_SANA = 31429,
|
||||
NPC_FELIKA = 31427,
|
||||
NPC_THATHUNG = 31430,
|
||||
NPC_KAJA = 31423
|
||||
};
|
||||
|
||||
enum SceneEvents
|
||||
{
|
||||
EVENT_SCENE_1 = 1,
|
||||
EVENT_SCENE_2 = 2,
|
||||
EVENT_SCENE_3 = 3,
|
||||
EVENT_SCENE_4 = 4,
|
||||
EVENT_SCENE_5 = 5,
|
||||
EVENT_SCENE_6 = 6,
|
||||
EVENT_SCENE_7 = 7,
|
||||
EVENT_SCENE_8 = 8,
|
||||
EVENT_SCENE_9 = 9,
|
||||
EVENT_SCENE_10 = 10,
|
||||
EVENT_SCENE_11 = 11,
|
||||
EVENT_SCENE_12 = 12,
|
||||
EVENT_SCENE_13 = 13,
|
||||
EVENT_RESET = 14
|
||||
};
|
||||
|
||||
enum CitizenTalk
|
||||
{
|
||||
SAY_GRYSHKA_1 = 0, // When can we reopen our shops? I'm losing gold here!
|
||||
SAY_GRYSHKA_2 = 1, // "This is an outrage!"
|
||||
SAY_OLVIA_1 = 0, // Where is the Warchief?
|
||||
SAY_OLVIA_2 = 1, // What are all these Forsaken doing here?
|
||||
SAY_FELIKA_1 = 0, // What is going on?
|
||||
SAY_FELIKA_2 = 1, // This is an outrage!
|
||||
SAY_THATHUNG = 0, // What is going on?
|
||||
SAY_KAJA = 0, // Why is Thrall allowing this to happen to our city?
|
||||
SAY_SANA = 0, // We demand answers!
|
||||
SAY_RUNTHAK_1 = 0, // SILENCE!
|
||||
SAY_RUNTHAK_2 = 1, // We are on the brink of all out war with the Alliance!
|
||||
SAY_RUNTHAK_3 = 2, // Tragic events have unfolded in Northrend. The Warchief is doing all that he can to keep us safe.
|
||||
SAY_RUNTHAK_4 = 3 // All services and shops are to remain closed until further notice! That is all!
|
||||
};
|
||||
|
||||
class npc_overlord_runthak_orgrimmar : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_overlord_runthak_orgrimmar() : CreatureScript("npc_overlord_runthak_orgrimmar") { }
|
||||
|
||||
struct npc_overlord_runthak_orgrimmarAI : public ScriptedAI
|
||||
{
|
||||
npc_overlord_runthak_orgrimmarAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
inProgress = false;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
inProgress = false;
|
||||
me->GetMotionMaster()->MovePath(me->GetSpawnId() * 10, true);
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && who->IsWithinDist(me, 20.0f) && !inProgress)
|
||||
{
|
||||
inProgress = true;
|
||||
events.ScheduleEvent(EVENT_SCENE_1, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventID = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventID)
|
||||
{
|
||||
case EVENT_SCENE_1:
|
||||
GetCitizenGuids();
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
if (Creature* gryshka = ObjectAccessor::GetCreature(*me, gryshkaGUID))
|
||||
{
|
||||
me->SetFacingToObject(gryshka);
|
||||
gryshka->AI()->Talk(SAY_GRYSHKA_1);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_SCENE_2, 4500);
|
||||
break;
|
||||
case EVENT_SCENE_2:
|
||||
if (Creature* olvia = ObjectAccessor::GetCreature(*me, olviaGUID))
|
||||
olvia->AI()->Talk(SAY_OLVIA_1);
|
||||
events.ScheduleEvent(EVENT_SCENE_3, 4500);
|
||||
break;
|
||||
case EVENT_SCENE_3:
|
||||
if (Creature* felika = ObjectAccessor::GetCreature(*me, felikaGUID))
|
||||
felika->AI()->Talk(SAY_FELIKA_1);
|
||||
events.ScheduleEvent(EVENT_SCENE_4, 4500);
|
||||
break;
|
||||
case EVENT_SCENE_4:
|
||||
if (Creature* thathung = ObjectAccessor::GetCreature(*me, thungGUID))
|
||||
thathung->AI()->Talk(SAY_THATHUNG);
|
||||
events.ScheduleEvent(EVENT_SCENE_5, 4500);
|
||||
break;
|
||||
case EVENT_SCENE_5:
|
||||
if (Creature* sana = ObjectAccessor::GetCreature(*me, sanaGUID))
|
||||
sana->AI()->Talk(SAY_SANA);
|
||||
events.ScheduleEvent(EVENT_SCENE_6, 4500);
|
||||
break;
|
||||
case EVENT_SCENE_6:
|
||||
if (Creature* gryshka = ObjectAccessor::GetCreature(*me, gryshkaGUID))
|
||||
gryshka->AI()->Talk(SAY_GRYSHKA_2);
|
||||
events.ScheduleEvent(EVENT_SCENE_7, 4500);
|
||||
break;
|
||||
case EVENT_SCENE_7:
|
||||
if (Creature* kaja = ObjectAccessor::GetCreature(*me, kajaGUID))
|
||||
kaja->AI()->Talk(SAY_KAJA);
|
||||
events.ScheduleEvent(EVENT_SCENE_8, 4500);
|
||||
break;
|
||||
case EVENT_SCENE_8:
|
||||
if (Creature* felika = ObjectAccessor::GetCreature(*me, felikaGUID))
|
||||
felika->AI()->Talk(SAY_FELIKA_2);
|
||||
events.ScheduleEvent(EVENT_SCENE_9, 4500);
|
||||
break;
|
||||
case EVENT_SCENE_9:
|
||||
if (Creature* olvia = ObjectAccessor::GetCreature(*me, olviaGUID))
|
||||
olvia->AI()->Talk(SAY_OLVIA_2);
|
||||
events.ScheduleEvent(EVENT_SCENE_10, 4500);
|
||||
break;
|
||||
case EVENT_SCENE_10:
|
||||
Talk(SAY_RUNTHAK_1);
|
||||
events.ScheduleEvent(EVENT_SCENE_11, 1500);
|
||||
break;
|
||||
case EVENT_SCENE_11:
|
||||
Talk(SAY_RUNTHAK_2);
|
||||
events.ScheduleEvent(EVENT_SCENE_12, 4500);
|
||||
break;
|
||||
case EVENT_SCENE_12:
|
||||
Talk(SAY_RUNTHAK_3);
|
||||
events.ScheduleEvent(EVENT_SCENE_13, 4500);
|
||||
break;
|
||||
case EVENT_SCENE_13:
|
||||
Talk(SAY_RUNTHAK_4);
|
||||
events.ScheduleEvent(EVENT_RESET, 25000);
|
||||
break;
|
||||
case EVENT_RESET:
|
||||
Reset();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GetCitizenGuids()
|
||||
{
|
||||
// if one GUID is empty it means all the others are empty as well so we should store them
|
||||
// otherwise do not call for grid search since someone else already activated event once before and guids are stored
|
||||
if (gryshkaGUID.IsEmpty())
|
||||
{
|
||||
std::list<Unit*> citizenList;
|
||||
Trinity::AnyFriendlyUnitInObjectRangeCheck checker(me, me, 25.0f);
|
||||
Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(me, citizenList, checker);
|
||||
me->VisitNearbyObject(20.0f, searcher);
|
||||
for (Unit* target : citizenList)
|
||||
{
|
||||
switch (target->GetEntry())
|
||||
{
|
||||
case NPC_GRYSHKA:
|
||||
gryshkaGUID = target->GetGUID();
|
||||
break;
|
||||
case NPC_OLVIA:
|
||||
olviaGUID = target->GetGUID();
|
||||
break;
|
||||
case NPC_SANA:
|
||||
sanaGUID = target->GetGUID();
|
||||
break;
|
||||
case NPC_FELIKA:
|
||||
felikaGUID = target->GetGUID();
|
||||
break;
|
||||
case NPC_THATHUNG:
|
||||
thungGUID = target->GetGUID();
|
||||
break;
|
||||
case NPC_KAJA:
|
||||
kajaGUID = target->GetGUID();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
bool inProgress;
|
||||
ObjectGuid gryshkaGUID;
|
||||
ObjectGuid olviaGUID;
|
||||
ObjectGuid sanaGUID;
|
||||
ObjectGuid felikaGUID;
|
||||
ObjectGuid thungGUID;
|
||||
ObjectGuid kajaGUID;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_overlord_runthak_orgrimmarAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// Phased out thrall during herald of war chain quest
|
||||
enum HeraldEntries
|
||||
{
|
||||
NPC_PORTAL_STORMWIND = 31640,
|
||||
NPC_JAINA_PROUDMOORE = 31418,
|
||||
NPC_BANSHEE_SYLVANAS = 31419,
|
||||
NPC_KORKRON_GUARD = 31417,
|
||||
NPC_THRALL_HERALD = 31412,
|
||||
|
||||
GO_PORTAL_UNDERCITY = 193425
|
||||
};
|
||||
|
||||
enum HeraldMisc
|
||||
{
|
||||
QUEST_HERALD_OF_WAR = 13257,
|
||||
GUARDS_SIZE = 4
|
||||
};
|
||||
|
||||
enum HeraldActions
|
||||
{
|
||||
ACTION_START_SCENE = 0
|
||||
};
|
||||
|
||||
enum HeraldSpell
|
||||
{
|
||||
SPELL_JAINA_SPAWNIN = 55761
|
||||
};
|
||||
|
||||
enum HeraldTalk
|
||||
{
|
||||
SAY_THRALL_0 = 0, // Kor'kron, stand down!
|
||||
SAY_THRALL_1 = 1, // Jaina...
|
||||
SAY_THRALL_2 = 2, // Jaina, what happened at the Wrathgate. It was a betrayal from within...
|
||||
SAY_THRALL_3 = 3, // The Horde has lost the Undercity.
|
||||
SAY_THRALL_4 = 4, // We now prepare to lay siege to the city and bring the perpetrators of this unforgivable crime to justice.
|
||||
SAY_THRALL_5 = 5, // If we are forced into a conflict, the Lich King will destroy our divided forces in Northrend.
|
||||
SAY_THRALL_6 = 6, // We will make this right, Jaina. Tell your king all that you have learned here.
|
||||
SAY_THRALL_7 = 7, // Kor'kron, prepare transport to the Undercity.
|
||||
|
||||
SAY_SYLVANAS_0 = 0, // Lady Proudmoore, the Warchief speaks the truth. This subterfuge was set in motion by Varimathras and Grand Apothecary Putress. It was not the Horde's doing.
|
||||
SAY_SYLVANAS_1 = 1, // As the combined Horde and Alliance forces began their assault upon the Wrath Gate, an uprising broke out in the Undercity. Varimathras and hordes of his demonic brethren attacked. Hundreds of my people were slain in the coup. I barely managed to escape with my life.
|
||||
|
||||
SAY_JAINA_0 = 0, // Thrall, what has happened? The King is preparing for war...
|
||||
SAY_JAINA_1 = 1, // I will deliver this information to King Wrynn, Thrall, but...
|
||||
SAY_JAINA_2 = 2, // Bolvar was like a brother to him. In the King's absence, Bolvar kept the Alliance united. He found strength for our people in our darkest hours. He watched over Anduin, raising him as his own.
|
||||
SAY_JAINA_3 = 3, // I fear that the rage will consume him, Thrall. I remain hopeful that reason will prevail, but we must prepare for the worst... for war.
|
||||
SAY_JAINA_4 = 4 // Farewell, Warchief. I pray that the next time we meet it will be as allies.
|
||||
};
|
||||
|
||||
enum HeraldEvents
|
||||
{
|
||||
EVENT_HERALD_SCENE1 = 1,
|
||||
EVENT_HERALD_SCENE2 = 2,
|
||||
EVENT_HERALD_SCENE3 = 3,
|
||||
EVENT_HERALD_SCENE4 = 4,
|
||||
EVENT_HERALD_SCENE5 = 5,
|
||||
EVENT_HERALD_SCENE6 = 6,
|
||||
EVENT_HERALD_SCENE7 = 7,
|
||||
EVENT_HERALD_SCENE8 = 8,
|
||||
EVENT_HERALD_SCENE9 = 9,
|
||||
EVENT_HERALD_SCENE10 = 10,
|
||||
EVENT_HERALD_SCENE11 = 11,
|
||||
EVENT_HERALD_SCENE12 = 12,
|
||||
EVENT_HERALD_SCENE13 = 13,
|
||||
EVENT_HERALD_SCENE14 = 14,
|
||||
EVENT_HERALD_SCENE15 = 15,
|
||||
EVENT_HERALD_RESET = 16
|
||||
};
|
||||
|
||||
Position const GuardsSpawnPosition[GUARDS_SIZE] =
|
||||
{
|
||||
{ 1909.39f, -4144.21f, 40.6368f, 0.042239f },
|
||||
{ 1910.73f, -4155.26f, 40.6316f, 0.615577f },
|
||||
{ 1934.01f, -4141.40f, 40.6375f, 3.61109f },
|
||||
{ 1931.11f, -4156.38f, 40.6130f, 2.19737f }
|
||||
};
|
||||
|
||||
Position const GuardsMovePosition[GUARDS_SIZE] =
|
||||
{
|
||||
{ 1917.461670f, -4147.514160f, 40.636799f, 5.89346f },
|
||||
{ 1916.181274f, -4152.295898f, 40.629120f, 0.497757f },
|
||||
{ 1926.435425f, -4146.397461f, 40.618534f, 3.846709f },
|
||||
{ 1926.519165f, -4153.216797f, 40.614975f, 2.570434f }
|
||||
};
|
||||
|
||||
Position const MiscMovePositions[3] =
|
||||
{
|
||||
{ 1921.719604f, -4143.051270f, 40.623356f, 1.657789f }, // jaina move
|
||||
{ 1921.151855f, -4139.343750f, 40.583084f, 4.732627f }, // thrall move
|
||||
{ 1918.732422f, -4139.619629f, 40.607685f, 4.803311f } // sylvanas move
|
||||
};
|
||||
|
||||
Position const PortalSpawnPosition = { 1921.752441f, -4151.148438f, 40.623848f, 1.714324f };
|
||||
|
||||
class npc_thrall_herald_of_war : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_thrall_herald_of_war() : CreatureScript("npc_thrall_herald_of_war") { }
|
||||
|
||||
struct npc_thrall_herald_of_warAI : public ScriptedAI
|
||||
{
|
||||
npc_thrall_herald_of_warAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
spawnedGuards = false;
|
||||
sceneInProgress = false;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
me->GetMotionMaster()->MovePath(me->GetSpawnId() * 10, true);
|
||||
sceneInProgress = false;
|
||||
|
||||
if (!spawnedGuards)
|
||||
{
|
||||
spawnedGuards = true;
|
||||
for (uint8 i = 0; i < GUARDS_SIZE; i++)
|
||||
{
|
||||
if (Creature* korkronGuard = me->SummonCreature(NPC_KORKRON_GUARD, GuardsSpawnPosition[i]))
|
||||
guardsGUIDs[i] = korkronGuard->GetGUID();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 pointId) override
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (pointId == 2)
|
||||
me->GetMotionMaster()->MovePath(me->GetSpawnId() * 10, true);
|
||||
}
|
||||
|
||||
void DoAction(int32 actionId) override
|
||||
{
|
||||
if (actionId == ACTION_START_SCENE && !sceneInProgress)
|
||||
{
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
sceneInProgress = true;
|
||||
|
||||
if (Creature* jaina = me->SummonCreature(NPC_JAINA_PROUDMOORE, PortalSpawnPosition))
|
||||
{
|
||||
me->SetFacingToObject(jaina);
|
||||
jainaGUID = jaina->GetGUID();
|
||||
jaina->CastSpell(jaina, SPELL_JAINA_SPAWNIN);
|
||||
}
|
||||
|
||||
if (Creature* stormwindPortal = me->SummonCreature(NPC_PORTAL_STORMWIND, PortalSpawnPosition))
|
||||
{
|
||||
stormwindPortal->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
stormwindPortalGUID = stormwindPortal->GetGUID();
|
||||
}
|
||||
|
||||
for (uint8 i = 0; i < GUARDS_SIZE; i++)
|
||||
{
|
||||
if (Creature* guards = ObjectAccessor::GetCreature(*me, guardsGUIDs[i]))
|
||||
{
|
||||
guards->SetWalk(false);
|
||||
guards->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
|
||||
guards->GetMotionMaster()->MovePoint(1, GuardsMovePosition[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (Creature* sylvanas = me->FindNearestCreature(NPC_BANSHEE_SYLVANAS, 25.0f))
|
||||
sylvanasGUID = sylvanas->GetGUID();
|
||||
|
||||
events.ScheduleEvent(EVENT_HERALD_SCENE1, 4000);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventID = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventID)
|
||||
{
|
||||
case EVENT_HERALD_SCENE1:
|
||||
Talk(SAY_THRALL_0);
|
||||
me->GetMotionMaster()->MovePoint(1, MiscMovePositions[1]);
|
||||
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
|
||||
{
|
||||
jaina->SetWalk(true);
|
||||
jaina->GetMotionMaster()->MovePoint(1, MiscMovePositions[0]);
|
||||
}
|
||||
|
||||
for (uint8 i = 0; i < GUARDS_SIZE; i++)
|
||||
{
|
||||
if (Creature* guard = ObjectAccessor::GetCreature(*me, guardsGUIDs[i]))
|
||||
{
|
||||
guard->GetMotionMaster()->MoveTargetedHome();
|
||||
guard->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
|
||||
}
|
||||
}
|
||||
events.ScheduleEvent(EVENT_HERALD_SCENE2, 3000);
|
||||
break;
|
||||
case EVENT_HERALD_SCENE2:
|
||||
Talk(SAY_THRALL_1);
|
||||
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
|
||||
me->SetFacingToObject(jaina);
|
||||
events.ScheduleEvent(EVENT_HERALD_SCENE3, 3500);
|
||||
break;
|
||||
case EVENT_HERALD_SCENE3:
|
||||
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
|
||||
jaina->AI()->Talk(SAY_JAINA_0);
|
||||
events.ScheduleEvent(EVENT_HERALD_SCENE4, 5500);
|
||||
break;
|
||||
case EVENT_HERALD_SCENE4:
|
||||
Talk(SAY_THRALL_2);
|
||||
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasGUID))
|
||||
{
|
||||
sylvanas->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
sylvanas->SetWalk(true);
|
||||
sylvanas->GetMotionMaster()->MovePoint(1, MiscMovePositions[2]);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_HERALD_SCENE5, 6500);
|
||||
break;
|
||||
case EVENT_HERALD_SCENE5:
|
||||
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasGUID))
|
||||
sylvanas->AI()->Talk(SAY_SYLVANAS_0);
|
||||
events.ScheduleEvent(EVENT_HERALD_SCENE6, 10000);
|
||||
break;
|
||||
case EVENT_HERALD_SCENE6:
|
||||
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasGUID))
|
||||
sylvanas->AI()->Talk(SAY_SYLVANAS_1);
|
||||
events.ScheduleEvent(EVENT_HERALD_SCENE7, 20000);
|
||||
break;
|
||||
case EVENT_HERALD_SCENE7:
|
||||
Talk(SAY_THRALL_3);
|
||||
events.ScheduleEvent(EVENT_HERALD_SCENE8, 4500);
|
||||
break;
|
||||
case EVENT_HERALD_SCENE8:
|
||||
Talk(SAY_THRALL_4);
|
||||
events.ScheduleEvent(EVENT_HERALD_SCENE9, 10000);
|
||||
break;
|
||||
case EVENT_HERALD_SCENE9:
|
||||
Talk(SAY_THRALL_5);
|
||||
events.ScheduleEvent(EVENT_HERALD_SCENE10, 8000);
|
||||
break;
|
||||
case EVENT_HERALD_SCENE10:
|
||||
Talk(SAY_THRALL_6);
|
||||
events.ScheduleEvent(EVENT_HERALD_SCENE11, 9000);
|
||||
break;
|
||||
case EVENT_HERALD_SCENE11:
|
||||
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
|
||||
jaina->AI()->Talk(SAY_JAINA_1);
|
||||
events.ScheduleEvent(EVENT_HERALD_SCENE12, 6000);
|
||||
break;
|
||||
case EVENT_HERALD_SCENE12:
|
||||
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
|
||||
jaina->AI()->Talk(SAY_JAINA_2);
|
||||
events.ScheduleEvent(EVENT_HERALD_SCENE13, 14000);
|
||||
break;
|
||||
case EVENT_HERALD_SCENE13:
|
||||
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
|
||||
jaina->AI()->Talk(SAY_JAINA_3);
|
||||
events.ScheduleEvent(EVENT_HERALD_SCENE14, 10000);
|
||||
break;
|
||||
case EVENT_HERALD_SCENE14:
|
||||
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
|
||||
{
|
||||
jaina->AI()->Talk(SAY_JAINA_4);
|
||||
jaina->SetWalk(true);
|
||||
jaina->GetMotionMaster()->MovePoint(2, jaina->GetHomePosition());
|
||||
jaina->DespawnOrUnsummon(5000);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_HERALD_SCENE15, 7000);
|
||||
break;
|
||||
case EVENT_HERALD_SCENE15:
|
||||
{
|
||||
me->SetWalk(true);
|
||||
me->GetMotionMaster()->MovePoint(2, me->GetHomePosition());
|
||||
Talk(SAY_THRALL_7);
|
||||
|
||||
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasGUID))
|
||||
{
|
||||
sylvanas->SetWalk(true);
|
||||
sylvanas->GetMotionMaster()->MovePoint(2, sylvanas->GetHomePosition());
|
||||
}
|
||||
|
||||
if (Creature* portal = ObjectAccessor::GetCreature(*me, stormwindPortalGUID))
|
||||
portal->DespawnOrUnsummon();
|
||||
|
||||
events.ScheduleEvent(EVENT_HERALD_RESET, 60000);
|
||||
break;
|
||||
}
|
||||
case EVENT_HERALD_RESET:
|
||||
Reset();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
ObjectGuid guardsGUIDs[GUARDS_SIZE];
|
||||
ObjectGuid jainaGUID;
|
||||
ObjectGuid sylvanasGUID;
|
||||
ObjectGuid stormwindPortalGUID;
|
||||
bool spawnedGuards;
|
||||
bool sceneInProgress;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_thrall_herald_of_warAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class areatrigger_orgrimmar_herald_of_war : public AreaTriggerScript
|
||||
{
|
||||
public:
|
||||
areatrigger_orgrimmar_herald_of_war() : AreaTriggerScript("areatrigger_orgrimmar_herald_of_war") { }
|
||||
|
||||
bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) override
|
||||
{
|
||||
if (player->IsAlive() && player->GetQuestStatus(QUEST_HERALD_OF_WAR) == QUEST_STATUS_COMPLETE)
|
||||
{
|
||||
if (Creature* thrall = player->FindNearestCreature(NPC_THRALL_HERALD, 50.0f))
|
||||
{
|
||||
thrall->AI()->DoAction(ACTION_START_SCENE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_orgrimmar()
|
||||
{
|
||||
new npc_shenthul();
|
||||
new npc_thrall_warchief();
|
||||
new npc_overlord_runthak_orgrimmar();
|
||||
new npc_thrall_herald_of_war();
|
||||
new areatrigger_orgrimmar_herald_of_war();
|
||||
}
|
||||
@@ -306,7 +306,7 @@ class boss_devourer_of_souls : public CreatureScript
|
||||
|
||||
case EVENT_WAILING_SOULS_TICK:
|
||||
beamAngle += beamAngleDiff;
|
||||
me->SetFacingTo(beamAngle);
|
||||
me->SetFacingTo(beamAngle, true);
|
||||
me->StopMoving();
|
||||
|
||||
DoCast(me, SPELL_WAILING_SOULS);
|
||||
|
||||
@@ -361,12 +361,12 @@ class boss_sindragosa : public CreatureScript
|
||||
break;
|
||||
case POINT_AIR_PHASE:
|
||||
me->CastCustomSpell(SPELL_ICE_TOMB_TARGET, SPELLVALUE_MAX_TARGETS, RAID_MODE<int32>(2, 5, 2, 6), NULL, TRIGGERED_FULL_MASK);
|
||||
me->SetFacingTo(float(M_PI));
|
||||
me->SetFacingTo(float(M_PI), true);
|
||||
events.ScheduleEvent(EVENT_AIR_MOVEMENT_FAR, 1);
|
||||
events.ScheduleEvent(EVENT_FROST_BOMB, 9000);
|
||||
break;
|
||||
case POINT_AIR_PHASE_FAR:
|
||||
me->SetFacingTo(float(M_PI));
|
||||
me->SetFacingTo(float(M_PI), true);
|
||||
events.ScheduleEvent(EVENT_LAND, 30000);
|
||||
break;
|
||||
case POINT_LAND:
|
||||
@@ -723,7 +723,7 @@ class npc_spinestalker : public CreatureScript
|
||||
me->SetDisableGravity(false);
|
||||
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
|
||||
me->SetHomePosition(SpinestalkerLandPos);
|
||||
me->SetFacingTo(SpinestalkerLandPos.GetOrientation());
|
||||
me->SetFacingTo(SpinestalkerLandPos.GetOrientation(), true);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
@@ -860,7 +860,7 @@ class npc_rimefang : public CreatureScript
|
||||
me->SetDisableGravity(false);
|
||||
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
|
||||
me->SetHomePosition(RimefangLandPos);
|
||||
me->SetFacingTo(RimefangLandPos.GetOrientation());
|
||||
me->SetFacingTo(RimefangLandPos.GetOrientation(), true);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
|
||||
@@ -813,7 +813,7 @@ class boss_the_lich_king : public CreatureScript
|
||||
events.ScheduleEvent(EVENT_INTRO_TALK_1, 9000, 0, PHASE_INTRO);
|
||||
break;
|
||||
case POINT_CENTER_1:
|
||||
me->SetFacingTo(0.0f);
|
||||
me->SetFacingTo(0.0f, true);
|
||||
Talk(SAY_LK_REMORSELESS_WINTER);
|
||||
me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL);
|
||||
DoCast(me, SPELL_REMORSELESS_WINTER_1);
|
||||
@@ -828,7 +828,7 @@ class boss_the_lich_king : public CreatureScript
|
||||
events.ScheduleEvent(EVENT_SOUL_REAPER, 94000, 0, PHASE_TWO);
|
||||
break;
|
||||
case POINT_CENTER_2:
|
||||
me->SetFacingTo(0.0f);
|
||||
me->SetFacingTo(0.0f, true);
|
||||
Talk(SAY_LK_REMORSELESS_WINTER);
|
||||
me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL);
|
||||
DoCast(me, SPELL_REMORSELESS_WINTER_2);
|
||||
|
||||
@@ -437,7 +437,7 @@ class boss_algalon_the_observer : public CreatureScript
|
||||
me->SetDisableGravity(false);
|
||||
else if (pointId == POINT_ALGALON_OUTRO)
|
||||
{
|
||||
me->SetFacingTo(1.605703f);
|
||||
me->SetFacingTo(1.605703f, true);
|
||||
events.ScheduleEvent(EVENT_OUTRO_3, 1200);
|
||||
events.ScheduleEvent(EVENT_OUTRO_4, 2400);
|
||||
events.ScheduleEvent(EVENT_OUTRO_5, 8500);
|
||||
|
||||
@@ -75,7 +75,7 @@ class boss_erekem : public CreatureScript
|
||||
void MovementInform(uint32 type, uint32 pointId) override
|
||||
{
|
||||
if (type == EFFECT_MOTION_TYPE && pointId == POINT_INTRO)
|
||||
me->SetFacingTo(4.921828f);
|
||||
me->SetFacingTo(4.921828f, true);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
|
||||
@@ -430,6 +430,8 @@ class npc_sinclari_vh : public CreatureScript
|
||||
me->GetCreatureListWithEntryInGrid(guardList, NPC_VIOLET_HOLD_GUARD, 100.0f);
|
||||
for (Creature* guard : guardList)
|
||||
{
|
||||
if (!guard->IsAlive())
|
||||
continue;
|
||||
guard->SetReactState(REACT_PASSIVE);
|
||||
guard->SetWalk(false);
|
||||
guard->GetMotionMaster()->MovePoint(0, GuardsMovePosition);
|
||||
|
||||
@@ -174,7 +174,7 @@ class npc_commander_eligor_dawnbringer : public CreatureScript
|
||||
{
|
||||
if (id == 1)
|
||||
{
|
||||
me->SetFacingTo(PosTalkLocations[talkWing].GetOrientation());
|
||||
me->SetFacingTo(PosTalkLocations[talkWing].GetOrientation(), true);
|
||||
TurnAudience();
|
||||
|
||||
switch (talkWing)
|
||||
|
||||
@@ -444,7 +444,7 @@ public:
|
||||
else if (pointId == AKAMA_INTRO_WAYPOINT)
|
||||
{
|
||||
me->SetWalk(false);
|
||||
me->SetFacingTo(0.08726646f);
|
||||
me->SetFacingTo(0.08726646f, true);
|
||||
_events.ScheduleEvent(EVENT_START_SOUL_EXPEL, Seconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -595,7 +595,7 @@ class boss_kaelthas : public CreatureScript
|
||||
events.ScheduleEvent(EVENT_TRANSITION_1, 1000);
|
||||
break;
|
||||
case POINT_TRANSITION_CENTER_ASCENDING:
|
||||
me->SetFacingTo(float(M_PI));
|
||||
me->SetFacingTo(float(M_PI), true);
|
||||
Talk(SAY_PHASE5_NUTS);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetDisableGravity(true);
|
||||
|
||||
Reference in new issue
Block a user