mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-17 10:55:43 +00:00
Big re-organization of repository [W.I.P]
This commit is contained in:
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef BFD_H_
|
||||
#define BFD_H_
|
||||
|
||||
enum Data
|
||||
{
|
||||
TYPE_GELIHAST = 0,
|
||||
TYPE_FIRE1 = 1,
|
||||
TYPE_FIRE2 = 2,
|
||||
TYPE_FIRE3 = 3,
|
||||
TYPE_FIRE4 = 4,
|
||||
TYPE_AKU_MAI = 5,
|
||||
MAX_ENCOUNTERS = 6
|
||||
};
|
||||
|
||||
enum CreatureIds
|
||||
{
|
||||
NPC_AKU_MAI_SNAPJAW = 4825,
|
||||
NPC_MURKSHALLOW_SOFTSHELL = 4977,
|
||||
NPC_AKU_MAI_SERVANT = 4978,
|
||||
NPC_BARBED_CRUSTACEAN = 4823
|
||||
};
|
||||
|
||||
enum GameObjectIds
|
||||
{
|
||||
GO_SHRINE_OF_GELIHAST = 103015,
|
||||
GO_FIRE_OF_AKU_MAI_1 = 21118,
|
||||
GO_FIRE_OF_AKU_MAI_2 = 21119,
|
||||
GO_FIRE_OF_AKU_MAI_3 = 21120,
|
||||
GO_FIRE_OF_AKU_MAI_4 = 21121,
|
||||
GO_AKU_MAI_DOOR = 21117,
|
||||
GO_ALTAR_OF_THE_DEEPS = 103016
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "blackfathom_deeps.h"
|
||||
|
||||
class instance_blackfathom_deeps : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_blackfathom_deeps() : InstanceMapScript("instance_blackfathom_deeps", 48) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_blackfathom_deeps_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
struct instance_blackfathom_deeps_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_blackfathom_deeps_InstanceMapScript(Map* map) : InstanceScript(map) { }
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
memset(&_encounters, 0, sizeof(_encounters));
|
||||
_akumaiPortalGUID = 0;
|
||||
_requiredDeaths = 0;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
if (creature->IsSummon() && (creature->GetEntry() == NPC_BARBED_CRUSTACEAN || creature->GetEntry() == NPC_AKU_MAI_SERVANT ||
|
||||
creature->GetEntry() == NPC_MURKSHALLOW_SOFTSHELL || creature->GetEntry() == NPC_AKU_MAI_SNAPJAW))
|
||||
++_requiredDeaths;
|
||||
}
|
||||
|
||||
void OnUnitDeath(Unit* unit)
|
||||
{
|
||||
if (unit->IsSummon() && (unit->GetEntry() == NPC_BARBED_CRUSTACEAN || unit->GetEntry() == NPC_AKU_MAI_SERVANT ||
|
||||
unit->GetEntry() == NPC_MURKSHALLOW_SOFTSHELL || unit->GetEntry() == NPC_AKU_MAI_SNAPJAW))
|
||||
{
|
||||
if (--_requiredDeaths == 0)
|
||||
if (_encounters[TYPE_FIRE1] == DONE && _encounters[TYPE_FIRE2] == DONE && _encounters[TYPE_FIRE3] == DONE && _encounters[TYPE_FIRE4] == DONE)
|
||||
HandleGameObject(_akumaiPortalGUID, true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* gameobject)
|
||||
{
|
||||
switch (gameobject->GetEntry())
|
||||
{
|
||||
case GO_FIRE_OF_AKU_MAI_1:
|
||||
case GO_FIRE_OF_AKU_MAI_2:
|
||||
case GO_FIRE_OF_AKU_MAI_3:
|
||||
case GO_FIRE_OF_AKU_MAI_4:
|
||||
if (_encounters[gameobject->GetEntry() - GO_FIRE_OF_AKU_MAI_1 + 1] == DONE)
|
||||
{
|
||||
gameobject->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE);
|
||||
gameobject->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_SHRINE_OF_GELIHAST:
|
||||
if (_encounters[TYPE_GELIHAST] == DONE)
|
||||
gameobject->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
break;
|
||||
case GO_ALTAR_OF_THE_DEEPS:
|
||||
if (_encounters[TYPE_AKU_MAI] == DONE)
|
||||
gameobject->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
break;
|
||||
case GO_AKU_MAI_DOOR:
|
||||
if (_encounters[TYPE_FIRE1] == DONE && _encounters[TYPE_FIRE2] == DONE && _encounters[TYPE_FIRE3] == DONE && _encounters[TYPE_FIRE4] == DONE)
|
||||
HandleGameObject(0, true, gameobject);
|
||||
_akumaiPortalGUID = gameobject->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_GELIHAST:
|
||||
case TYPE_FIRE1:
|
||||
case TYPE_FIRE2:
|
||||
case TYPE_FIRE3:
|
||||
case TYPE_FIRE4:
|
||||
case TYPE_AKU_MAI:
|
||||
_encounters[type] = data;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data == DONE)
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "B L " << _encounters[0] << ' ' << _encounters[1] << ' ' << _encounters[2] << ' ' << _encounters[3] << ' ' << _encounters[4] << ' ' << _encounters[5];
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
return;
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2;
|
||||
if (dataHead1 == 'B' && dataHead2 == 'L')
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
|
||||
{
|
||||
loadStream >> _encounters[i];
|
||||
if (_encounters[i] == IN_PROGRESS)
|
||||
_encounters[i] = NOT_STARTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _encounters[MAX_ENCOUNTERS];
|
||||
uint64 _akumaiPortalGUID;
|
||||
uint8 _requiredDeaths;
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_instance_blackfathom_deeps()
|
||||
{
|
||||
new instance_blackfathom_deeps();
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
# Copyright (C)
|
||||
#
|
||||
# This file is free software; as a special exception the author gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
set(scripts_STAT_SRCS
|
||||
${scripts_STAT_SRCS}
|
||||
Kalimdor/zone_stonetalon_mountains.cpp
|
||||
Kalimdor/zone_silithus.cpp
|
||||
Kalimdor/zone_moonglade.cpp
|
||||
Kalimdor/RazorfenDowns/razorfen_downs.cpp
|
||||
Kalimdor/RazorfenDowns/instance_razorfen_downs.cpp
|
||||
Kalimdor/RazorfenDowns/razorfen_downs.h
|
||||
Kalimdor/ZulFarrak/instance_zulfarrak.cpp
|
||||
Kalimdor/ZulFarrak/zulfarrak.h
|
||||
Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp
|
||||
Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.h
|
||||
Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_lieutenant_drake.cpp
|
||||
Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp
|
||||
Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/instance_old_hillsbrad.cpp
|
||||
Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp
|
||||
Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
|
||||
Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h
|
||||
Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h
|
||||
Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp
|
||||
Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
|
||||
Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp
|
||||
Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
|
||||
Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
|
||||
Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp
|
||||
Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h
|
||||
Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp
|
||||
Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp
|
||||
Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite.cpp
|
||||
Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm.cpp
|
||||
Kalimdor/CavernsOfTime/CullingOfStratholme/boss_meathook.cpp
|
||||
Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp
|
||||
Kalimdor/CavernsOfTime/CullingOfStratholme/boss_epoch.cpp
|
||||
Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
|
||||
Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
|
||||
Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.h
|
||||
Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.h
|
||||
Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp
|
||||
Kalimdor/CavernsOfTime/TheBlackMorass/boss_chrono_lord_deja.cpp
|
||||
Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp
|
||||
Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp
|
||||
Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp
|
||||
Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp
|
||||
Kalimdor/BlackfathomDeeps/blackfathom_deeps.h
|
||||
Kalimdor/zone_azuremyst_isle.cpp
|
||||
Kalimdor/zone_orgrimmar.cpp
|
||||
Kalimdor/zone_desolace.cpp
|
||||
Kalimdor/zone_feralas.cpp
|
||||
Kalimdor/Maraudon/instance_maraudon.cpp
|
||||
Kalimdor/Maraudon/maraudon.h
|
||||
Kalimdor/TempleOfAhnQiraj/boss_fankriss.cpp
|
||||
Kalimdor/TempleOfAhnQiraj/boss_huhuran.cpp
|
||||
Kalimdor/TempleOfAhnQiraj/instance_temple_of_ahnqiraj.cpp
|
||||
Kalimdor/TempleOfAhnQiraj/mob_anubisath_sentinel.cpp
|
||||
Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp
|
||||
Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp
|
||||
Kalimdor/TempleOfAhnQiraj/boss_sartura.cpp
|
||||
Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp
|
||||
Kalimdor/TempleOfAhnQiraj/temple_of_ahnqiraj.h
|
||||
Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp
|
||||
Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp
|
||||
Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp
|
||||
Kalimdor/zone_darkshore.cpp
|
||||
Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp
|
||||
Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp
|
||||
Kalimdor/RuinsOfAhnQiraj/boss_rajaxx.cpp
|
||||
Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp
|
||||
Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp
|
||||
Kalimdor/RuinsOfAhnQiraj/boss_moam.cpp
|
||||
Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.h
|
||||
Kalimdor/RuinsOfAhnQiraj/boss_kurinnaxx.cpp
|
||||
Kalimdor/zone_mulgore.cpp
|
||||
Kalimdor/zone_bloodmyst_isle.cpp
|
||||
Kalimdor/zone_thunder_bluff.cpp
|
||||
Kalimdor/zone_azshara.cpp
|
||||
Kalimdor/RazorfenKraul/instance_razorfen_kraul.cpp
|
||||
Kalimdor/zone_the_barrens.cpp
|
||||
Kalimdor/zone_ungoro_crater.cpp
|
||||
Kalimdor/WailingCaverns/wailing_caverns.h
|
||||
Kalimdor/WailingCaverns/instance_wailing_caverns.cpp
|
||||
Kalimdor/zone_durotar.cpp
|
||||
Kalimdor/zone_felwood.cpp
|
||||
Kalimdor/boss_azuregos.cpp
|
||||
Kalimdor/zone_tanaris.cpp
|
||||
Kalimdor/zone_dustwallow_marsh.cpp
|
||||
Kalimdor/zone_winterspring.cpp
|
||||
Kalimdor/zone_thousand_needles.cpp
|
||||
Kalimdor/zone_ashenvale.cpp
|
||||
Kalimdor/zone_teldrassil.cpp
|
||||
Kalimdor/OnyxiasLair/boss_onyxia.cpp
|
||||
Kalimdor/OnyxiasLair/onyxias_lair.h
|
||||
Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp
|
||||
Kalimdor/RagefireChasm/instance_ragefire_chasm.cpp
|
||||
Kalimdor/DireMaul/instance_dire_maul.cpp
|
||||
Kalimdor/DireMaul/dire_maul.h
|
||||
)
|
||||
|
||||
AC_ADD_SCRIPT_LOADER("Kalimdor" "ScriptLoader.h")
|
||||
|
||||
message(" -> Prepared: Kalimdor")
|
||||
@@ -1,260 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "hyjal.h"
|
||||
#include "hyjal_trash.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CARRION_SWARM = 31306,
|
||||
SPELL_SLEEP = 31298,
|
||||
SPELL_VAMPIRIC_AURA = 38196,
|
||||
SPELL_INFERNO = 31299,
|
||||
SPELL_IMMOLATION = 31303,
|
||||
SPELL_INFERNO_EFFECT = 31302,
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_ONDEATH = 0,
|
||||
SAY_ONSLAY = 1,
|
||||
SAY_SWARM = 2,
|
||||
SAY_SLEEP = 3,
|
||||
SAY_INFERNO = 4,
|
||||
SAY_ONAGGRO = 5,
|
||||
};
|
||||
|
||||
class boss_anetheron : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_anetheron() : CreatureScript("boss_anetheron") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_anetheronAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_anetheronAI : public hyjal_trashAI
|
||||
{
|
||||
boss_anetheronAI(Creature* creature) : hyjal_trashAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
go = false;
|
||||
}
|
||||
|
||||
uint32 SwarmTimer;
|
||||
uint32 SleepTimer;
|
||||
uint32 AuraTimer;
|
||||
uint32 InfernoTimer;
|
||||
bool go;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
damageTaken = 0;
|
||||
SwarmTimer = 45000;
|
||||
SleepTimer = 60000;
|
||||
AuraTimer = 5000;
|
||||
InfernoTimer = 45000;
|
||||
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_ANETHERONEVENT, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_ANETHERONEVENT, IN_PROGRESS);
|
||||
|
||||
Talk(SAY_ONAGGRO);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_ONSLAY);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (waypointId == 7)
|
||||
{
|
||||
Unit* target = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_JAINAPROUDMOORE));
|
||||
if (target && target->IsAlive())
|
||||
me->AddThreat(target, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
hyjal_trashAI::JustDied(killer);
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_ANETHERONEVENT, DONE);
|
||||
Talk(SAY_ONDEATH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (IsEvent)
|
||||
{
|
||||
//Must update npc_escortAI
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
if (!go)
|
||||
{
|
||||
go = true;
|
||||
AddWaypoint(0, 4896.08f, -1576.35f, 1333.65f);
|
||||
AddWaypoint(1, 4898.68f, -1615.02f, 1329.48f);
|
||||
AddWaypoint(2, 4907.12f, -1667.08f, 1321.00f);
|
||||
AddWaypoint(3, 4963.18f, -1699.35f, 1340.51f);
|
||||
AddWaypoint(4, 4989.16f, -1716.67f, 1335.74f);
|
||||
AddWaypoint(5, 5026.27f, -1736.89f, 1323.02f);
|
||||
AddWaypoint(6, 5037.77f, -1770.56f, 1324.36f);
|
||||
AddWaypoint(7, 5067.23f, -1789.95f, 1321.17f);
|
||||
Start(false, true);
|
||||
SetDespawnAtEnd(false);
|
||||
}
|
||||
}
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (SwarmTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_CARRION_SWARM);
|
||||
|
||||
SwarmTimer = urand(45000, 60000);
|
||||
Talk(SAY_SWARM);
|
||||
} else SwarmTimer -= diff;
|
||||
|
||||
if (SleepTimer <= diff)
|
||||
{
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
target->CastSpell(target, SPELL_SLEEP, true);
|
||||
}
|
||||
SleepTimer = 60000;
|
||||
Talk(SAY_SLEEP);
|
||||
} else SleepTimer -= diff;
|
||||
if (AuraTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_VAMPIRIC_AURA, true);
|
||||
AuraTimer = urand(10000, 20000);
|
||||
} else AuraTimer -= diff;
|
||||
if (InfernoTimer <= diff)
|
||||
{
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_INFERNO);
|
||||
InfernoTimer = 45000;
|
||||
Talk(SAY_INFERNO);
|
||||
} else InfernoTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class npc_towering_infernal : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_towering_infernal() : CreatureScript("npc_towering_infernal") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_towering_infernalAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_towering_infernalAI : public ScriptedAI
|
||||
{
|
||||
npc_towering_infernalAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
AnetheronGUID = instance->GetData64(DATA_ANETHERON);
|
||||
}
|
||||
|
||||
uint32 ImmolationTimer;
|
||||
uint32 CheckTimer;
|
||||
uint64 AnetheronGUID;
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
DoCast(me, SPELL_INFERNO_EFFECT);
|
||||
ImmolationTimer = 5000;
|
||||
CheckTimer = 5000;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
|
||||
{
|
||||
if (me->IsWithinDist(who, 50) && !me->IsInCombat() && me->IsValidAttackTarget(who))
|
||||
AttackStart(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (CheckTimer <= diff)
|
||||
{
|
||||
if (AnetheronGUID)
|
||||
{
|
||||
Creature* boss = ObjectAccessor::GetCreature(*me, AnetheronGUID);
|
||||
if (!boss || (boss && boss->isDead()))
|
||||
{
|
||||
me->setDeathState(JUST_DIED);
|
||||
me->RemoveCorpse();
|
||||
return;
|
||||
}
|
||||
}
|
||||
CheckTimer = 5000;
|
||||
} else CheckTimer -= diff;
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (ImmolationTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_IMMOLATION);
|
||||
ImmolationTimer = 5000;
|
||||
} else ImmolationTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_anetheron()
|
||||
{
|
||||
new boss_anetheron();
|
||||
new npc_towering_infernal();
|
||||
}
|
||||
@@ -1,644 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Boss_Archimonde
|
||||
SD%Complete: 85
|
||||
SDComment: Doomfires not completely offlike due to core limitations for random moving. Tyrande and second phase not fully implemented.
|
||||
SDCategory: Caverns of Time, Mount Hyjal
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "hyjal.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "hyjal_trash.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_AGGRO = 1,
|
||||
SAY_DOOMFIRE = 2,
|
||||
SAY_AIR_BURST = 3,
|
||||
SAY_SLAY = 4,
|
||||
SAY_ENRAGE = 5,
|
||||
SAY_DEATH = 6,
|
||||
SAY_SOUL_CHARGE = 7,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_DENOUEMENT_WISP = 32124,
|
||||
SPELL_ANCIENT_SPARK = 39349,
|
||||
SPELL_PROTECTION_OF_ELUNE = 38528,
|
||||
|
||||
SPELL_DRAIN_WORLD_TREE = 39140,
|
||||
SPELL_DRAIN_WORLD_TREE_2 = 39141,
|
||||
|
||||
SPELL_FINGER_OF_DEATH = 31984,
|
||||
SPELL_HAND_OF_DEATH = 35354,
|
||||
SPELL_AIR_BURST = 32014,
|
||||
SPELL_GRIP_OF_THE_LEGION = 31972,
|
||||
SPELL_DOOMFIRE_STRIKE = 31903, //summons two creatures
|
||||
SPELL_DOOMFIRE_SPAWN = 32074,
|
||||
SPELL_DOOMFIRE = 31945,
|
||||
SPELL_SOUL_CHARGE_YELLOW = 32045,
|
||||
SPELL_SOUL_CHARGE_GREEN = 32051,
|
||||
SPELL_SOUL_CHARGE_RED = 32052,
|
||||
SPELL_UNLEASH_SOUL_YELLOW = 32054,
|
||||
SPELL_UNLEASH_SOUL_GREEN = 32057,
|
||||
SPELL_UNLEASH_SOUL_RED = 32053,
|
||||
SPELL_FEAR = 31970,
|
||||
};
|
||||
|
||||
enum Summons
|
||||
{
|
||||
CREATURE_DOOMFIRE = 18095,
|
||||
CREATURE_DOOMFIRE_SPIRIT = 18104,
|
||||
CREATURE_ANCIENT_WISP = 17946,
|
||||
CREATURE_CHANNEL_TARGET = 22418,
|
||||
};
|
||||
|
||||
Position const NordrassilLoc = {5503.713f, -3523.436f, 1608.781f, 0.0f};
|
||||
|
||||
class npc_ancient_wisp : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ancient_wisp() : CreatureScript("npc_ancient_wisp") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_ancient_wispAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_ancient_wispAI : public ScriptedAI
|
||||
{
|
||||
npc_ancient_wispAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
ArchimondeGUID = 0;
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
uint64 ArchimondeGUID;
|
||||
uint32 CheckTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
CheckTimer = 1000;
|
||||
|
||||
ArchimondeGUID = instance->GetData64(DATA_ARCHIMONDE);
|
||||
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (CheckTimer <= diff)
|
||||
{
|
||||
if (Unit* Archimonde = ObjectAccessor::GetUnit(*me, ArchimondeGUID))
|
||||
{
|
||||
if (Archimonde->HealthBelowPct(2) || !Archimonde->IsAlive())
|
||||
DoCast(me, SPELL_DENOUEMENT_WISP);
|
||||
else
|
||||
DoCast(Archimonde, SPELL_ANCIENT_SPARK);
|
||||
}
|
||||
CheckTimer = 1000;
|
||||
} else CheckTimer -= diff;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/* This script is merely a placeholder for the Doomfire that triggers Doomfire spell. It will
|
||||
MoveChase the Doomfire Spirit always, until despawn (AttackStart is called upon it's spawn) */
|
||||
class npc_doomfire : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_doomfire() : CreatureScript("npc_doomfire") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_doomfireAI(creature);
|
||||
}
|
||||
|
||||
struct npc_doomfireAI : public ScriptedAI
|
||||
{
|
||||
npc_doomfireAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void Reset() { }
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) { }
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
damage = 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/* This is the script for the Doomfire Spirit Mob. This mob simply follow players or
|
||||
travels in random directions if target cannot be found. */
|
||||
class npc_doomfire_targetting : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_doomfire_targetting() : CreatureScript("npc_doomfire_targetting") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_doomfire_targettingAI(creature);
|
||||
}
|
||||
|
||||
struct npc_doomfire_targettingAI : public ScriptedAI
|
||||
{
|
||||
npc_doomfire_targettingAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint64 TargetGUID;
|
||||
uint32 ChangeTargetTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
TargetGUID = 0;
|
||||
ChangeTargetTimer = 5000;
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
|
||||
{
|
||||
//will update once TargetGUID is 0. In case noone actually moves(not likely) and this is 0
|
||||
//when UpdateAI needs it, it will be forced to select randomPoint
|
||||
if (!TargetGUID && who->GetTypeId() == TYPEID_PLAYER)
|
||||
TargetGUID = who->GetGUID();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (ChangeTargetTimer <= diff)
|
||||
{
|
||||
if (Unit* temp = ObjectAccessor::GetUnit(*me, TargetGUID))
|
||||
{
|
||||
me->GetMotionMaster()->MoveFollow(temp, 0.0f, 0.0f);
|
||||
TargetGUID = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Position pos;
|
||||
me->GetRandomNearPosition(pos, 40);
|
||||
me->GetMotionMaster()->MovePoint(0, pos.m_positionX, pos.m_positionY, pos.m_positionZ);
|
||||
}
|
||||
|
||||
ChangeTargetTimer = 5000;
|
||||
} else ChangeTargetTimer -= diff;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/* Finally, Archimonde's script. His script isn't extremely complex, most are simply spells on timers.
|
||||
The only complicated aspect of the battle is Finger of Death and Doomfire, with Doomfire being the
|
||||
hardest bit to code. Finger of Death is simply a distance check - if no one is in melee range, then
|
||||
select a random target and cast the spell on them. However, if someone IS in melee range, and this
|
||||
is NOT the main tank (creature's victim), then we aggro that player and they become the new victim.
|
||||
For Doomfire, we summon a mob (Doomfire Spirit) for the Doomfire mob to follow. It's spirit will
|
||||
randomly select it's target to follow and then we create the random movement making it unpredictable. */
|
||||
|
||||
class boss_archimonde : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_archimonde() : CreatureScript("boss_archimonde") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_archimondeAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_archimondeAI : public hyjal_trashAI
|
||||
{
|
||||
boss_archimondeAI(Creature* creature) : hyjal_trashAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint64 DoomfireSpiritGUID;
|
||||
uint64 WorldTreeGUID;
|
||||
|
||||
uint32 DrainNordrassilTimer;
|
||||
uint32 FearTimer;
|
||||
uint32 AirBurstTimer;
|
||||
uint32 GripOfTheLegionTimer;
|
||||
uint32 DoomfireTimer;
|
||||
uint32 SoulChargeTimer;
|
||||
uint8 SoulChargeCount;
|
||||
uint32 MeleeRangeCheckTimer;
|
||||
uint32 HandOfDeathTimer;
|
||||
uint32 SummonWispTimer;
|
||||
uint8 WispCount;
|
||||
uint32 EnrageTimer;
|
||||
uint32 CheckDistanceTimer;
|
||||
|
||||
bool Enraged;
|
||||
bool BelowTenPercent;
|
||||
bool HasProtected;
|
||||
bool IsChanneling;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
instance->SetData(DATA_ARCHIMONDEEVENT, NOT_STARTED);
|
||||
|
||||
DoomfireSpiritGUID = 0;
|
||||
damageTaken = 0;
|
||||
WorldTreeGUID = 0;
|
||||
|
||||
DrainNordrassilTimer = 0;
|
||||
FearTimer = 42000;
|
||||
AirBurstTimer = 30000;
|
||||
GripOfTheLegionTimer = urand(5000, 25000);
|
||||
DoomfireTimer = 20000;
|
||||
SoulChargeTimer = urand(2000, 30000);
|
||||
SoulChargeCount = 0;
|
||||
MeleeRangeCheckTimer = 15000;
|
||||
HandOfDeathTimer = 2000;
|
||||
WispCount = 0; // When ~30 wisps are summoned, Archimonde dies
|
||||
EnrageTimer = 600000; // 10 minutes
|
||||
CheckDistanceTimer = 30000; // This checks if he's too close to the World Tree (75 yards from a point on the tree), if true then he will enrage
|
||||
SummonWispTimer = 0;
|
||||
|
||||
Enraged = false;
|
||||
BelowTenPercent = false;
|
||||
HasProtected = false;
|
||||
IsChanneling = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
me->InterruptSpell(CURRENT_CHANNELED_SPELL);
|
||||
Talk(SAY_AGGRO);
|
||||
DoZoneInCombat();
|
||||
|
||||
instance->SetData(DATA_ARCHIMONDEEVENT, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
if (victim && victim->GetTypeId() == TYPEID_PLAYER)
|
||||
GainSoulCharge(victim->ToPlayer());
|
||||
}
|
||||
|
||||
void GainSoulCharge(Player* victim)
|
||||
{
|
||||
switch (victim->getClass())
|
||||
{
|
||||
case CLASS_PRIEST:
|
||||
case CLASS_PALADIN:
|
||||
case CLASS_WARLOCK:
|
||||
victim->CastSpell(me, SPELL_SOUL_CHARGE_RED, true);
|
||||
break;
|
||||
case CLASS_MAGE:
|
||||
case CLASS_ROGUE:
|
||||
case CLASS_WARRIOR:
|
||||
victim->CastSpell(me, SPELL_SOUL_CHARGE_YELLOW, true);
|
||||
break;
|
||||
case CLASS_DRUID:
|
||||
case CLASS_SHAMAN:
|
||||
case CLASS_HUNTER:
|
||||
victim->CastSpell(me, SPELL_SOUL_CHARGE_GREEN, true);
|
||||
break;
|
||||
}
|
||||
|
||||
SoulChargeTimer = urand(2000, 30000);
|
||||
++SoulChargeCount;
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
hyjal_trashAI::JustDied(killer);
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
instance->SetData(DATA_ARCHIMONDEEVENT, DONE);
|
||||
instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, me->GetEntry(), 1, me); }
|
||||
|
||||
bool CanUseFingerOfDeath()
|
||||
{
|
||||
// First we check if our current victim is in melee range or not.
|
||||
Unit* victim = me->GetVictim();
|
||||
if (victim && me->IsWithinDistInMap(victim, me->GetAggroRange(victim)))
|
||||
return false;
|
||||
|
||||
ThreatContainer::StorageType const &threatlist = me->getThreatManager().getThreatList();
|
||||
if (threatlist.empty())
|
||||
return false;
|
||||
|
||||
std::list<Unit*> targets;
|
||||
ThreatContainer::StorageType::const_iterator itr = threatlist.begin();
|
||||
for (; itr != threatlist.end(); ++itr)
|
||||
{
|
||||
Unit* unit = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid());
|
||||
if (unit && unit->IsAlive())
|
||||
targets.push_back(unit);
|
||||
}
|
||||
|
||||
if (targets.empty())
|
||||
return false;
|
||||
|
||||
targets.sort(Trinity::ObjectDistanceOrderPred(me));
|
||||
Unit* target = targets.front();
|
||||
if (target)
|
||||
{
|
||||
if (!me->IsWithinDistInMap(target, me->GetAggroRange(target)))
|
||||
return true; // Cast Finger of Death
|
||||
else // This target is closest, he is our new tank
|
||||
me->AddThreat(target, me->getThreatManager().getThreat(me->GetVictim()));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned)
|
||||
{
|
||||
if (summoned->GetEntry() == CREATURE_ANCIENT_WISP)
|
||||
summoned->AI()->AttackStart(me);
|
||||
else
|
||||
{
|
||||
summoned->setFaction(me->getFaction());
|
||||
summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
if (summoned->GetEntry() == CREATURE_DOOMFIRE_SPIRIT)
|
||||
{
|
||||
DoomfireSpiritGUID = summoned->GetGUID();
|
||||
}
|
||||
|
||||
if (summoned->GetEntry() == CREATURE_DOOMFIRE)
|
||||
{
|
||||
summoned->CastSpell(summoned, SPELL_DOOMFIRE_SPAWN, false);
|
||||
summoned->CastSpell(summoned, SPELL_DOOMFIRE, true, 0, 0, me->GetGUID());
|
||||
|
||||
if (Unit* DoomfireSpirit = ObjectAccessor::GetUnit(*me, DoomfireSpiritGUID))
|
||||
{
|
||||
summoned->GetMotionMaster()->MoveFollow(DoomfireSpirit, 0.0f, 0.0f);
|
||||
DoomfireSpiritGUID = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//this is code doing close to what the summoning spell would do (spell 31903)
|
||||
void SummonDoomfire(Unit* target)
|
||||
{
|
||||
me->SummonCreature(CREATURE_DOOMFIRE_SPIRIT,
|
||||
target->GetPositionX()+15.0f, target->GetPositionY()+15.0f, target->GetPositionZ(), 0,
|
||||
TEMPSUMMON_TIMED_DESPAWN, 27000);
|
||||
|
||||
me->SummonCreature(CREATURE_DOOMFIRE,
|
||||
target->GetPositionX()-15.0f, target->GetPositionY()-15.0f, target->GetPositionZ(), 0,
|
||||
TEMPSUMMON_TIMED_DESPAWN, 27000);
|
||||
}
|
||||
|
||||
void UnleashSoulCharge()
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
|
||||
bool HasCast = false;
|
||||
uint32 chargeSpell = 0;
|
||||
uint32 unleashSpell = 0;
|
||||
|
||||
switch (urand(0, 2))
|
||||
{
|
||||
case 0:
|
||||
chargeSpell = SPELL_SOUL_CHARGE_RED;
|
||||
unleashSpell = SPELL_UNLEASH_SOUL_RED;
|
||||
break;
|
||||
case 1:
|
||||
chargeSpell = SPELL_SOUL_CHARGE_YELLOW;
|
||||
unleashSpell = SPELL_UNLEASH_SOUL_YELLOW;
|
||||
break;
|
||||
case 2:
|
||||
chargeSpell = SPELL_SOUL_CHARGE_GREEN;
|
||||
unleashSpell = SPELL_UNLEASH_SOUL_GREEN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasAura(chargeSpell))
|
||||
{
|
||||
me->RemoveAuraFromStack(chargeSpell);
|
||||
DoCastVictim(unleashSpell);
|
||||
HasCast = true;
|
||||
SoulChargeCount--;
|
||||
}
|
||||
|
||||
if (HasCast)
|
||||
SoulChargeTimer = urand(2000, 30000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!me->IsInCombat())
|
||||
{
|
||||
// Do not let the raid skip straight to Archimonde. Visible and hostile ONLY if Azagalor is finished.
|
||||
if ((instance->GetData(DATA_AZGALOREVENT) < DONE) && (me->IsVisible() || (me->getFaction() != 35)))
|
||||
{
|
||||
me->SetVisible(false);
|
||||
me->setFaction(35);
|
||||
}
|
||||
else if ((instance->GetData(DATA_AZGALOREVENT) >= DONE) && (!me->IsVisible() || (me->getFaction() == 35)))
|
||||
{
|
||||
me->setFaction(1720);
|
||||
me->SetVisible(true);
|
||||
}
|
||||
|
||||
if (DrainNordrassilTimer <= diff)
|
||||
{
|
||||
if (!IsChanneling)
|
||||
{
|
||||
Creature* temp = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 1200000);
|
||||
|
||||
if (temp)
|
||||
WorldTreeGUID = temp->GetGUID();
|
||||
|
||||
if (Unit* Nordrassil = ObjectAccessor::GetUnit(*me, WorldTreeGUID))
|
||||
{
|
||||
Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
Nordrassil->SetDisplayId(11686);
|
||||
DoCast(Nordrassil, SPELL_DRAIN_WORLD_TREE);
|
||||
IsChanneling = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (Unit* Nordrassil = ObjectAccessor::GetUnit(*me, WorldTreeGUID))
|
||||
{
|
||||
Nordrassil->CastSpell(me, SPELL_DRAIN_WORLD_TREE_2, true);
|
||||
DrainNordrassilTimer = 1000;
|
||||
}
|
||||
} else DrainNordrassilTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->HealthBelowPct(10) && !BelowTenPercent && !Enraged)
|
||||
BelowTenPercent = true;
|
||||
|
||||
if (!Enraged)
|
||||
{
|
||||
if (EnrageTimer <= diff)
|
||||
{
|
||||
if (HealthAbovePct(10))
|
||||
{
|
||||
me->GetMotionMaster()->Clear(false);
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
Enraged = true;
|
||||
Talk(SAY_ENRAGE);
|
||||
}
|
||||
} else EnrageTimer -= diff;
|
||||
|
||||
if (CheckDistanceTimer <= diff)
|
||||
{
|
||||
// To simplify the check, we simply summon a Creature in the location and then check how far we are from the creature
|
||||
Creature* Check = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 2000);
|
||||
if (Check)
|
||||
{
|
||||
Check->SetVisible(false);
|
||||
|
||||
if (me->IsWithinDistInMap(Check, 75))
|
||||
{
|
||||
me->GetMotionMaster()->Clear(false);
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
Enraged = true;
|
||||
Talk(SAY_ENRAGE);
|
||||
}
|
||||
}
|
||||
CheckDistanceTimer = 5000;
|
||||
} else CheckDistanceTimer -= diff;
|
||||
}
|
||||
|
||||
if (BelowTenPercent)
|
||||
{
|
||||
if (!HasProtected)
|
||||
{
|
||||
me->GetMotionMaster()->Clear(false);
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
|
||||
//all members of raid must get this buff
|
||||
DoCastVictim(SPELL_PROTECTION_OF_ELUNE, true);
|
||||
HasProtected = true;
|
||||
Enraged = true;
|
||||
}
|
||||
|
||||
if (SummonWispTimer <= diff)
|
||||
{
|
||||
DoSpawnCreature(CREATURE_ANCIENT_WISP, float(rand()%40), float(rand()%40), 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
SummonWispTimer = 1500;
|
||||
++WispCount;
|
||||
} else SummonWispTimer -= diff;
|
||||
|
||||
if (WispCount >= 30)
|
||||
Unit::DealDamage(me, me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
|
||||
}
|
||||
|
||||
if (Enraged)
|
||||
{
|
||||
if (HandOfDeathTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_HAND_OF_DEATH);
|
||||
HandOfDeathTimer = 2000;
|
||||
} else HandOfDeathTimer -= diff;
|
||||
return; // Don't do anything after this point.
|
||||
}
|
||||
|
||||
if (SoulChargeCount)
|
||||
{
|
||||
if (SoulChargeTimer <= diff)
|
||||
UnleashSoulCharge();
|
||||
else SoulChargeTimer -= diff;
|
||||
}
|
||||
|
||||
if (GripOfTheLegionTimer <= diff)
|
||||
{
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_GRIP_OF_THE_LEGION);
|
||||
GripOfTheLegionTimer = urand(5000, 25000);
|
||||
} else GripOfTheLegionTimer -= diff;
|
||||
|
||||
if (AirBurstTimer <= diff)
|
||||
{
|
||||
Talk(SAY_AIR_BURST);
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1), SPELL_AIR_BURST);//not on tank
|
||||
AirBurstTimer = urand(25000, 40000);
|
||||
} else AirBurstTimer -= diff;
|
||||
|
||||
if (FearTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_FEAR);
|
||||
FearTimer = 42000;
|
||||
} else FearTimer -= diff;
|
||||
|
||||
if (DoomfireTimer <= diff)
|
||||
{
|
||||
Talk(SAY_DOOMFIRE);
|
||||
Unit* temp = SelectTarget(SELECT_TARGET_RANDOM, 1);
|
||||
if (!temp)
|
||||
temp = me->GetVictim();
|
||||
|
||||
//replace with spell cast 31903 once implicitTarget 73 implemented
|
||||
SummonDoomfire(temp);
|
||||
|
||||
//supposedly three doomfire can be up at the same time
|
||||
DoomfireTimer = 20000;
|
||||
} else DoomfireTimer -= diff;
|
||||
|
||||
if (MeleeRangeCheckTimer <= diff)
|
||||
{
|
||||
if (CanUseFingerOfDeath())
|
||||
{
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH);
|
||||
MeleeRangeCheckTimer = 1000;
|
||||
}
|
||||
|
||||
MeleeRangeCheckTimer = 5000;
|
||||
} else MeleeRangeCheckTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
void WaypointReached(uint32 /*waypointId*/) { }
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_boss_archimonde()
|
||||
{
|
||||
new boss_archimonde();
|
||||
new npc_doomfire();
|
||||
new npc_doomfire_targetting();
|
||||
new npc_ancient_wisp();
|
||||
}
|
||||
@@ -1,278 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "hyjal.h"
|
||||
#include "hyjal_trash.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_RAIN_OF_FIRE = 31340,
|
||||
SPELL_DOOM = 31347,
|
||||
SPELL_HOWL_OF_AZGALOR = 31344,
|
||||
SPELL_CLEAVE = 31345,
|
||||
SPELL_BERSERK = 26662,
|
||||
|
||||
SPELL_THRASH = 12787,
|
||||
SPELL_CRIPPLE = 31406,
|
||||
SPELL_WARSTOMP = 31408,
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_ONDEATH = 0,
|
||||
SAY_ONSLAY = 1,
|
||||
SAY_DOOM = 2, // Not used?
|
||||
SAY_ONAGGRO = 3,
|
||||
};
|
||||
|
||||
class boss_azgalor : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_azgalor() : CreatureScript("boss_azgalor") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_azgalorAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_azgalorAI : public hyjal_trashAI
|
||||
{
|
||||
boss_azgalorAI(Creature* creature) : hyjal_trashAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
go = false;
|
||||
}
|
||||
|
||||
uint32 RainTimer;
|
||||
uint32 DoomTimer;
|
||||
uint32 HowlTimer;
|
||||
uint32 CleaveTimer;
|
||||
uint32 EnrageTimer;
|
||||
bool enraged;
|
||||
|
||||
bool go;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
damageTaken = 0;
|
||||
RainTimer = 20000;
|
||||
DoomTimer = 50000;
|
||||
HowlTimer = 30000;
|
||||
CleaveTimer = 10000;
|
||||
EnrageTimer = 600000;
|
||||
enraged = false;
|
||||
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_AZGALOREVENT, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_AZGALOREVENT, IN_PROGRESS);
|
||||
|
||||
Talk(SAY_ONAGGRO);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
Talk(SAY_ONSLAY);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (waypointId == 7 && instance)
|
||||
{
|
||||
Unit* target = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_THRALL));
|
||||
if (target && target->IsAlive())
|
||||
me->AddThreat(target, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
hyjal_trashAI::JustDied(killer);
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_AZGALOREVENT, DONE);
|
||||
Talk(SAY_ONDEATH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (IsEvent)
|
||||
{
|
||||
//Must update npc_escortAI
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
if (!go)
|
||||
{
|
||||
go = true;
|
||||
AddWaypoint(0, 5492.91f, -2404.61f, 1462.63f);
|
||||
AddWaypoint(1, 5531.76f, -2460.87f, 1469.55f);
|
||||
AddWaypoint(2, 5554.58f, -2514.66f, 1476.12f);
|
||||
AddWaypoint(3, 5554.16f, -2567.23f, 1479.90f);
|
||||
AddWaypoint(4, 5540.67f, -2625.99f, 1480.89f);
|
||||
AddWaypoint(5, 5508.16f, -2659.2f, 1480.15f);
|
||||
AddWaypoint(6, 5489.62f, -2704.05f, 1482.18f);
|
||||
AddWaypoint(7, 5457.04f, -2726.26f, 1485.10f);
|
||||
Start(false, true);
|
||||
SetDespawnAtEnd(false);
|
||||
}
|
||||
}
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (RainTimer <= diff)
|
||||
{
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 30, true), SPELL_RAIN_OF_FIRE);
|
||||
RainTimer = 20000+rand()%15000;
|
||||
} else RainTimer -= diff;
|
||||
|
||||
if (DoomTimer <= diff)
|
||||
{
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true), SPELL_DOOM);//never on tank
|
||||
DoomTimer = 45000+rand()%5000;
|
||||
} else DoomTimer -= diff;
|
||||
|
||||
if (HowlTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_HOWL_OF_AZGALOR);
|
||||
HowlTimer = 30000;
|
||||
} else HowlTimer -= diff;
|
||||
|
||||
if (CleaveTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
CleaveTimer = 10000+rand()%5000;
|
||||
} else CleaveTimer -= diff;
|
||||
|
||||
if (EnrageTimer < diff && !enraged)
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCast(me, SPELL_BERSERK, true);
|
||||
enraged = true;
|
||||
EnrageTimer = 600000;
|
||||
} else EnrageTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class npc_lesser_doomguard : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_lesser_doomguard() : CreatureScript("npc_lesser_doomguard") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_lesser_doomguardAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_lesser_doomguardAI : public hyjal_trashAI
|
||||
{
|
||||
npc_lesser_doomguardAI(Creature* creature) : hyjal_trashAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
AzgalorGUID = instance->GetData64(DATA_AZGALOR);
|
||||
}
|
||||
|
||||
uint32 CrippleTimer;
|
||||
uint32 WarstompTimer;
|
||||
uint32 CheckTimer;
|
||||
uint64 AzgalorGUID;
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
CrippleTimer = 50000;
|
||||
WarstompTimer = 10000;
|
||||
DoCast(me, SPELL_THRASH);
|
||||
CheckTimer = 5000;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 /*waypointId*/)
|
||||
{
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
|
||||
{
|
||||
if (me->IsWithinDist(who, 50) && !me->IsInCombat() && me->IsValidAttackTarget(who))
|
||||
AttackStart(who);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (CheckTimer <= diff)
|
||||
{
|
||||
if (AzgalorGUID)
|
||||
{
|
||||
Creature* boss = ObjectAccessor::GetCreature(*me, AzgalorGUID);
|
||||
if (!boss || (boss && boss->isDead()))
|
||||
{
|
||||
me->setDeathState(JUST_DIED);
|
||||
me->RemoveCorpse();
|
||||
return;
|
||||
}
|
||||
}
|
||||
CheckTimer = 5000;
|
||||
} else CheckTimer -= diff;
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (WarstompTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_WARSTOMP);
|
||||
WarstompTimer = 10000+rand()%5000;
|
||||
} else WarstompTimer -= diff;
|
||||
|
||||
if (CrippleTimer <= diff)
|
||||
{
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_CRIPPLE);
|
||||
CrippleTimer = 25000+rand()%5000;
|
||||
} else CrippleTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_azgalor()
|
||||
{
|
||||
new boss_azgalor();
|
||||
new npc_lesser_doomguard();
|
||||
}
|
||||
@@ -1,230 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "SpellAuraEffects.h"
|
||||
#include "SpellScript.h"
|
||||
#include "hyjal.h"
|
||||
#include "hyjal_trash.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CLEAVE = 31436,
|
||||
SPELL_WARSTOMP = 31480,
|
||||
SPELL_MARK = 31447,
|
||||
SPELL_MARK_DAMAGE = 31463
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_ONSLAY = 0,
|
||||
SAY_MARK = 1,
|
||||
SAY_ONAGGRO = 2,
|
||||
};
|
||||
|
||||
enum Sounds
|
||||
{
|
||||
SOUND_ONDEATH = 11018,
|
||||
};
|
||||
|
||||
class boss_kazrogal : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_kazrogal() : CreatureScript("boss_kazrogal") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_kazrogalAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_kazrogalAI : public hyjal_trashAI
|
||||
{
|
||||
boss_kazrogalAI(Creature* creature) : hyjal_trashAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
go = false;
|
||||
}
|
||||
|
||||
uint32 CleaveTimer;
|
||||
uint32 WarStompTimer;
|
||||
uint32 MarkTimer;
|
||||
uint32 MarkTimerBase;
|
||||
bool go;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
damageTaken = 0;
|
||||
CleaveTimer = 5000;
|
||||
WarStompTimer = 15000;
|
||||
MarkTimer = 45000;
|
||||
MarkTimerBase = 45000;
|
||||
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_KAZROGALEVENT, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_KAZROGALEVENT, IN_PROGRESS);
|
||||
Talk(SAY_ONAGGRO);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
Talk(SAY_ONSLAY);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (waypointId == 7 && instance)
|
||||
{
|
||||
Unit* target = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_THRALL));
|
||||
if (target && target->IsAlive())
|
||||
me->AddThreat(target, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
hyjal_trashAI::JustDied(killer);
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_KAZROGALEVENT, DONE);
|
||||
DoPlaySoundToSet(me, SOUND_ONDEATH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (IsEvent)
|
||||
{
|
||||
//Must update npc_escortAI
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
if (!go)
|
||||
{
|
||||
go = true;
|
||||
AddWaypoint(0, 5492.91f, -2404.61f, 1462.63f);
|
||||
AddWaypoint(1, 5531.76f, -2460.87f, 1469.55f);
|
||||
AddWaypoint(2, 5554.58f, -2514.66f, 1476.12f);
|
||||
AddWaypoint(3, 5554.16f, -2567.23f, 1479.90f);
|
||||
AddWaypoint(4, 5540.67f, -2625.99f, 1480.89f);
|
||||
AddWaypoint(5, 5508.16f, -2659.2f, 1480.15f);
|
||||
AddWaypoint(6, 5489.62f, -2704.05f, 1482.18f);
|
||||
AddWaypoint(7, 5457.04f, -2726.26f, 1485.10f);
|
||||
Start(false, true);
|
||||
SetDespawnAtEnd(false);
|
||||
}
|
||||
}
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (CleaveTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_CLEAVE);
|
||||
CleaveTimer = 6000+rand()%15000;
|
||||
} else CleaveTimer -= diff;
|
||||
|
||||
if (WarStompTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_WARSTOMP);
|
||||
WarStompTimer = 60000;
|
||||
} else WarStompTimer -= diff;
|
||||
|
||||
if (MarkTimer <= diff)
|
||||
{
|
||||
DoCastAOE(SPELL_MARK);
|
||||
|
||||
MarkTimerBase -= 5000;
|
||||
if (MarkTimerBase < 5500)
|
||||
MarkTimerBase = 5500;
|
||||
MarkTimer = MarkTimerBase;
|
||||
Talk(SAY_MARK);
|
||||
} else MarkTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class spell_mark_of_kazrogal : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_mark_of_kazrogal() : SpellScriptLoader("spell_mark_of_kazrogal") { }
|
||||
|
||||
class spell_mark_of_kazrogal_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_mark_of_kazrogal_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.remove_if(Trinity::PowerCheck(POWER_MANA, false));
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_kazrogal_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_mark_of_kazrogal_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_mark_of_kazrogal_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spell*/)
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_MARK_DAMAGE))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnPeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
|
||||
if (target->GetPower(POWER_MANA) == 0)
|
||||
{
|
||||
target->CastSpell(target, SPELL_MARK_DAMAGE, true, NULL, aurEff);
|
||||
// Remove aura
|
||||
SetDuration(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_mark_of_kazrogal_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_MANA_LEECH);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_mark_of_kazrogal_SpellScript();
|
||||
}
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_mark_of_kazrogal_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_kazrogal()
|
||||
{
|
||||
new boss_kazrogal();
|
||||
new spell_mark_of_kazrogal();
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "hyjal.h"
|
||||
#include "hyjal_trash.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_FROST_ARMOR = 31256,
|
||||
SPELL_DEATH_AND_DECAY = 31258,
|
||||
SPELL_FROST_NOVA = 31250,
|
||||
SPELL_ICEBOLT = 31249
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_ONDEATH = 0,
|
||||
SAY_ONSLAY = 1,
|
||||
SAY_DECAY = 2,
|
||||
SAY_NOVA = 3,
|
||||
SAY_ONAGGRO = 4
|
||||
};
|
||||
|
||||
class boss_rage_winterchill : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_rage_winterchill() : CreatureScript("boss_rage_winterchill") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_rage_winterchillAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_rage_winterchillAI : public hyjal_trashAI
|
||||
{
|
||||
boss_rage_winterchillAI(Creature* creature) : hyjal_trashAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
go = false;
|
||||
}
|
||||
|
||||
uint32 FrostArmorTimer;
|
||||
uint32 DecayTimer;
|
||||
uint32 NovaTimer;
|
||||
uint32 IceboltTimer;
|
||||
bool go;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
damageTaken = 0;
|
||||
FrostArmorTimer = 37000;
|
||||
DecayTimer = 45000;
|
||||
NovaTimer = 15000;
|
||||
IceboltTimer = 10000;
|
||||
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_RAGEWINTERCHILLEVENT, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_RAGEWINTERCHILLEVENT, IN_PROGRESS);
|
||||
Talk(SAY_ONAGGRO);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
Talk(SAY_ONSLAY);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (waypointId == 7 && instance)
|
||||
{
|
||||
Unit* target = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_JAINAPROUDMOORE));
|
||||
if (target && target->IsAlive())
|
||||
me->AddThreat(target, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
hyjal_trashAI::JustDied(killer);
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_RAGEWINTERCHILLEVENT, DONE);
|
||||
Talk(SAY_ONDEATH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (IsEvent)
|
||||
{
|
||||
//Must update npc_escortAI
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
if (!go)
|
||||
{
|
||||
go = true;
|
||||
AddWaypoint(0, 4896.08f, -1576.35f, 1333.65f);
|
||||
AddWaypoint(1, 4898.68f, -1615.02f, 1329.48f);
|
||||
AddWaypoint(2, 4907.12f, -1667.08f, 1321.00f);
|
||||
AddWaypoint(3, 4963.18f, -1699.35f, 1340.51f);
|
||||
AddWaypoint(4, 4989.16f, -1716.67f, 1335.74f);
|
||||
AddWaypoint(5, 5026.27f, -1736.89f, 1323.02f);
|
||||
AddWaypoint(6, 5037.77f, -1770.56f, 1324.36f);
|
||||
AddWaypoint(7, 5067.23f, -1789.95f, 1321.17f);
|
||||
Start(false, true);
|
||||
SetDespawnAtEnd(false);
|
||||
}
|
||||
}
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (FrostArmorTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_FROST_ARMOR);
|
||||
FrostArmorTimer = 40000+rand()%20000;
|
||||
} else FrostArmorTimer -= diff;
|
||||
if (DecayTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_DEATH_AND_DECAY);
|
||||
DecayTimer = 60000+rand()%20000;
|
||||
Talk(SAY_DECAY);
|
||||
} else DecayTimer -= diff;
|
||||
if (NovaTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_FROST_NOVA);
|
||||
NovaTimer = 30000+rand()%15000;
|
||||
Talk(SAY_NOVA);
|
||||
} else NovaTimer -= diff;
|
||||
if (IceboltTimer <= diff)
|
||||
{
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 40, true), SPELL_ICEBOLT);
|
||||
IceboltTimer = 11000+rand()%20000;
|
||||
} else IceboltTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_rage_winterchill()
|
||||
{
|
||||
new boss_rage_winterchill();
|
||||
}
|
||||
@@ -1,262 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Hyjal
|
||||
SD%Complete: 80
|
||||
SDComment: gossip text id's unknown
|
||||
SDCategory: Caverns of Time, Mount Hyjal
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_jaina_proudmoore
|
||||
npc_thrall
|
||||
npc_tyrande_whisperwind
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "hyjalAI.h"
|
||||
#include "Player.h"
|
||||
|
||||
#define GOSSIP_ITEM_BEGIN_ALLY "My companions and I are with you, Lady Proudmoore."
|
||||
#define GOSSIP_ITEM_ANETHERON "We are ready for whatever Archimonde might send our way, Lady Proudmoore."
|
||||
|
||||
#define GOSSIP_ITEM_BEGIN_HORDE "I am with you, Thrall."
|
||||
#define GOSSIP_ITEM_AZGALOR "We have nothing to fear."
|
||||
|
||||
#define GOSSIP_ITEM_RETREAT "We can't keep this up. Let's retreat!"
|
||||
|
||||
#define GOSSIP_ITEM_TYRANDE "Aid us in defending Nordrassil"
|
||||
#define ITEM_TEAR_OF_GODDESS 24494
|
||||
|
||||
#define GOSSIP_ITEM_GM1 "[GM] Toggle Debug Timers"
|
||||
|
||||
class npc_jaina_proudmoore : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_jaina_proudmoore() : CreatureScript("npc_jaina_proudmoore") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
hyjalAI* ai = CAST_AI(hyjalAI, creature->AI());
|
||||
switch (action)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF + 1:
|
||||
ai->StartEvent(player);
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 2:
|
||||
ai->FirstBossDead = true;
|
||||
ai->WaveCount = 9;
|
||||
ai->StartEvent(player);
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 3:
|
||||
ai->Retreat();
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF:
|
||||
ai->Debug = !ai->Debug;
|
||||
//TC_LOG_DEBUG("scripts", "HyjalAI - Debug mode has been toggled");
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
hyjalAI* ai = CAST_AI(hyjalAI, creature->AI());
|
||||
if (ai->EventBegun)
|
||||
return false;
|
||||
|
||||
uint32 RageEncounter = ai->GetInstanceData(DATA_RAGEWINTERCHILLEVENT);
|
||||
uint32 AnetheronEncounter = ai->GetInstanceData(DATA_ANETHERONEVENT);
|
||||
if (RageEncounter == NOT_STARTED)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEGIN_ALLY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
else if (RageEncounter == DONE && AnetheronEncounter == NOT_STARTED)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ANETHERON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
else if (RageEncounter == DONE && AnetheronEncounter == DONE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_RETREAT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
|
||||
if (player->IsGameMaster())
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_ITEM_GM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||
|
||||
player->SEND_GOSSIP_MENU(907, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
if (!creature->GetInstanceScript())
|
||||
return NULL;
|
||||
|
||||
hyjalAI* ai = new hyjalAI(creature);
|
||||
|
||||
ai->Reset();
|
||||
ai->EnterEvadeMode();
|
||||
|
||||
ai->Spells[0].SpellId = SPELL_BLIZZARD;
|
||||
ai->Spells[0].Cooldown = urand(15000, 35000);
|
||||
ai->Spells[0].TargetType = TARGETTYPE_RANDOM;
|
||||
|
||||
ai->Spells[1].SpellId = SPELL_PYROBLAST;
|
||||
ai->Spells[1].Cooldown = urand(5500, 9500);
|
||||
ai->Spells[1].TargetType = TARGETTYPE_RANDOM;
|
||||
|
||||
ai->Spells[2].SpellId = SPELL_SUMMON_ELEMENTALS;
|
||||
ai->Spells[2].Cooldown = urand(15000, 45000);
|
||||
ai->Spells[2].TargetType = TARGETTYPE_SELF;
|
||||
|
||||
return ai;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class npc_thrall : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_thrall() : CreatureScript("npc_thrall") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
hyjalAI* ai = CAST_AI(hyjalAI, creature->AI());
|
||||
ai->DeSpawnVeins();//despawn the alliance veins
|
||||
switch (action)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF + 1:
|
||||
ai->StartEvent(player);
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 2:
|
||||
ai->FirstBossDead = true;
|
||||
ai->WaveCount = 9;
|
||||
ai->StartEvent(player);
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 3:
|
||||
ai->Retreat();
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF:
|
||||
ai->Debug = !ai->Debug;
|
||||
//TC_LOG_DEBUG("scripts", "HyjalAI - Debug mode has been toggled");
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
hyjalAI* ai = CAST_AI(hyjalAI, creature->AI());
|
||||
if (ai->EventBegun)
|
||||
return false;
|
||||
|
||||
uint32 AnetheronEvent = ai->GetInstanceData(DATA_ANETHERONEVENT);
|
||||
// Only let them start the Horde phases if Anetheron is dead.
|
||||
if (AnetheronEvent == DONE && ai->GetInstanceData(DATA_ALLIANCE_RETREAT))
|
||||
{
|
||||
uint32 KazrogalEvent = ai->GetInstanceData(DATA_KAZROGALEVENT);
|
||||
uint32 AzgalorEvent = ai->GetInstanceData(DATA_AZGALOREVENT);
|
||||
if (KazrogalEvent == NOT_STARTED)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEGIN_HORDE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
else if (KazrogalEvent == DONE && AzgalorEvent == NOT_STARTED)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AZGALOR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
else if (AzgalorEvent == DONE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_RETREAT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
}
|
||||
|
||||
if (player->IsGameMaster())
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_ITEM_GM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||
|
||||
player->SEND_GOSSIP_MENU(907, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
if (!creature->GetInstanceScript())
|
||||
return NULL;
|
||||
|
||||
hyjalAI* ai = new hyjalAI(creature);
|
||||
|
||||
ai->Reset();
|
||||
ai->EnterEvadeMode();
|
||||
|
||||
ai->Spells[0].SpellId = SPELL_CHAIN_LIGHTNING;
|
||||
ai->Spells[0].Cooldown = urand(3000, 8000);
|
||||
ai->Spells[0].TargetType = TARGETTYPE_VICTIM;
|
||||
|
||||
ai->Spells[1].SpellId = SPELL_SUMMON_DIRE_WOLF;
|
||||
ai->Spells[1].Cooldown = urand(6000, 41000);
|
||||
ai->Spells[1].TargetType = TARGETTYPE_RANDOM;
|
||||
|
||||
return ai;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class npc_tyrande_whisperwind : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_tyrande_whisperwind() : CreatureScript("npc_tyrande_whisperwind") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
if (!creature->GetInstanceScript())
|
||||
return NULL;
|
||||
|
||||
hyjalAI* ai = new hyjalAI(creature);
|
||||
ai->Reset();
|
||||
ai->EnterEvadeMode();
|
||||
return ai;
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
if (action == GOSSIP_ACTION_INFO_DEF)
|
||||
{
|
||||
ItemPosCountVec dest;
|
||||
uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_TEAR_OF_GODDESS, 1);
|
||||
if (msg == EQUIP_ERR_OK)
|
||||
if (Item* item = player->StoreNewItem(dest, ITEM_TEAR_OF_GODDESS, true))
|
||||
player->SendNewItem(item, 1, true, false, true);
|
||||
|
||||
player->SEND_GOSSIP_MENU(907, creature->GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
hyjalAI* ai = CAST_AI(hyjalAI, creature->AI());
|
||||
uint32 AzgalorEvent = ai->GetInstanceData(DATA_AZGALOREVENT);
|
||||
|
||||
// Only let them get item if Azgalor is dead.
|
||||
if (AzgalorEvent == DONE && !player->HasItemCount(ITEM_TEAR_OF_GODDESS))
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_TYRANDE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||
player->SEND_GOSSIP_MENU(907, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void AddSC_hyjal()
|
||||
{
|
||||
new npc_jaina_proudmoore();
|
||||
new npc_thrall();
|
||||
new npc_tyrande_whisperwind();
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef DEF_HYJAL_H
|
||||
#define DEF_HYJAL_H
|
||||
|
||||
#define ERROR_INST_DATA "TSCR: Instance data not set properly for Mount Hyjal. Encounters will be buggy."
|
||||
|
||||
uint32 const EncounterCount = 5;
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
DATA_ANETHERON = 1,
|
||||
DATA_ANETHERONEVENT = 2,
|
||||
DATA_ARCHIMONDE = 3,
|
||||
DATA_ARCHIMONDEEVENT = 4,
|
||||
DATA_AZGALOR = 5,
|
||||
DATA_AZGALOREVENT = 6,
|
||||
DATA_JAINAPROUDMOORE = 7,
|
||||
DATA_KAZROGAL = 8,
|
||||
DATA_KAZROGALEVENT = 9,
|
||||
DATA_RAGEWINTERCHILL = 10,
|
||||
DATA_RAGEWINTERCHILLEVENT = 11,
|
||||
DATA_THRALL = 12,
|
||||
DATA_TYRANDEWHISPERWIND = 13,
|
||||
DATA_TRASH = 14,
|
||||
DATA_RESET_TRASH_COUNT = 15,
|
||||
DATA_ALLIANCE_RETREAT = 16,
|
||||
DATA_HORDE_RETREAT = 17,
|
||||
DATA_RAIDDAMAGE = 18,
|
||||
DATA_RESET_RAIDDAMAGE = 19,
|
||||
TYPE_RETREAT = 20
|
||||
};
|
||||
|
||||
enum WorldStateIds
|
||||
{
|
||||
WORLD_STATE_WAVES = 2842,
|
||||
WORLD_STATE_ENEMY = 2453,
|
||||
WORLD_STATE_ENEMYCOUNT = 2454
|
||||
};
|
||||
|
||||
enum CreaturesIds
|
||||
{
|
||||
// Trash Mobs summoned in waves
|
||||
NECROMANCER = 17899,
|
||||
ABOMINATION = 17898,
|
||||
GHOUL = 17895,
|
||||
BANSHEE = 17905,
|
||||
CRYPT_FIEND = 17897,
|
||||
GARGOYLE = 17906,
|
||||
FROST_WYRM = 17907,
|
||||
GIANT_INFERNAL = 17908,
|
||||
FEL_STALKER = 17916,
|
||||
|
||||
JAINA = 17772,
|
||||
THRALL = 17852,
|
||||
TYRANDE = 17948,
|
||||
|
||||
// Bosses summoned after every 8 waves
|
||||
RAGE_WINTERCHILL = 17767,
|
||||
ANETHERON = 17808,
|
||||
KAZROGAL = 17888,
|
||||
AZGALOR = 17842,
|
||||
ARCHIMONDE = 17968,
|
||||
NPC_WORLD_TRIGGER_TINY = 21987
|
||||
};
|
||||
|
||||
enum GameobjectIds
|
||||
{
|
||||
GO_HORDE_ENCAMPMENT_PORTAL = 182060,
|
||||
GO_NIGHT_ELF_VILLAGE_PORTAL = 182061,
|
||||
GO_ANCIENT_GEM = 185557,
|
||||
GO_ANCIENT_VEIN = 185557,
|
||||
GO_ROARING_FLAME = 182592
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef SC_HYJALAI_H
|
||||
#define SC_HYJALAI_H
|
||||
|
||||
#include "hyjal.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
|
||||
#define HYJAL_AI_MAX_SPELLS 3
|
||||
|
||||
enum SpellIds
|
||||
{
|
||||
SPELL_TELEPORT_VISUAL = 41232,
|
||||
SPELL_MASS_TELEPORT = 16807,
|
||||
|
||||
//Spells for Jaina
|
||||
SPELL_BRILLIANCE_AURA = 31260, // The database must handle this spell via creature_addon(it should, but is removed in evade..)
|
||||
SPELL_BLIZZARD = 31266,
|
||||
SPELL_PYROBLAST = 31263,
|
||||
SPELL_SUMMON_ELEMENTALS = 31264,
|
||||
|
||||
//Thrall spells
|
||||
SPELL_CHAIN_LIGHTNING = 31330,
|
||||
SPELL_SUMMON_DIRE_WOLF = 31331
|
||||
};
|
||||
|
||||
struct Wave
|
||||
{
|
||||
uint32 Mob[18]; // Stores Creature Entries to be summoned in Waves
|
||||
uint32 WaveTimer; // The timer before the next wave is summoned
|
||||
bool IsBoss; // Simply used to inform the wave summoner that the next wave contains a boss to halt all waves after that
|
||||
};
|
||||
|
||||
const Wave AllianceWaves[]= // Waves that will be summoned in the Alliance Base
|
||||
{ // Rage Winterchill Wave 1-8
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, 0, 0, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, 0, 0, 0, 0}, 180000, false},
|
||||
// All 8 Waves are summoned, summon Rage Winterchill, next few waves are for Anetheron
|
||||
{{RAGE_WINTERCHILL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, true},
|
||||
// Anetheron Wave 1-8
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, 0, 0, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, BANSHEE, BANSHEE, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, NECROMANCER, NECROMANCER, BANSHEE, BANSHEE, BANSHEE, BANSHEE, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, BANSHEE, BANSHEE, BANSHEE, BANSHEE, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, GHOUL, GHOUL, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0, 0, 0}, 180000, false},
|
||||
// All 8 Waves are summoned, summon Anatheron
|
||||
{{ANETHERON, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, true}
|
||||
};
|
||||
|
||||
const Wave HordeWaves[]= // Waves that are summoned in the Horde base
|
||||
{ // Kaz'Rogal Wave 1-8
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0}, 180000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, 0, 0, 0, 0}, 180000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, 0, 0, 0, 0}, 180000, false},
|
||||
{{CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, NECROMANCER, NECROMANCER, 0, 0, 0, 0}, 180000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0}, 180000, false},
|
||||
{{GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, FROST_WYRM, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 180000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, FROST_WYRM, 0, 0, 0, 0, 0, 0, 0}, 180000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0}, 240000, false},
|
||||
// All 8 Waves are summoned, summon Kaz'Rogal, next few waves are for Azgalor
|
||||
{{KAZROGAL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, true},
|
||||
// Azgalor Wave 1-8
|
||||
{{ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0}, 180000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, FROST_WYRM, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, 0, 0, 0, 0}, 180000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, 0, 0, 0, 0}, 180000, false},
|
||||
{{GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, 0, 0, 0, 0}, 180000, false},
|
||||
{{FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0}, 180000, false},
|
||||
{{NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, BANSHEE, BANSHEE, BANSHEE, BANSHEE, BANSHEE, BANSHEE, 0, 0, 0, 0, 0, 0}, 180000, false},
|
||||
{{GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, FEL_STALKER, FEL_STALKER, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, 0, 0, 0, 0}, 180000, false},
|
||||
{{CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, FEL_STALKER, FEL_STALKER, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, BANSHEE, BANSHEE, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0}, 240000, false},
|
||||
// All 8 Waves are summoned, summon Azgalor
|
||||
{{AZGALOR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, true}
|
||||
};
|
||||
|
||||
enum TargetType // Used in the spell cast system for the AI
|
||||
{
|
||||
TARGETTYPE_SELF = 0,
|
||||
TARGETTYPE_RANDOM = 1,
|
||||
TARGETTYPE_VICTIM = 2,
|
||||
};
|
||||
|
||||
enum YellId
|
||||
{
|
||||
ATTACKED = 0, // Used when attacked and set in combat
|
||||
BEGIN = 1, // Used when the event is begun
|
||||
INCOMING = 2, // Used to warn the raid that another wave phase is coming
|
||||
RALLY = 3, // Used to rally the raid and warn that the next wave has been summoned
|
||||
FAILURE = 4, // Used when raid has failed (unsure where to place)
|
||||
SUCCESS = 5, // Used when the raid has sucessfully defeated a wave phase
|
||||
DEATH = 6, // Used on death
|
||||
};
|
||||
|
||||
struct hyjalAI : public npc_escortAI
|
||||
{
|
||||
hyjalAI(Creature* creature);
|
||||
|
||||
void Reset(); // Generically used to reset our variables. Do *not* call in EnterEvadeMode as this may make problems if the raid is still in combat
|
||||
|
||||
void EnterEvadeMode(); // Send creature back to spawn location and evade.
|
||||
|
||||
void EnterCombat(Unit* /*who*/); // Used to reset cooldowns for our spells and to inform the raid that we're under attack
|
||||
|
||||
void UpdateAI(uint32 diff); // Called to summon waves, check for boss deaths and to cast our spells.
|
||||
|
||||
void JustDied(Unit* /*killer*/); // Called on death, informs the raid that they have failed.
|
||||
|
||||
void SetFaction(uint32 _faction) // Set the faction to either Alliance or Horde in Hyjal
|
||||
{
|
||||
Faction = _faction;
|
||||
}
|
||||
|
||||
void Retreat(); // "Teleport" (teleport visual + set invisible) all friendly creatures away from the base.
|
||||
|
||||
void SpawnVeins();
|
||||
void DeSpawnVeins();
|
||||
void JustSummoned(Creature* summoned);
|
||||
void SummonedCreatureDespawn(Creature* summoned);
|
||||
void HideNearPos(float x, float y);
|
||||
void RespawnNearPos(float x, float y);
|
||||
void WaypointReached(uint32 waypointId);
|
||||
void DoOverrun(uint32 faction, const uint32 diff);
|
||||
void MoveInLineOfSight(Unit* who);
|
||||
|
||||
void SummonCreature(uint32 entry, float Base[4][3]); // Summons a creature for that wave in that base
|
||||
|
||||
// Summons the next wave, calls SummonCreature
|
||||
void SummonNextWave(const Wave wave[18], uint32 Count, float Base[4][3]);
|
||||
|
||||
void StartEvent(Player* player); // Begins the event by gossip click
|
||||
|
||||
uint32 GetInstanceData(uint32 Event); // Gets instance data for this instance, used to check if raid has gotten past a certain point and can access the next phase
|
||||
|
||||
public:
|
||||
InstanceScript* instance;
|
||||
|
||||
uint64 PlayerGUID;
|
||||
uint64 BossGUID[2];
|
||||
uint64 VeinGUID[14];
|
||||
|
||||
uint32 NextWaveTimer;
|
||||
uint32 WaveCount;
|
||||
uint32 CheckTimer;
|
||||
uint32 Faction;
|
||||
uint32 EnemyCount;
|
||||
uint32 RetreatTimer;
|
||||
|
||||
bool EventBegun;
|
||||
bool FirstBossDead;
|
||||
bool SecondBossDead;
|
||||
bool Summon;
|
||||
bool bRetreat;
|
||||
bool Debug;
|
||||
bool VeinsSpawned[2];
|
||||
uint8 InfernalCount;
|
||||
SummonList Summons;
|
||||
bool Overrun;
|
||||
bool Teleported;
|
||||
bool WaitForTeleport;
|
||||
uint32 TeleportTimer;
|
||||
uint32 OverrunCounter;
|
||||
uint32 OverrunCounter2;
|
||||
uint32 InfernalPoint;
|
||||
uint32 RespawnTimer;
|
||||
bool DoRespawn;
|
||||
bool DoHide;
|
||||
bool IsDummy;
|
||||
uint32 MassTeleportTimer;
|
||||
bool DoMassTeleport;
|
||||
uint64 DummyGuid;
|
||||
|
||||
struct Spell
|
||||
{
|
||||
uint32 SpellId;
|
||||
uint32 Cooldown;
|
||||
uint32 TargetType;
|
||||
} Spells[HYJAL_AI_MAX_SPELLS];
|
||||
|
||||
private:
|
||||
uint32 SpellTimer[3];
|
||||
//std::list<uint64> CreatureList;
|
||||
};
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef SC_HYJAL_TRASH_AI_H
|
||||
#define SC_HYJAL_TRASH_AI_H
|
||||
|
||||
#include "hyjal.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
|
||||
#define MINRAIDDAMAGE 700000//minimal damage before trash can drop loot and reputation, resets if faction leader dies
|
||||
|
||||
struct hyjal_trashAI : public npc_escortAI
|
||||
{
|
||||
hyjal_trashAI(Creature* creature);
|
||||
|
||||
void UpdateAI(uint32 diff);
|
||||
|
||||
void JustDied(Unit* /*killer*/);
|
||||
|
||||
void DamageTaken(Unit* done_by, uint32 &damage, DamageEffectType, SpellSchoolMask);
|
||||
|
||||
public:
|
||||
InstanceScript* instance;
|
||||
bool IsEvent;
|
||||
uint32 Delay;
|
||||
uint32 LastOverronPos;
|
||||
bool IsOverrun;
|
||||
bool SetupOverrun;
|
||||
uint32 OverrunType;
|
||||
uint8 faction;
|
||||
bool useFlyPath;
|
||||
uint32 damageTaken;
|
||||
float DummyTarget[3];
|
||||
|
||||
//private:
|
||||
};
|
||||
#endif
|
||||
@@ -1,333 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Instance_Mount_Hyjal
|
||||
SD%Complete: 100
|
||||
SDComment: Instance Data Scripts and functions to acquire mobs and set encounter status for use in various Hyjal Scripts
|
||||
SDCategory: Caverns of Time, Mount Hyjal
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "hyjal_trash.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Chat.h"
|
||||
|
||||
/* Battle of Mount Hyjal encounters:
|
||||
0 - Rage Winterchill event
|
||||
1 - Anetheron event
|
||||
2 - Kaz'rogal event
|
||||
3 - Azgalor event
|
||||
4 - Archimonde event
|
||||
*/
|
||||
|
||||
#define YELL_EFFORTS "All of your efforts have been in vain, for the draining of the World Tree has already begun. Soon the heart of your world will beat no more."
|
||||
#define YELL_EFFORTS_NAME "Archimonde"
|
||||
|
||||
class instance_hyjal : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_hyjal() : InstanceMapScript("instance_hyjal", 534) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_mount_hyjal_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
struct instance_mount_hyjal_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_mount_hyjal_InstanceMapScript(Map* map) : InstanceScript(map) { }
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
|
||||
m_uiAncientGemGUID.clear();
|
||||
|
||||
RageWinterchill = 0;
|
||||
Anetheron = 0;
|
||||
Kazrogal = 0;
|
||||
Azgalor = 0;
|
||||
Archimonde = 0;
|
||||
JainaProudmoore = 0;
|
||||
Thrall = 0;
|
||||
TyrandeWhisperwind = 0;
|
||||
HordeGate = 0;
|
||||
ElfGate = 0;
|
||||
RaidDamage = 0;
|
||||
Trash = 0;
|
||||
hordeRetreat = 0;
|
||||
allianceRetreat = 0;
|
||||
|
||||
ArchiYell = false;
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
for (uint8 i = 0; i < EncounterCount; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go)
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_HORDE_ENCAMPMENT_PORTAL:
|
||||
HordeGate = go->GetGUID();
|
||||
if (allianceRetreat)
|
||||
HandleGameObject(0, true, go);
|
||||
else
|
||||
HandleGameObject(0, false, go);
|
||||
break;
|
||||
case GO_NIGHT_ELF_VILLAGE_PORTAL:
|
||||
ElfGate = go->GetGUID();
|
||||
if (hordeRetreat)
|
||||
HandleGameObject(0, true, go);
|
||||
else
|
||||
HandleGameObject(0, false, go);
|
||||
break;
|
||||
case GO_ANCIENT_GEM:
|
||||
m_uiAncientGemGUID.push_back(go->GetGUID());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case RAGE_WINTERCHILL: RageWinterchill = creature->GetGUID(); break;
|
||||
case ANETHERON: Anetheron = creature->GetGUID(); break;
|
||||
case KAZROGAL: Kazrogal = creature->GetGUID(); break;
|
||||
case AZGALOR: Azgalor = creature->GetGUID(); break;
|
||||
case ARCHIMONDE: Archimonde = creature->GetGUID(); break;
|
||||
case JAINA: JainaProudmoore = creature->GetGUID(); break;
|
||||
case THRALL: Thrall = creature->GetGUID(); break;
|
||||
case TYRANDE: TyrandeWhisperwind = creature->GetGUID(); break;
|
||||
}
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 identifier) const
|
||||
{
|
||||
switch (identifier)
|
||||
{
|
||||
case DATA_RAGEWINTERCHILL: return RageWinterchill;
|
||||
case DATA_ANETHERON: return Anetheron;
|
||||
case DATA_KAZROGAL: return Kazrogal;
|
||||
case DATA_AZGALOR: return Azgalor;
|
||||
case DATA_ARCHIMONDE: return Archimonde;
|
||||
case DATA_JAINAPROUDMOORE: return JainaProudmoore;
|
||||
case DATA_THRALL: return Thrall;
|
||||
case DATA_TYRANDEWHISPERWIND: return TyrandeWhisperwind;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_RAGEWINTERCHILLEVENT:
|
||||
m_auiEncounter[0] = data;
|
||||
break;
|
||||
case DATA_ANETHERONEVENT:
|
||||
m_auiEncounter[1] = data;
|
||||
break;
|
||||
case DATA_KAZROGALEVENT:
|
||||
m_auiEncounter[2] = data;
|
||||
break;
|
||||
case DATA_AZGALOREVENT:
|
||||
{
|
||||
m_auiEncounter[3] = data;
|
||||
if (data == DONE)
|
||||
{
|
||||
if (ArchiYell)
|
||||
break;
|
||||
|
||||
ArchiYell = true;
|
||||
|
||||
Creature* creature = instance->GetCreature(Azgalor);
|
||||
if (creature)
|
||||
{
|
||||
Creature* unit = creature->SummonCreature(NPC_WORLD_TRIGGER_TINY, creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000);
|
||||
|
||||
Map* map = creature->GetMap();
|
||||
if (map->IsDungeon() && unit)
|
||||
{
|
||||
unit->SetVisible(false);
|
||||
Map::PlayerList const &PlayerList = map->GetPlayers();
|
||||
if (PlayerList.isEmpty())
|
||||
return;
|
||||
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
{
|
||||
if (i->GetSource())
|
||||
{
|
||||
WorldPacket packet;
|
||||
ChatHandler::BuildChatPacket(packet, CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, unit, i->GetSource(), YELL_EFFORTS);
|
||||
i->GetSource()->GetSession()->SendPacket(&packet);
|
||||
|
||||
WorldPacket data2(SMSG_PLAY_SOUND, 4);
|
||||
data2 << 10986;
|
||||
i->GetSource()->GetSession()->SendPacket(&data2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DATA_ARCHIMONDEEVENT:
|
||||
m_auiEncounter[4] = data;
|
||||
break;
|
||||
case DATA_RESET_TRASH_COUNT:
|
||||
Trash = 0;
|
||||
break;
|
||||
case DATA_TRASH:
|
||||
if (data)
|
||||
Trash = data;
|
||||
else
|
||||
Trash--;
|
||||
DoUpdateWorldState(WORLD_STATE_ENEMYCOUNT, Trash);
|
||||
break;
|
||||
case TYPE_RETREAT:
|
||||
if (data == SPECIAL)
|
||||
{
|
||||
if (!m_uiAncientGemGUID.empty())
|
||||
{
|
||||
for (std::list<uint64>::const_iterator itr = m_uiAncientGemGUID.begin(); itr != m_uiAncientGemGUID.end(); ++itr)
|
||||
{
|
||||
//don't know how long it expected
|
||||
DoRespawnGameObject(*itr, DAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DATA_ALLIANCE_RETREAT:
|
||||
allianceRetreat = data;
|
||||
HandleGameObject(HordeGate, true);
|
||||
SaveToDB();
|
||||
break;
|
||||
case DATA_HORDE_RETREAT:
|
||||
hordeRetreat = data;
|
||||
HandleGameObject(ElfGate, true);
|
||||
SaveToDB();
|
||||
break;
|
||||
case DATA_RAIDDAMAGE:
|
||||
RaidDamage += data;
|
||||
if (RaidDamage >= MINRAIDDAMAGE)
|
||||
RaidDamage = MINRAIDDAMAGE;
|
||||
break;
|
||||
case DATA_RESET_RAIDDAMAGE:
|
||||
RaidDamage = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// TC_LOG_DEBUG("scripts", "Instance Hyjal: Instance data updated for event %u (Data=%u)", type, data);
|
||||
|
||||
if (data == DONE)
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' << m_auiEncounter[2] << ' '
|
||||
<< m_auiEncounter[3] << ' ' << m_auiEncounter[4]
|
||||
<< ' ' << allianceRetreat << ' ' << hordeRetreat
|
||||
<< ' ' << RaidDamage;
|
||||
|
||||
str_data = saveStream.str();
|
||||
|
||||
SaveToDB();
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_RAGEWINTERCHILLEVENT: return m_auiEncounter[0];
|
||||
case DATA_ANETHERONEVENT: return m_auiEncounter[1];
|
||||
case DATA_KAZROGALEVENT: return m_auiEncounter[2];
|
||||
case DATA_AZGALOREVENT: return m_auiEncounter[3];
|
||||
case DATA_ARCHIMONDEEVENT: return m_auiEncounter[4];
|
||||
case DATA_TRASH: return Trash;
|
||||
case DATA_ALLIANCE_RETREAT: return allianceRetreat;
|
||||
case DATA_HORDE_RETREAT: return hordeRetreat;
|
||||
case DATA_RAIDDAMAGE: return RaidDamage;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
return str_data;
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3] >> m_auiEncounter[4] >> allianceRetreat >> hordeRetreat >> RaidDamage;
|
||||
for (uint8 i = 0; i < EncounterCount; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as IN_PROGRESS - reset it instead.
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
protected:
|
||||
uint32 m_auiEncounter[EncounterCount];
|
||||
std::string str_data;
|
||||
std::list<uint64> m_uiAncientGemGUID;
|
||||
uint64 RageWinterchill;
|
||||
uint64 Anetheron;
|
||||
uint64 Kazrogal;
|
||||
uint64 Azgalor;
|
||||
uint64 Archimonde;
|
||||
uint64 JainaProudmoore;
|
||||
uint64 Thrall;
|
||||
uint64 TyrandeWhisperwind;
|
||||
uint64 HordeGate;
|
||||
uint64 ElfGate;
|
||||
uint32 Trash;
|
||||
uint32 hordeRetreat;
|
||||
uint32 allianceRetreat;
|
||||
uint32 RaidDamage;
|
||||
bool ArchiYell;
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_instance_mount_hyjal()
|
||||
{
|
||||
new instance_hyjal();
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
#include "SpellInfo.h"
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CURSE_OF_EXERTION = 52772,
|
||||
SPELL_WOUNDING_STRIKE_N = 52771,
|
||||
SPELL_WOUNDING_STRIKE_H = 58830,
|
||||
SPELL_TIME_STOP = 58848,
|
||||
SPELL_TIME_WARP = 52766,
|
||||
SPELL_TIME_STEP_N = 52737,
|
||||
SPELL_TIME_STEP_H = 58829,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_CURSE_OF_EXERTION = 1,
|
||||
EVENT_SPELL_WOUNDING_STRIKE = 2,
|
||||
EVENT_SPELL_TIME_STOP = 3,
|
||||
EVENT_SPELL_TIME_WARP = 4,
|
||||
EVENT_TIME_WARP = 5,
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_INTRO = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_TIME_WARP = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4
|
||||
};
|
||||
|
||||
class boss_epoch : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_epoch() : CreatureScript("boss_epoch") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_epochAI (creature);
|
||||
}
|
||||
|
||||
struct boss_epochAI : public ScriptedAI
|
||||
{
|
||||
boss_epochAI(Creature* c) : ScriptedAI(c)
|
||||
{
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
uint8 warps;
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
warps = 0;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_CURSE_OF_EXERTION, 9000);
|
||||
events.ScheduleEvent(EVENT_SPELL_WOUNDING_STRIKE, 3000);
|
||||
events.ScheduleEvent(EVENT_SPELL_TIME_WARP, 25000);
|
||||
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_SPELL_TIME_STOP, 20000);
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, const SpellInfo* spellInfo)
|
||||
{
|
||||
if (spellInfo->Id == SPELL_TIME_STEP_H || spellInfo->Id == SPELL_TIME_STEP_N)
|
||||
{
|
||||
if (target == me)
|
||||
return;
|
||||
|
||||
if (warps >= 2)
|
||||
{
|
||||
warps = 0;
|
||||
return;
|
||||
}
|
||||
warps++;
|
||||
me->CastSpell(target, DUNGEON_MODE(SPELL_TIME_STEP_N, SPELL_TIME_STEP_H), true);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_CURSE_OF_EXERTION:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
|
||||
me->CastSpell(target, SPELL_CURSE_OF_EXERTION, false);
|
||||
events.RepeatEvent(9000);
|
||||
break;
|
||||
case EVENT_SPELL_WOUNDING_STRIKE:
|
||||
me->CastSpell(me->GetVictim(), DUNGEON_MODE(SPELL_WOUNDING_STRIKE_N, SPELL_WOUNDING_STRIKE_H), false);
|
||||
events.RepeatEvent(6000);
|
||||
break;
|
||||
case EVENT_SPELL_TIME_STOP:
|
||||
me->CastSpell(me, SPELL_TIME_STOP, false);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_TIME_WARP:
|
||||
Talk(SAY_TIME_WARP);
|
||||
me->CastSpell(me, SPELL_TIME_WARP, false);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
|
||||
me->CastSpell(target, DUNGEON_MODE(SPELL_TIME_STEP_N, SPELL_TIME_STEP_H), true);
|
||||
|
||||
events.RepeatEvent(25000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (!urand(0,1))
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_epoch()
|
||||
{
|
||||
new boss_epoch();
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CORRUPTING_BLIGHT = 60588,
|
||||
SPELL_VOID_STRIKE = 60590,
|
||||
SPELL_CORRUPTION_OF_TIME_AURA = 60451,
|
||||
SPELL_CORRUPTION_OF_TIME_CHANNEL = 60422,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_CORRUPTING_BLIGHT = 1,
|
||||
EVENT_SPELL_VOID_STRIKE = 2,
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_DEATH = 1,
|
||||
SAY_FAIL = 2
|
||||
};
|
||||
|
||||
class boss_infinite_corruptor : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_infinite_corruptor() : CreatureScript("boss_infinite_corruptor") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_infinite_corruptorAI(creature);
|
||||
}
|
||||
|
||||
struct boss_infinite_corruptorAI : public ScriptedAI
|
||||
{
|
||||
boss_infinite_corruptorAI(Creature* c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
uint32 beamTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
if (InstanceScript* pInstance = me->GetInstanceScript())
|
||||
if (pInstance->GetData(DATA_GUARDIANTIME_EVENT) == 0)
|
||||
me->DespawnOrUnsummon(500);
|
||||
|
||||
me->SummonCreature(NPC_TIME_RIFT, 2337.6f, 1270.0f, 132.95f, 2.79f);
|
||||
me->SummonCreature(NPC_GUARDIAN_OF_TIME, 2319.3f, 1267.7f, 132.8f, 1.0f);
|
||||
beamTimer = 1;
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) { summons.Summon(cr); }
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
events.ScheduleEvent(EVENT_SPELL_VOID_STRIKE, 8000);
|
||||
events.ScheduleEvent(EVENT_SPELL_CORRUPTING_BLIGHT, 12000);
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, (*itr)))
|
||||
{
|
||||
if (cr->GetEntry() == NPC_TIME_RIFT)
|
||||
cr->DespawnOrUnsummon(1000);
|
||||
else
|
||||
{
|
||||
cr->DespawnOrUnsummon(5000);
|
||||
cr->RemoveAllAuras();
|
||||
cr->MonsterSay("You have my thanks for saving my existence in this timeline. Now i must report back to my superiors. They must know immediately of what i just experienced.", LANG_UNIVERSAL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (InstanceScript* pInstance = me->GetInstanceScript())
|
||||
pInstance->SetData(DATA_SHOW_INFINITE_TIMER, 0);
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (!me->IsAlive())
|
||||
return;
|
||||
|
||||
if (param == ACTION_RUN_OUT_OF_TIME)
|
||||
{
|
||||
Talk(SAY_FAIL);
|
||||
summons.DespawnAll();
|
||||
me->DespawnOrUnsummon(500);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (beamTimer)
|
||||
{
|
||||
beamTimer += diff;
|
||||
if (beamTimer >= 2000)
|
||||
{
|
||||
me->CastSpell(me, SPELL_CORRUPTION_OF_TIME_CHANNEL, true);
|
||||
beamTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_VOID_STRIKE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_VOID_STRIKE, false);
|
||||
events.RepeatEvent(8000);
|
||||
break;
|
||||
case EVENT_SPELL_CORRUPTING_BLIGHT:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
|
||||
me->CastSpell(target, SPELL_CORRUPTING_BLIGHT, false);
|
||||
events.RepeatEvent(12000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_infinite_corruptor()
|
||||
{
|
||||
new boss_infinite_corruptor();
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CARRION_SWARM_N = 52720,
|
||||
SPELL_CARRION_SWARM_H = 58852,
|
||||
SPELL_MIND_BLAST_N = 52722,
|
||||
SPELL_MIND_BLAST_H = 58850,
|
||||
SPELL_SLEEP_N = 52721,
|
||||
SPELL_SLEEP_H = 58849,
|
||||
SPELL_VAMPIRIC_TOUCH = 52723,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_CARRION_SWARM = 1,
|
||||
EVENT_SPELL_MIND_BLAST = 2,
|
||||
EVENT_SPELL_SLEEP = 3,
|
||||
EVENT_SPELL_VAMPIRIC_TOUCH = 4,
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 2,
|
||||
SAY_KILL = 3,
|
||||
SAY_SLAY = 4,
|
||||
SAY_SLEEP = 5,
|
||||
SAY_30HEALTH = 6,
|
||||
SAY_15HEALTH = 7,
|
||||
SAY_ESCAPE_SPEECH_1 = 8,
|
||||
SAY_ESCAPE_SPEECH_2 = 9,
|
||||
SAY_OUTRO = 10
|
||||
};
|
||||
|
||||
class boss_mal_ganis : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_mal_ganis() : CreatureScript("boss_mal_ganis") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_mal_ganisAI (creature);
|
||||
}
|
||||
|
||||
struct boss_mal_ganisAI : public ScriptedAI
|
||||
{
|
||||
boss_mal_ganisAI(Creature* c) : ScriptedAI(c)
|
||||
{
|
||||
finished = false;
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
bool finished;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);
|
||||
events.Reset();
|
||||
if (finished)
|
||||
{
|
||||
Talk(SAY_OUTRO);
|
||||
me->DespawnOrUnsummon(20000);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
events.ScheduleEvent(EVENT_SPELL_CARRION_SWARM, 6000);
|
||||
events.ScheduleEvent(EVENT_SPELL_MIND_BLAST, 11000);
|
||||
events.ScheduleEvent(EVENT_SPELL_SLEEP, 20000);
|
||||
events.ScheduleEvent(EVENT_SPELL_VAMPIRIC_TOUCH, 15000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (!urand(0,1))
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (!finished && damage >= me->GetHealth())
|
||||
{
|
||||
damage = 0;
|
||||
finished = true;
|
||||
me->SetRegeneratingHealth(false);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
if (InstanceScript* pInstance = me->GetInstanceScript())
|
||||
{
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetData64(DATA_ARTHAS)))
|
||||
cr->AI()->DoAction(ACTION_KILLED_MALGANIS);
|
||||
|
||||
// give credit to players
|
||||
me->CastSpell(me, 58630, true);
|
||||
}
|
||||
|
||||
// quest completion
|
||||
if (who)
|
||||
if (Player* player = who->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
player->RewardPlayerAndGroupAtEvent(31006, player); // Royal Escort quest, Mal'ganis bunny
|
||||
|
||||
EnterEvadeMode();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_CARRION_SWARM:
|
||||
me->CastSpell(me->GetVictim(), DUNGEON_MODE(SPELL_CARRION_SWARM_N, SPELL_CARRION_SWARM_H), false);
|
||||
events.RepeatEvent(7000);
|
||||
break;
|
||||
case EVENT_SPELL_MIND_BLAST:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
|
||||
me->CastSpell(target, DUNGEON_MODE(SPELL_MIND_BLAST_N, SPELL_MIND_BLAST_H), false);
|
||||
events.RepeatEvent(6000);
|
||||
break;
|
||||
case EVENT_SPELL_SLEEP:
|
||||
Talk(SAY_SLEEP);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
|
||||
me->CastSpell(target, DUNGEON_MODE(SPELL_SLEEP_N, SPELL_SLEEP_H), false);
|
||||
events.RepeatEvent(17000);
|
||||
break;
|
||||
case EVENT_SPELL_VAMPIRIC_TOUCH:
|
||||
me->CastSpell(me, SPELL_VAMPIRIC_TOUCH, true);
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_mal_ganis()
|
||||
{
|
||||
new boss_mal_ganis();
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CONSTRICTING_CHAINS_N = 52696,
|
||||
SPELL_CONSTRICTING_CHAINS_H = 58823,
|
||||
SPELL_DISEASE_EXPULSION_N = 52666,
|
||||
SPELL_DISEASE_EXPULSION_H = 58824,
|
||||
SPELL_FRENZY = 58841,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_CONSTRICTING_CHAINS = 1,
|
||||
EVENT_SPELL_DISEASE_EXPULSION = 2,
|
||||
EVENT_SPELL_FRENZY = 3,
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_SPAWN = 2,
|
||||
SAY_DEATH = 3
|
||||
};
|
||||
|
||||
class boss_meathook : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_meathook() : CreatureScript("boss_meathook") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_meathookAI (creature);
|
||||
}
|
||||
|
||||
struct boss_meathookAI : public ScriptedAI
|
||||
{
|
||||
boss_meathookAI(Creature* c) : ScriptedAI(c)
|
||||
{
|
||||
Talk(SAY_SPAWN);
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
void Reset() { events.Reset(); }
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
events.RescheduleEvent(EVENT_SPELL_CONSTRICTING_CHAINS, 15000);
|
||||
events.RescheduleEvent(EVENT_SPELL_DISEASE_EXPULSION, 4000);
|
||||
events.RescheduleEvent(EVENT_SPELL_FRENZY, 20000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (!urand(0,1))
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_DISEASE_EXPULSION:
|
||||
me->CastSpell(me, DUNGEON_MODE(SPELL_DISEASE_EXPULSION_N, SPELL_DISEASE_EXPULSION_H), false);
|
||||
events.RepeatEvent(6000);
|
||||
break;
|
||||
case EVENT_SPELL_FRENZY:
|
||||
me->CastSpell(me, SPELL_FRENZY, false);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_CONSTRICTING_CHAINS:
|
||||
if (Unit *pTarget = SelectTarget(SELECT_TARGET_BOTTOMAGGRO, 0, 50.0f, true))
|
||||
me->CastSpell(pTarget, DUNGEON_MODE(SPELL_CONSTRICTING_CHAINS_N, SPELL_CONSTRICTING_CHAINS_H), false);
|
||||
events.RepeatEvent(14000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_meathook()
|
||||
{
|
||||
new boss_meathook();
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
#include "SpellScript.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_SHADOW_BOLT_N = 57725,
|
||||
SPELL_SHADOW_BOLT_H = 58827,
|
||||
SPELL_STEAL_FLESH_CHANNEL = 52708,
|
||||
SPELL_STEAL_FLESH_TARGET = 52711,
|
||||
SPELL_STEAL_FLESH_CASTER = 52712,
|
||||
SPELL_SUMMON_GHOULS = 52451,
|
||||
SPELL_EXPLODE_GHOUL_N = 52480,
|
||||
SPELL_EXPLODE_GHOUL_H = 58825,
|
||||
SPELL_CURSE_OF_TWISTED_FAITH = 58845,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_SHADOW_BOLT = 1,
|
||||
EVENT_SPELL_STEAL_FLESH = 2,
|
||||
EVENT_SPELL_SUMMON_GHOULS = 3,
|
||||
EVENT_EXPLODE_GHOUL = 4,
|
||||
EVENT_SPELL_CURSE = 5,
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SPAWN = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_DEATH = 3,
|
||||
SAY_EXPLODE_GHOUL = 4,
|
||||
SAY_STEAL_FLESH = 5,
|
||||
SAY_SUMMON_GHOULS = 6
|
||||
};
|
||||
|
||||
class boss_salramm : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_salramm() : CreatureScript("boss_salramm") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_salrammAI (creature);
|
||||
}
|
||||
|
||||
struct boss_salrammAI : public ScriptedAI
|
||||
{
|
||||
boss_salrammAI(Creature* c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
Talk(SAY_SPAWN);
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) { summons.Summon(cr); }
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
events.ScheduleEvent(EVENT_SPELL_SHADOW_BOLT, 7000);
|
||||
events.ScheduleEvent(EVENT_SPELL_STEAL_FLESH, 11000);
|
||||
events.ScheduleEvent(EVENT_SPELL_SUMMON_GHOULS, 16000);
|
||||
events.ScheduleEvent(EVENT_EXPLODE_GHOUL, 22000);
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_SPELL_CURSE, 25000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
summons.DespawnAll();
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (!urand(0,1))
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void ExplodeGhoul()
|
||||
{
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, (*itr)))
|
||||
if (cr->IsAlive())
|
||||
{
|
||||
me->CastSpell(cr, DUNGEON_MODE(SPELL_EXPLODE_GHOUL_N, SPELL_EXPLODE_GHOUL_H), false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_SHADOW_BOLT:
|
||||
me->CastSpell(me->GetVictim(), DUNGEON_MODE(SPELL_SHADOW_BOLT_N, SPELL_SHADOW_BOLT_H), false);
|
||||
events.RepeatEvent(10000);
|
||||
break;
|
||||
case EVENT_SPELL_STEAL_FLESH:
|
||||
if (!urand(0,2))
|
||||
Talk(SAY_STEAL_FLESH);
|
||||
me->CastSpell(me->GetVictim(), SPELL_STEAL_FLESH_CHANNEL, false);
|
||||
events.RepeatEvent(12000);
|
||||
break;
|
||||
case EVENT_SPELL_SUMMON_GHOULS:
|
||||
if (!urand(0,2))
|
||||
Talk(SAY_SUMMON_GHOULS);
|
||||
me->CastSpell(me, SPELL_SUMMON_GHOULS, false);
|
||||
events.RepeatEvent(10000);
|
||||
break;
|
||||
case EVENT_EXPLODE_GHOUL:
|
||||
if (!urand(0,2))
|
||||
Talk(SAY_EXPLODE_GHOUL);
|
||||
ExplodeGhoul();
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
case EVENT_SPELL_CURSE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_CURSE_OF_TWISTED_FAITH, false);
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class spell_boss_salramm_steal_flesh : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_boss_salramm_steal_flesh() : SpellScriptLoader("spell_boss_salramm_steal_flesh") { }
|
||||
|
||||
class spell_boss_salramm_steal_flesh_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_boss_salramm_steal_flesh_AuraScript);
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
Unit* target = GetUnitOwner();
|
||||
if (caster)
|
||||
{
|
||||
caster->CastSpell(caster, SPELL_STEAL_FLESH_CASTER, true);
|
||||
caster->CastSpell(target, SPELL_STEAL_FLESH_TARGET, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_boss_salramm_steal_flesh_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_boss_salramm_steal_flesh_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_salramm()
|
||||
{
|
||||
new boss_salramm();
|
||||
new spell_boss_salramm_steal_flesh();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#ifndef DEF_CULLING_OF_STRATHOLME_H
|
||||
#define DEF_CULLING_OF_STRATHOLME_H
|
||||
|
||||
enum Data
|
||||
{
|
||||
DATA_ARTHAS_EVENT,
|
||||
DATA_GUARDIANTIME_EVENT,
|
||||
|
||||
// Communication
|
||||
DATA_SHOW_CRATES,
|
||||
DATA_CRATE_COUNT,
|
||||
DATA_START_WAVES,
|
||||
DATA_SHOW_INFINITE_TIMER,
|
||||
DATA_ARTHAS_REPOSITION,
|
||||
};
|
||||
|
||||
enum Data64
|
||||
{
|
||||
DATA_ARTHAS,
|
||||
DATA_INFINITE,
|
||||
DATA_SHKAF_GATE,
|
||||
DATA_EXIT_GATE,
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
NPC_MEATHOOK = 26529,
|
||||
NPC_SALRAMM = 26530,
|
||||
NPC_EPOCH = 26532,
|
||||
NPC_MAL_GANIS = 26533,
|
||||
NPC_INFINITE = 32273,
|
||||
NPC_ARTHAS = 26499,
|
||||
NPC_JAINA = 26497,
|
||||
NPC_UTHER = 26528,
|
||||
|
||||
NPC_GUARDIAN_OF_TIME = 32281,
|
||||
NPC_TIME_RIFT = 28409,
|
||||
|
||||
NPC_CHROMIE_MIDDLE = 27915,
|
||||
NPC_GRAIN_CREATE_TRIGGER = 30996,
|
||||
NPC_HOURGLASS = 28656,
|
||||
};
|
||||
|
||||
enum GameObjects
|
||||
{
|
||||
GO_SHKAF_GATE = 188686,
|
||||
GO_EXIT_GATE = 191788,
|
||||
GO_MALGANIS_CHEST_N = 190663,
|
||||
GO_MALGANIS_CHEST_H = 193597,
|
||||
GO_SUSPICIOUS_CRATE = 190094,
|
||||
GO_PLAGUED_CRATE = 190095,
|
||||
};
|
||||
|
||||
enum WorldStatesCoT
|
||||
{
|
||||
WORLDSTATE_SHOW_CRATES = 3479,
|
||||
WORLDSTATE_CRATES_REVEALED = 3480,
|
||||
WORLDSTATE_WAVE_COUNT = 3504,
|
||||
WORLDSTATE_TIME_GUARDIAN = 3931,
|
||||
WORLDSTATE_TIME_GUARDIAN_SHOW = 3932,
|
||||
};
|
||||
|
||||
enum CrateSpells
|
||||
{
|
||||
SPELL_CRATES_CREDIT = 58109,
|
||||
SPELL_ARCANE_DISRUPTION = 49590,
|
||||
|
||||
SPELL_HUMAN_FEMALE = 35483,
|
||||
SPELL_HUMAN_MALE = 35482,
|
||||
};
|
||||
|
||||
enum EventPositions
|
||||
{
|
||||
EVENT_POS_CHROMIE = 0,
|
||||
EVENT_POS_HOURGLASS = 1,
|
||||
EVENT_SRC_UTHER,
|
||||
EVENT_SRC_JAINA,
|
||||
EVENT_SRC_HORSE1,
|
||||
EVENT_SRC_HORSE2,
|
||||
EVENT_SRC_HORSE3,
|
||||
EVENT_DST_UTHER,
|
||||
EVENT_DST_HORSE1,
|
||||
EVENT_DST_HORSE2,
|
||||
EVENT_DST_HORSE3,
|
||||
EVENT_POS_RETREAT,
|
||||
EVENT_SRC_TOWN_CITYMAN1,
|
||||
EVENT_SRC_TOWN_CITYMAN2,
|
||||
EVENT_DST_CITYMAN,
|
||||
EVENT_SRC_MALGANIS,
|
||||
EVENT_SRC_MEATHOOK,
|
||||
EVENT_SRC_SALRAMM,
|
||||
EVENT_SRC_HALL_CITYMAN1,
|
||||
EVENT_SRC_HALL_CITYMAN2,
|
||||
EVENT_SRC_HALL_CITYMAN3,
|
||||
EVENT_SRC_EPOCH,
|
||||
EVENT_DST_EPOCH,
|
||||
EVENT_SRC_CORRUPTOR,
|
||||
EVENT_SRC_MALGANIS_FINAL,
|
||||
};
|
||||
|
||||
enum ArthasPhase
|
||||
{
|
||||
COS_PROGRESS_NOT_STARTED = 0,
|
||||
COS_PROGRESS_CRATES_FOUND = 1,
|
||||
COS_PROGRESS_START_INTRO = 2,
|
||||
COS_PROGRESS_FINISHED_INTRO = 3,
|
||||
COS_PROGRESS_FINISHED_CITY_INTRO = 4,
|
||||
COS_PROGRESS_KILLED_MEATHOOK = 5,
|
||||
COS_PROGRESS_KILLED_SALRAMM = 6,
|
||||
COS_PROGRESS_REACHED_TOWN_HALL = 7,
|
||||
COS_PROGRESS_KILLED_EPOCH = 8,
|
||||
COS_PROGRESS_LAST_CITY = 9,
|
||||
COS_PROGRESS_BEFORE_MALGANIS = 10,
|
||||
COS_PROGRESS_FINISHED = 11,
|
||||
};
|
||||
|
||||
enum Actions
|
||||
{
|
||||
ACTION_START_EVENT = 1,
|
||||
ACTION_START_CITY = 2,
|
||||
ACTION_KILLED_SALRAMM = 3,
|
||||
ACTION_START_TOWN_HALL = 4,
|
||||
ACTION_START_SECRET_PASSAGE = 5,
|
||||
ACTION_START_LAST_CITY = 6,
|
||||
ACTION_RUN_OUT_OF_TIME = 7,
|
||||
ACTION_START_MALGANIS = 8,
|
||||
ACTION_KILLED_MALGANIS = 9,
|
||||
};
|
||||
|
||||
const Position LeaderIntroPos1 = {1938.05f, 1289.79f, 145.38f, 3.18f};
|
||||
const Position LeaderIntroPos2 = {2050.66f, 1287.33f, 142.67f, M_PI};
|
||||
const Position LeaderIntroPos2special = {2092.15f, 1276.65f, 140.52f, 0.22f};
|
||||
const Position LeaderIntroPos3 = {2365.63f, 1194.84f, 131.97f, 0.0f};
|
||||
const Position LeaderIntroPos4 = {2423.12f, 1119.43f, 148.07f, 0.0f};
|
||||
const Position LeaderIntroPos5 = {2540.48f, 1129.06f, 130.86f, 0.0f};
|
||||
const Position LeaderIntroPos6 = {2327.39f, 1412.47f, 127.69f, 0.0f};
|
||||
|
||||
const Position EventPos[] =
|
||||
{
|
||||
{1813.298f, 1283.578f, 142.326f, 3.878161f}, // chromie
|
||||
{1809.46f, 1286.05f, 142.62f, 4.8f}, // hourglass
|
||||
{1795.76f, 1271.54f, 140.61f, 0.21f}, // source for uther
|
||||
{1895.48f, 1292.66f, 143.706f, 0.023475f}, // source for jaina
|
||||
{1788.38f, 1273.7f, 140.15f, 0.2f}, // source for horses
|
||||
{1788.76f, 1271.54f, 140.62f, 0.21f},
|
||||
{1788.74f, 1267.38f, 140.18f, 0.11f},
|
||||
{1897.6f, 1285.5f, 143.44f, 0.32f}, // dest for uther
|
||||
{1888.56f, 1289.95f, 143.8f, 0.01f}, // dest for horses
|
||||
{1888.94f, 1285.41f, 143.69f, 0.08f},
|
||||
{1889.55f, 1279.95f, 143.62f, 0.1f},
|
||||
{1751.9f, 1262.45f, 137.62f, 3.35f}, // retreat position after intro (uther + horses)
|
||||
{2091.977f, 1275.021f, 140.757f, 0.558f}, // source for town city man 1
|
||||
{2093.514f, 1275.842f, 140.408f, 3.801f}, // 2
|
||||
{2089.04f, 1277.98f, 140.85f, 2.35f}, // cityman dest pos
|
||||
{2117.349f, 1288.624f, 136.271f, 1.37f}, // malganis city intro
|
||||
{2351.45f, 1197.81f, 130.45f, 3.83f}, // meathook spawn position
|
||||
{2351.45f, 1197.81f, 130.45f, 3.83f}, // salramm spawn position
|
||||
{2398.14f, 1207.81f, 134.04f, 5.15f}, // source for hall city man 1
|
||||
{2403.22f, 1205.54f, 134.04f, 3.31f}, // 2
|
||||
{2400.82f, 1201.69f, 134.01f, 1.53f}, // 3
|
||||
{2463.131f, 1115.391f, 152.473f, 3.41f}, // epoch spawn position
|
||||
{2451.809f, 1112.901f, 149.220f, 3.36f}, // epoch move pos
|
||||
{2329.07f, 1276.98f, 132.68f, 4.0f}, // infinite corruptor pos
|
||||
{2298.25f, 1500.56f, 128.37f, 4.95f} // malganis final pos
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,422 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "CreatureTextMgr.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
#include "Player.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
class instance_culling_of_stratholme : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_culling_of_stratholme() : InstanceMapScript("instance_culling_of_stratholme", 595) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* pMap) const
|
||||
{
|
||||
return new instance_culling_of_stratholme_InstanceMapScript(pMap);
|
||||
}
|
||||
|
||||
struct instance_culling_of_stratholme_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_culling_of_stratholme_InstanceMapScript(Map* pMap) : InstanceScript(pMap)
|
||||
{
|
||||
// NPCs
|
||||
_arthasGUID = 0;
|
||||
_infiniteGUID = 0;
|
||||
|
||||
// GOs
|
||||
_shkafGateGUID = 0;
|
||||
_exitGateGUID = 0;
|
||||
|
||||
// Instance
|
||||
_crateCount = 0;
|
||||
_showCrateTimer = 0;
|
||||
_guardianTimer = 0;
|
||||
_respawnAndReposition = false;
|
||||
_encounterState = COS_PROGRESS_NOT_STARTED;
|
||||
_loadTimer = 0;
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void FillInitialWorldStates(WorldPacket& data)
|
||||
{
|
||||
data << uint32(WORLDSTATE_SHOW_CRATES) << uint32(0);
|
||||
data << uint32(WORLDSTATE_CRATES_REVEALED) << uint32(_crateCount);
|
||||
data << uint32(WORLDSTATE_WAVE_COUNT) << uint32(0);
|
||||
data << uint32(WORLDSTATE_TIME_GUARDIAN) << uint32(25);
|
||||
data << uint32(WORLDSTATE_TIME_GUARDIAN_SHOW) << uint32(0);
|
||||
}
|
||||
|
||||
void OnPlayerEnter(Player* plr)
|
||||
{
|
||||
if (instance->GetPlayersCountExceptGMs() == 1)
|
||||
SetData(DATA_ARTHAS_REPOSITION, 2);
|
||||
|
||||
EnsureGridLoaded();
|
||||
|
||||
if (plr->getRace() != RACE_HUMAN && plr->getRace() != RACE_DWARF && plr->getRace() != RACE_GNOME)
|
||||
plr->CastSpell(plr, ((plr->getGender() == GENDER_MALE) ? SPELL_HUMAN_MALE : SPELL_HUMAN_FEMALE), true);
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_ARTHAS:
|
||||
_arthasGUID = creature->GetGUID();
|
||||
if (_encounterState == COS_PROGRESS_FINISHED)
|
||||
creature->SetVisible(false);
|
||||
else
|
||||
Reposition(creature);
|
||||
break;
|
||||
case NPC_INFINITE:
|
||||
_infiniteGUID = creature->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go)
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_SHKAF_GATE:
|
||||
_shkafGateGUID = go->GetGUID();
|
||||
if (_encounterState >= COS_PROGRESS_KILLED_EPOCH)
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_EXIT_GATE:
|
||||
_exitGateGUID = go->GetGUID();
|
||||
if (_encounterState == COS_PROGRESS_FINISHED)
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_SHOW_CRATES:
|
||||
DoUpdateWorldState(WORLDSTATE_SHOW_CRATES, data);
|
||||
return;
|
||||
case DATA_SHOW_INFINITE_TIMER:
|
||||
if (!instance->IsHeroic() || !_guardianTimer)
|
||||
return;
|
||||
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN_SHOW, data);
|
||||
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN, uint32(_guardianTimer / (MINUTE*IN_MILLISECONDS)));
|
||||
if (data == 0)
|
||||
{
|
||||
_guardianTimer = 0;
|
||||
SaveToDB();
|
||||
}
|
||||
else if (!_infiniteGUID)
|
||||
instance->SummonCreature(NPC_INFINITE, EventPos[EVENT_SRC_CORRUPTOR]);
|
||||
return;
|
||||
case DATA_START_WAVES:
|
||||
DoUpdateWorldState(WORLDSTATE_WAVE_COUNT, 1);
|
||||
if (instance->IsHeroic())
|
||||
{
|
||||
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN_SHOW, true);
|
||||
_guardianTimer = 26*MINUTE*IN_MILLISECONDS;
|
||||
if (!_infiniteGUID)
|
||||
instance->SummonCreature(NPC_INFINITE, EventPos[EVENT_SRC_CORRUPTOR]);
|
||||
}
|
||||
return;
|
||||
case DATA_CRATE_COUNT:
|
||||
_crateCount++;
|
||||
if (_crateCount == 5)
|
||||
{
|
||||
Map::PlayerList const &PlayerList = instance->GetPlayers();
|
||||
if (!PlayerList.isEmpty())
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
i->GetSource()->KilledMonsterCredit(NPC_GRAIN_CREATE_TRIGGER, 0);
|
||||
|
||||
_showCrateTimer++;
|
||||
if (GetData(DATA_ARTHAS_EVENT) < COS_PROGRESS_CRATES_FOUND)
|
||||
SetData(DATA_ARTHAS_EVENT, COS_PROGRESS_CRATES_FOUND);
|
||||
}
|
||||
|
||||
DoUpdateWorldState(WORLDSTATE_CRATES_REVEALED, _crateCount);
|
||||
return;
|
||||
case DATA_ARTHAS_EVENT:
|
||||
// Start Event
|
||||
_encounterState = data;
|
||||
if (data == COS_PROGRESS_START_INTRO)
|
||||
{
|
||||
if (Creature *arthas = instance->GetCreature(_arthasGUID))
|
||||
arthas->AI()->DoAction(ACTION_START_EVENT);
|
||||
}
|
||||
else if (data == COS_PROGRESS_KILLED_SALRAMM)
|
||||
{
|
||||
if (Creature *arthas = instance->GetCreature(_arthasGUID))
|
||||
arthas->AI()->DoAction(ACTION_KILLED_SALRAMM);
|
||||
}
|
||||
break;
|
||||
case DATA_ARTHAS_REPOSITION:
|
||||
if (data == 2)
|
||||
_respawnAndReposition = true;
|
||||
else if (Creature *arthas = instance->GetCreature(_arthasGUID))
|
||||
Reposition(arthas);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (type == DATA_ARTHAS_EVENT)
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_ARTHAS_EVENT:
|
||||
return _encounterState;
|
||||
case DATA_GUARDIANTIME_EVENT:
|
||||
return _guardianTimer;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 identifier) const
|
||||
{
|
||||
switch (identifier)
|
||||
{
|
||||
case DATA_SHKAF_GATE:
|
||||
return _shkafGateGUID;
|
||||
case DATA_ARTHAS:
|
||||
return _arthasGUID;
|
||||
case DATA_EXIT_GATE:
|
||||
return _exitGateGUID;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Update(uint32 diff)
|
||||
{
|
||||
if (_loadTimer)
|
||||
{
|
||||
_loadTimer += diff;
|
||||
if (_loadTimer > 3000)
|
||||
{
|
||||
UpdateEventState();
|
||||
_loadTimer = 0;
|
||||
}
|
||||
}
|
||||
// Used when arthas dies
|
||||
if (_respawnAndReposition)
|
||||
{
|
||||
if (Creature *arthas = instance->GetCreature(_arthasGUID))
|
||||
{
|
||||
if (!arthas->IsAlive())
|
||||
{
|
||||
EnsureGridLoaded();
|
||||
arthas->setDeathState(DEAD);
|
||||
arthas->Respawn();
|
||||
}
|
||||
else
|
||||
{
|
||||
arthas->AI()->Reset();
|
||||
_respawnAndReposition = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Used after 5-th crates is revealed
|
||||
if (_showCrateTimer)
|
||||
{
|
||||
_showCrateTimer += diff;
|
||||
if (_showCrateTimer >= 20000)
|
||||
{
|
||||
UpdateEventState();
|
||||
_showCrateTimer = 0; // just to be sure
|
||||
}
|
||||
}
|
||||
|
||||
// Used to display how much time players have
|
||||
if (_guardianTimer)
|
||||
{
|
||||
uint32 div = uint32(_guardianTimer / (MINUTE*IN_MILLISECONDS));
|
||||
_guardianTimer -= diff;
|
||||
uint32 divAfter = uint32(_guardianTimer / (MINUTE*IN_MILLISECONDS));
|
||||
|
||||
if (divAfter == 0)
|
||||
{
|
||||
_guardianTimer = 0;
|
||||
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN_SHOW, 0);
|
||||
|
||||
// Inform infinite we run out of time
|
||||
if (instance->IsHeroic() && _infiniteGUID)
|
||||
if (Creature* cr = instance->GetCreature(_infiniteGUID))
|
||||
cr->AI()->DoAction(ACTION_RUN_OUT_OF_TIME);
|
||||
|
||||
}
|
||||
else if (div > divAfter)
|
||||
{
|
||||
if (divAfter == 5)
|
||||
ChromieWhisper(1);
|
||||
else if (divAfter == 1)
|
||||
ChromieWhisper(2);
|
||||
|
||||
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN, divAfter);
|
||||
SaveToDB();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateEventState()
|
||||
{
|
||||
if (_encounterState > COS_PROGRESS_NOT_STARTED)
|
||||
{
|
||||
// Summon Chromie and global whisper
|
||||
instance->SummonCreature(NPC_CHROMIE_MIDDLE, EventPos[EVENT_POS_CHROMIE]);
|
||||
instance->SummonCreature(NPC_HOURGLASS, EventPos[EVENT_POS_HOURGLASS]);
|
||||
|
||||
if (_encounterState == COS_PROGRESS_CRATES_FOUND ||
|
||||
_encounterState == COS_PROGRESS_START_INTRO)
|
||||
{
|
||||
ChromieWhisper(0);
|
||||
|
||||
// hide crates count
|
||||
DoUpdateWorldState(WORLDSTATE_SHOW_CRATES, 0);
|
||||
_showCrateTimer = 0;
|
||||
_encounterState = COS_PROGRESS_CRATES_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChromieWhisper(uint8 textId)
|
||||
{
|
||||
if (!instance->GetPlayers().isEmpty())
|
||||
if (Player* player = instance->GetPlayers().getFirst()->GetSource())
|
||||
{
|
||||
Position pos;
|
||||
player->GetPosition(&pos);
|
||||
if (Creature* cr = instance->SummonCreature(NPC_CHROMIE_MIDDLE, pos))
|
||||
{
|
||||
cr->SetVisible(false);
|
||||
cr->DespawnOrUnsummon(1000);
|
||||
sCreatureTextMgr->SendChat(cr, textId, player, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Reposition(Creature* arthas)
|
||||
{
|
||||
switch (GetData(DATA_ARTHAS_EVENT))
|
||||
{
|
||||
case COS_PROGRESS_FINISHED_INTRO:
|
||||
arthas->UpdatePosition(LeaderIntroPos2, true);
|
||||
arthas->SetHomePosition(LeaderIntroPos2);
|
||||
arthas->SetFacingTo(LeaderIntroPos2.GetOrientation());
|
||||
break;
|
||||
case COS_PROGRESS_FINISHED_CITY_INTRO:
|
||||
case COS_PROGRESS_KILLED_MEATHOOK:
|
||||
case COS_PROGRESS_KILLED_SALRAMM:
|
||||
arthas->UpdatePosition(LeaderIntroPos2special, true);
|
||||
arthas->SetHomePosition(LeaderIntroPos2special);
|
||||
arthas->SetFacingTo(LeaderIntroPos2special.GetOrientation());
|
||||
break;
|
||||
case COS_PROGRESS_REACHED_TOWN_HALL:
|
||||
arthas->UpdatePosition(LeaderIntroPos3, true);
|
||||
arthas->SetHomePosition(LeaderIntroPos3);
|
||||
arthas->SetFacingTo(LeaderIntroPos3.GetOrientation());
|
||||
break;
|
||||
case COS_PROGRESS_KILLED_EPOCH:
|
||||
arthas->UpdatePosition(LeaderIntroPos4, true);
|
||||
arthas->SetHomePosition(LeaderIntroPos4);
|
||||
arthas->SetFacingTo(LeaderIntroPos4.GetOrientation());
|
||||
break;
|
||||
case COS_PROGRESS_LAST_CITY:
|
||||
arthas->UpdatePosition(LeaderIntroPos5, true);
|
||||
arthas->SetHomePosition(LeaderIntroPos5);
|
||||
arthas->SetFacingTo(LeaderIntroPos5.GetOrientation());
|
||||
break;
|
||||
case COS_PROGRESS_BEFORE_MALGANIS:
|
||||
arthas->UpdatePosition(LeaderIntroPos6, true);
|
||||
arthas->SetHomePosition(LeaderIntroPos6);
|
||||
arthas->SetFacingTo(LeaderIntroPos6.GetOrientation());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EnsureGridLoaded()
|
||||
{
|
||||
instance->LoadGrid(LeaderIntroPos1.GetPositionX(), LeaderIntroPos1.GetPositionY());
|
||||
instance->LoadGrid(LeaderIntroPos2.GetPositionX(), LeaderIntroPos2.GetPositionY());
|
||||
instance->LoadGrid(LeaderIntroPos3.GetPositionX(), LeaderIntroPos3.GetPositionY());
|
||||
instance->LoadGrid(LeaderIntroPos4.GetPositionX(), LeaderIntroPos4.GetPositionY());
|
||||
instance->LoadGrid(LeaderIntroPos5.GetPositionX(), LeaderIntroPos5.GetPositionY());
|
||||
instance->LoadGrid(LeaderIntroPos6.GetPositionX(), LeaderIntroPos6.GetPositionY());
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "C S " << _encounterState << ' ' << _guardianTimer;
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
uint32 data0, data1;
|
||||
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1;
|
||||
|
||||
if (dataHead1 == 'C' && dataHead2 == 'S')
|
||||
{
|
||||
_encounterState = data0;
|
||||
_guardianTimer = data1;
|
||||
|
||||
//UpdateEventState();
|
||||
_loadTimer++;
|
||||
}
|
||||
else
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
private:
|
||||
// NPCs
|
||||
uint64 _arthasGUID;
|
||||
uint64 _infiniteGUID;
|
||||
|
||||
// GOs
|
||||
uint64 _shkafGateGUID;
|
||||
uint64 _exitGateGUID;
|
||||
uint32 _encounterState;
|
||||
uint32 _crateCount;
|
||||
uint32 _showCrateTimer;
|
||||
uint32 _guardianTimer;
|
||||
|
||||
bool _respawnAndReposition;
|
||||
uint32 _loadTimer;
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_instance_culling_of_stratholme()
|
||||
{
|
||||
new instance_culling_of_stratholme();
|
||||
}
|
||||
@@ -1,213 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "old_hillsbrad.h"
|
||||
|
||||
enum CaptainSkarloc
|
||||
{
|
||||
SAY_ENTER = 0,
|
||||
SAY_TAUNT = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_DEATH = 3,
|
||||
|
||||
SPELL_HOLY_LIGHT = 29427,
|
||||
SPELL_CLEANSE = 29380,
|
||||
SPELL_HAMMER_OF_JUSTICE = 13005,
|
||||
SPELL_HOLY_SHIELD = 31904,
|
||||
SPELL_DEVOTION_AURA = 8258,
|
||||
SPELL_CONSECRATION = 38385,
|
||||
|
||||
WAYPOINTS_COUNT = 4,
|
||||
|
||||
EVENT_INITIAL_TALK = 1,
|
||||
EVENT_START_FIGHT = 2,
|
||||
EVENT_SPELL_CLEANSE = 10,
|
||||
EVENT_SPELL_HAMMER = 11,
|
||||
EVENT_SPELL_HOLY_LIGHT = 12,
|
||||
EVENT_SPELL_HOLY_SHIELD = 13,
|
||||
EVENT_SPELL_CONSECRATION = 14
|
||||
};
|
||||
|
||||
const Position startPath[WAYPOINTS_COUNT] =
|
||||
{
|
||||
{2008.38f, 281.57f, 65.70f, 0.0f},
|
||||
{2035.71f, 271.38f, 63.495f, 0.0f},
|
||||
{2049.12f, 252.31f, 62.855f, 0.0f},
|
||||
{2058.77f, 236.04f, 63.92f, 0.0f}
|
||||
};
|
||||
|
||||
class boss_captain_skarloc : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_captain_skarloc() : CreatureScript("boss_captain_skarloc") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_captain_skarlocAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_captain_skarlocAI : public ScriptedAI
|
||||
{
|
||||
boss_captain_skarlocAI(Creature* creature) : ScriptedAI(creature), summons(me) { }
|
||||
|
||||
EventMap events;
|
||||
EventMap events2;
|
||||
SummonList summons;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
events2.Reset();
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
if (Creature* thrall = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetData64(DATA_THRALL_GUID)))
|
||||
thrall->AI()->JustSummoned(summon);
|
||||
summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
|
||||
if (summon->GetEntry() == NPC_SKARLOC_MOUNT)
|
||||
return;
|
||||
|
||||
if (summons.size() == 1)
|
||||
summon->GetMotionMaster()->MovePoint(0, 2060.788f, 237.301f, 63.999f);
|
||||
else
|
||||
summon->GetMotionMaster()->MovePoint(0, 2056.870f, 234.853f, 63.839f);
|
||||
}
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
ScriptedAI::InitializeAI();
|
||||
|
||||
Movement::PointsArray path;
|
||||
path.push_back(G3D::Vector3(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()));
|
||||
for (uint8 i = 0; i < WAYPOINTS_COUNT; ++i)
|
||||
path.push_back(G3D::Vector3(startPath[i].GetPositionX(), startPath[i].GetPositionY(), startPath[i].GetPositionZ()));
|
||||
|
||||
me->GetMotionMaster()->MoveSplinePath(&path);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->Mount(SKARLOC_MOUNT_MODEL);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type != ESCORT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
// Xinef: we can rely here on internal counting
|
||||
if (id == 1)
|
||||
{
|
||||
me->SummonCreature(NPC_DURNHOLDE_MAGE, 2038.549f, 273.303f, 63.420f, 5.30f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_VETERAN, 2032.810f, 269.416f, 63.561f, 5.30f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
}
|
||||
else if (id == 2)
|
||||
{
|
||||
me->SummonCreature(NPC_SKARLOC_MOUNT, 2049.12f, 252.31f, 62.855f, me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->Dismount();
|
||||
me->SetWalk(true);
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
|
||||
summon->SetWalk(true);
|
||||
}
|
||||
|
||||
if (me->movespline->Finalized())
|
||||
{
|
||||
events2.ScheduleEvent(EVENT_INITIAL_TALK, 500);
|
||||
events2.ScheduleEvent(EVENT_START_FIGHT, 8000);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
me->CastSpell(me, SPELL_DEVOTION_AURA, true);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_HOLY_LIGHT, 15000);
|
||||
events.ScheduleEvent(EVENT_SPELL_CLEANSE, 6000);
|
||||
events.ScheduleEvent(EVENT_SPELL_HAMMER, 20000);
|
||||
events.ScheduleEvent(EVENT_SPELL_HOLY_SHIELD, 10000);
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_SPELL_CONSECRATION, 1000);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
me->GetInstanceScript()->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_SKARLOC_KILLED);
|
||||
me->GetInstanceScript()->SetData(DATA_THRALL_ADD_FLAG, 0);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
events2.Update(diff);
|
||||
switch (events2.ExecuteEvent())
|
||||
{
|
||||
case EVENT_INITIAL_TALK:
|
||||
Talk(SAY_ENTER);
|
||||
break;
|
||||
case EVENT_START_FIGHT:
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->SetInCombatWithZone();
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
|
||||
if (summon->GetEntry() != NPC_SKARLOC_MOUNT)
|
||||
{
|
||||
summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
summon->SetInCombatWithZone();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_HOLY_LIGHT:
|
||||
me->CastSpell(me, SPELL_HOLY_LIGHT, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_HOLY_LIGHT, 20000);
|
||||
break;
|
||||
case EVENT_SPELL_CLEANSE:
|
||||
if (roll_chance_i(33))
|
||||
Talk(SAY_TAUNT);
|
||||
me->CastSpell(me, SPELL_CLEANSE, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_CLEANSE, 10000);
|
||||
break;
|
||||
case EVENT_SPELL_HAMMER:
|
||||
me->CastSpell(me->GetVictim(), SPELL_HAMMER_OF_JUSTICE, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_HAMMER, 30000);
|
||||
break;
|
||||
case EVENT_SPELL_HOLY_SHIELD:
|
||||
me->CastSpell(me, SPELL_CLEANSE, false);
|
||||
events.ScheduleEvent(SPELL_HOLY_SHIELD, 30000);
|
||||
break;
|
||||
case EVENT_SPELL_CONSECRATION:
|
||||
me->CastSpell(me, SPELL_CONSECRATION, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_CONSECRATION, 20000);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_captain_skarloc()
|
||||
{
|
||||
new boss_captain_skarloc();
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "old_hillsbrad.h"
|
||||
|
||||
|
||||
enum EpochHunter
|
||||
{
|
||||
SAY_AGGRO = 3,
|
||||
SAY_SLAY = 4,
|
||||
SAY_BREATH = 5,
|
||||
SAY_DEATH = 6,
|
||||
|
||||
SPELL_SAND_BREATH = 31914,
|
||||
SPELL_IMPENDING_DEATH = 31916,
|
||||
SPELL_MAGIC_DISRUPTION_AURA = 33834,
|
||||
SPELL_WING_BUFFET = 31475,
|
||||
|
||||
EVENT_SPELL_SAND_BREATH = 1,
|
||||
EVENT_SPELL_IMPENDING_DEATH = 2,
|
||||
EVENT_SPELL_DISRUPTION = 3,
|
||||
EVENT_SPELL_WING_BUFFET = 4
|
||||
};
|
||||
|
||||
class boss_epoch_hunter : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_epoch_hunter() : CreatureScript("boss_epoch_hunter") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_epoch_hunterAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_epoch_hunterAI : public ScriptedAI
|
||||
{
|
||||
boss_epoch_hunterAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_SAND_BREATH, 8000);
|
||||
events.ScheduleEvent(EVENT_SPELL_IMPENDING_DEATH, 2000);
|
||||
events.ScheduleEvent(EVENT_SPELL_DISRUPTION, 20000);
|
||||
events.ScheduleEvent(EVENT_SPELL_WING_BUFFET, 14000);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
if (killer == me)
|
||||
return;
|
||||
Talk(SAY_DEATH);
|
||||
me->GetInstanceScript()->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_EPOCH_KILLED);
|
||||
if (Creature* taretha = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetData64(DATA_TARETHA_GUID)))
|
||||
taretha->AI()->DoAction(me->GetEntry());
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_SAND_BREATH:
|
||||
if (roll_chance_i(50))
|
||||
Talk(SAY_BREATH);
|
||||
me->CastSpell(me->GetVictim(), SPELL_SAND_BREATH, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_SAND_BREATH, 20000);
|
||||
break;
|
||||
case EVENT_SPELL_IMPENDING_DEATH:
|
||||
me->CastSpell(me->GetVictim(), SPELL_IMPENDING_DEATH, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_IMPENDING_DEATH, 30000);
|
||||
break;
|
||||
case EVENT_SPELL_WING_BUFFET:
|
||||
me->CastSpell(me, SPELL_WING_BUFFET, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_WING_BUFFET, 30000);
|
||||
break;
|
||||
case EVENT_SPELL_DISRUPTION:
|
||||
me->CastSpell(me, SPELL_MAGIC_DISRUPTION_AURA, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_DISRUPTION, 30000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_epoch_hunter()
|
||||
{
|
||||
new boss_epoch_hunter();
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "old_hillsbrad.h"
|
||||
#include "MoveSplineInit.h"
|
||||
#include "SmartScriptMgr.h"
|
||||
|
||||
enum LieutenantDrake
|
||||
{
|
||||
SAY_ENTER = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_MORTAL = 3,
|
||||
SAY_SHOUT = 4,
|
||||
SAY_DEATH = 5,
|
||||
|
||||
SPELL_WHIRLWIND = 31909,
|
||||
SPELL_EXPLODING_SHOT = 33792,
|
||||
SPELL_HAMSTRING = 9080,
|
||||
SPELL_MORTAL_STRIKE = 31911,
|
||||
SPELL_FRIGHTENING_SHOUT = 33789,
|
||||
|
||||
EVENT_WHIRLWIND = 1,
|
||||
EVENT_FRIGHTENING_SHOUT = 2,
|
||||
EVENT_MORTAL_STRIKE = 3,
|
||||
EVENT_HAMSTRING = 4,
|
||||
EVENT_EXPLODING_SHOT = 5
|
||||
};
|
||||
|
||||
class boss_lieutenant_drake : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_lieutenant_drake() : CreatureScript("boss_lieutenant_drake") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_lieutenant_drakeAI(creature);
|
||||
}
|
||||
|
||||
struct boss_lieutenant_drakeAI : public ScriptedAI
|
||||
{
|
||||
boss_lieutenant_drakeAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
pathPoints.clear();
|
||||
WPPath* path = sSmartWaypointMgr->GetPath(me->GetEntry());
|
||||
if (!path || path->empty())
|
||||
return;
|
||||
|
||||
pathPoints.push_back(G3D::Vector3(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()));
|
||||
|
||||
uint32 wpCounter = 1;
|
||||
WPPath::const_iterator itr;
|
||||
while ((itr = path->find(wpCounter++)) != path->end())
|
||||
{
|
||||
WayPoint* wp = itr->second;
|
||||
pathPoints.push_back(G3D::Vector3(wp->x, wp->y, wp->z));
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
ScriptedAI::InitializeAI();
|
||||
//Talk(SAY_ENTER);
|
||||
JustReachedHome();
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
me->SetWalk(true);
|
||||
Movement::MoveSplineInit init(me);
|
||||
init.MovebyPath(pathPoints);
|
||||
init.SetCyclic();
|
||||
init.Launch();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_WHIRLWIND, 4000);
|
||||
events.ScheduleEvent(EVENT_FRIGHTENING_SHOUT, 14000);
|
||||
events.ScheduleEvent(EVENT_MORTAL_STRIKE, 9000);
|
||||
events.ScheduleEvent(EVENT_HAMSTRING, 18000);
|
||||
events.ScheduleEvent(EVENT_EXPLODING_SHOT, 1000);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
instance->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_DRAKE_KILLED);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_WHIRLWIND:
|
||||
me->CastSpell(me, SPELL_WHIRLWIND, false);
|
||||
events.ScheduleEvent(EVENT_WHIRLWIND, 25000);
|
||||
break;
|
||||
case EVENT_EXPLODING_SHOT:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 40.0f))
|
||||
me->CastSpell(target, SPELL_EXPLODING_SHOT, false);
|
||||
events.ScheduleEvent(EVENT_EXPLODING_SHOT, 25000);
|
||||
break;
|
||||
case EVENT_MORTAL_STRIKE:
|
||||
if (roll_chance_i(40))
|
||||
Talk(SAY_MORTAL);
|
||||
me->CastSpell(me->GetVictim(), SPELL_MORTAL_STRIKE, false);
|
||||
events.ScheduleEvent(EVENT_MORTAL_STRIKE, 10000);
|
||||
break;
|
||||
case EVENT_FRIGHTENING_SHOUT:
|
||||
if (roll_chance_i(40))
|
||||
Talk(SAY_SHOUT);
|
||||
me->CastSpell(me, SPELL_FRIGHTENING_SHOUT, false);
|
||||
events.ScheduleEvent(EVENT_FRIGHTENING_SHOUT, 25000);
|
||||
break;
|
||||
case EVENT_HAMSTRING:
|
||||
me->CastSpell(me->GetVictim(), SPELL_HAMSTRING, false);
|
||||
events.ScheduleEvent(EVENT_HAMSTRING, 25000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
Movement::PointsArray pathPoints;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_lieutenant_drake()
|
||||
{
|
||||
new boss_lieutenant_drake();
|
||||
}
|
||||
@@ -1,345 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "old_hillsbrad.h"
|
||||
#include "Player.h"
|
||||
|
||||
const Position instancePositions[INSTANCE_POSITIONS_COUNT] =
|
||||
{
|
||||
{2188.18f, 228.90f, 53.025f, 1.77f}, // Orcs Gather Point 1
|
||||
{2103.23f, 93.55f, 53.096f, 3.78f}, // Orcs Gather Point 2
|
||||
{2128.43f, 71.01f, 64.42f, 1.74f} // Lieutenant Drake Summon Position
|
||||
};
|
||||
|
||||
const Position thrallPositions[THRALL_POSITIONS_COUNT] =
|
||||
{
|
||||
{2181.37f, 119.15f, 89.45f, 5.75f}, // After wearing armor
|
||||
{2096.09f, 195.91f, 65.22f, 2.45f}, // After Fourth Ambush
|
||||
{2062.9f, 229.93f, 64.454f, 2.45f}, // After Captain Skarloc death
|
||||
{2486.91f, 626.356f, 58.0761f, 0.0f}, // Arrived at Tarren Mill
|
||||
{2660.47f, 659.223f, 62.0f, 5.78f} // Taretha Met
|
||||
|
||||
};
|
||||
|
||||
class instance_old_hillsbrad : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_old_hillsbrad() : InstanceMapScript("instance_old_hillsbrad", 560) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_old_hillsbrad_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
struct instance_old_hillsbrad_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_old_hillsbrad_InstanceMapScript(Map* map) : InstanceScript(map) { }
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_encounterProgress = 0;
|
||||
_barrelCount = 0;
|
||||
_attemptsCount = 0;
|
||||
|
||||
_thrallGUID = 0;
|
||||
_tarethaGUID = 0;
|
||||
|
||||
_initalFlamesSet.clear();
|
||||
_finalFlamesSet.clear();
|
||||
_prisonersSet.clear();
|
||||
_events.Reset();
|
||||
}
|
||||
|
||||
void OnPlayerEnter(Player* player)
|
||||
{
|
||||
if (instance->GetPlayersCountExceptGMs() == 1)
|
||||
CleanupInstance();
|
||||
|
||||
EnsureGridLoaded();
|
||||
|
||||
if (_encounterProgress < ENCOUNTER_PROGRESS_BARRELS)
|
||||
player->SendUpdateWorldState(WORLD_STATE_BARRELS_PLANTED, _barrelCount);
|
||||
}
|
||||
|
||||
void CleanupInstance()
|
||||
{
|
||||
if (_encounterProgress == ENCOUNTER_PROGRESS_NONE)
|
||||
return;
|
||||
|
||||
_events.ScheduleEvent(EVENT_INITIAL_BARRELS_FLAME, 0);
|
||||
_events.ScheduleEvent(EVENT_FINAL_BARRELS_FLAME, 0);
|
||||
|
||||
if (_encounterProgress == ENCOUNTER_PROGRESS_BARRELS)
|
||||
_events.ScheduleEvent(EVENT_SUMMON_LIEUTENANT, 0);
|
||||
else
|
||||
SetData(DATA_THRALL_REPOSITION, 2);
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_THRALL:
|
||||
_thrallGUID = creature->GetGUID();
|
||||
if (_encounterProgress == ENCOUNTER_PROGRESS_FINISHED)
|
||||
creature->SetVisible(false);
|
||||
else
|
||||
Reposition(creature);
|
||||
break;
|
||||
case NPC_ORC_PRISONER:
|
||||
_prisonersSet.insert(creature->GetGUID());
|
||||
break;
|
||||
case NPC_TARETHA:
|
||||
if (_encounterProgress == ENCOUNTER_PROGRESS_FINISHED)
|
||||
creature->SetVisible(false);
|
||||
_tarethaGUID = creature->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* gameobject)
|
||||
{
|
||||
switch (gameobject->GetEntry())
|
||||
{
|
||||
case GO_BARREL:
|
||||
if (_encounterProgress >= ENCOUNTER_PROGRESS_BARRELS)
|
||||
gameobject->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
break;
|
||||
case GO_PRISON_DOOR:
|
||||
if (_encounterProgress >= ENCOUNTER_PROGRESS_THRALL_ARMORED)
|
||||
gameobject->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_ROARING_FLAME:
|
||||
// Xinef: hack in DB to distinguish final / initial flames
|
||||
if (gameobject->GetPhaseMask() & 0x2)
|
||||
_finalFlamesSet.insert(gameobject->GetGUID());
|
||||
else
|
||||
_initalFlamesSet.insert(gameobject->GetGUID());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_THRALL_REPOSITION:
|
||||
if (data > 1)
|
||||
_events.ScheduleEvent(EVENT_THRALL_REPOSITION, data == 2 ? 0 : 10000);
|
||||
else if (Creature* thrall = instance->GetCreature(_thrallGUID))
|
||||
Reposition(thrall);
|
||||
return;
|
||||
case DATA_ESCORT_PROGRESS:
|
||||
_encounterProgress = data;
|
||||
SaveToDB();
|
||||
break;
|
||||
case DATA_BOMBS_PLACED:
|
||||
{
|
||||
if (_barrelCount >= 5 || _encounterProgress > ENCOUNTER_PROGRESS_NONE)
|
||||
return;
|
||||
|
||||
DoUpdateWorldState(WORLD_STATE_BARRELS_PLANTED, ++_barrelCount);
|
||||
if (_barrelCount == 5)
|
||||
{
|
||||
_events.ScheduleEvent(EVENT_INITIAL_BARRELS_FLAME, 4000);
|
||||
_events.ScheduleEvent(EVENT_FINAL_BARRELS_FLAME, 12000);
|
||||
_events.ScheduleEvent(EVENT_SUMMON_LIEUTENANT, 18000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DATA_THRALL_ADD_FLAG:
|
||||
if (Creature* thrall = instance->GetCreature(_thrallGUID))
|
||||
thrall->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 data) const
|
||||
{
|
||||
if (data == DATA_ESCORT_PROGRESS)
|
||||
return _encounterProgress;
|
||||
else if (data == DATA_ATTEMPTS_COUNT)
|
||||
return _attemptsCount;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 data) const
|
||||
{
|
||||
if (data == DATA_THRALL_GUID)
|
||||
return _thrallGUID;
|
||||
else if (data == DATA_TARETHA_GUID)
|
||||
return _tarethaGUID;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Update(uint32 diff)
|
||||
{
|
||||
_events.Update(diff);
|
||||
switch (_events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_INITIAL_BARRELS_FLAME:
|
||||
{
|
||||
instance->LoadGrid(instancePositions[0].GetPositionX(), instancePositions[0].GetPositionY());
|
||||
instance->LoadGrid(instancePositions[1].GetPositionX(), instancePositions[1].GetPositionY());
|
||||
|
||||
for (std::set<uint64>::const_iterator itr = _prisonersSet.begin(); itr != _prisonersSet.end(); ++itr)
|
||||
if (Creature* orc = instance->GetCreature(*itr))
|
||||
{
|
||||
uint8 index = orc->GetDistance(instancePositions[0]) < 80.0f ? 0 : 1;
|
||||
Position pos(instancePositions[index]);
|
||||
orc->MovePosition(pos, frand(1.0f, 3.0f) + 15.0f * (float)rand_norm(), (float)rand_norm() * static_cast<float>(2 * M_PI));
|
||||
orc->GetMotionMaster()->MovePoint(1, pos);
|
||||
orc->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
}
|
||||
|
||||
for (std::set<uint64>::const_iterator itr = _initalFlamesSet.begin(); itr != _initalFlamesSet.end(); ++itr)
|
||||
if (GameObject* gobject = instance->GetGameObject(*itr))
|
||||
{
|
||||
gobject->SetRespawnTime(0);
|
||||
gobject->UpdateObjectVisibility(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_FINAL_BARRELS_FLAME:
|
||||
{
|
||||
instance->LoadGrid(instancePositions[0].GetPositionX(), instancePositions[0].GetPositionY());
|
||||
instance->LoadGrid(instancePositions[1].GetPositionX(), instancePositions[1].GetPositionY());
|
||||
|
||||
if (_encounterProgress == ENCOUNTER_PROGRESS_NONE)
|
||||
{
|
||||
Map::PlayerList const& players = instance->GetPlayers();
|
||||
if (!players.isEmpty())
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
if (Player* player = itr->GetSource())
|
||||
player->KilledMonsterCredit(NPC_LODGE_QUEST_TRIGGER, 0);
|
||||
}
|
||||
|
||||
for (std::set<uint64>::const_iterator itr = _finalFlamesSet.begin(); itr != _finalFlamesSet.end(); ++itr)
|
||||
if (GameObject* gobject = instance->GetGameObject(*itr))
|
||||
{
|
||||
gobject->SetRespawnTime(0);
|
||||
gobject->UpdateObjectVisibility(true);
|
||||
}
|
||||
|
||||
for (std::set<uint64>::const_iterator itr = _prisonersSet.begin(); itr != _prisonersSet.end(); ++itr)
|
||||
if (Creature* orc = instance->GetCreature(*itr))
|
||||
if (roll_chance_i(25))
|
||||
orc->HandleEmoteCommand(EMOTE_ONESHOT_CHEER);
|
||||
|
||||
SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_BARRELS);
|
||||
DoUpdateWorldState(WORLD_STATE_BARRELS_PLANTED, 0);
|
||||
break;
|
||||
}
|
||||
case EVENT_SUMMON_LIEUTENANT:
|
||||
{
|
||||
instance->LoadGrid(instancePositions[2].GetPositionX(), instancePositions[2].GetPositionY());
|
||||
if (Creature* drake = instance->SummonCreature(NPC_LIEUTENANT_DRAKE, instancePositions[2]))
|
||||
drake->AI()->Talk(0);
|
||||
}
|
||||
case EVENT_THRALL_REPOSITION:
|
||||
{
|
||||
if (Creature* thrall = instance->GetCreature(_thrallGUID))
|
||||
{
|
||||
if (!thrall->IsAlive())
|
||||
{
|
||||
++_attemptsCount;
|
||||
EnsureGridLoaded();
|
||||
thrall->SetVisible(false);
|
||||
Reposition(thrall);
|
||||
thrall->setDeathState(DEAD);
|
||||
thrall->Respawn();
|
||||
thrall->SetVisible(true);
|
||||
SaveToDB();
|
||||
}
|
||||
else
|
||||
thrall->AI()->Reset();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Reposition(Creature* thrall)
|
||||
{
|
||||
switch (uint32 data = GetData(DATA_ESCORT_PROGRESS))
|
||||
{
|
||||
case ENCOUNTER_PROGRESS_THRALL_ARMORED:
|
||||
case ENCOUNTER_PROGRESS_AMBUSHES_1:
|
||||
case ENCOUNTER_PROGRESS_SKARLOC_KILLED:
|
||||
case ENCOUNTER_PROGRESS_TARREN_MILL:
|
||||
case ENCOUNTER_PROGRESS_TARETHA_MEET:
|
||||
thrall->UpdatePosition(thrallPositions[data - ENCOUNTER_PROGRESS_THRALL_ARMORED], true);
|
||||
thrall->SetHomePosition(thrallPositions[data - ENCOUNTER_PROGRESS_THRALL_ARMORED]);
|
||||
thrall->SetFacingTo(thrallPositions[data - ENCOUNTER_PROGRESS_THRALL_ARMORED].GetOrientation());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EnsureGridLoaded()
|
||||
{
|
||||
for (uint8 i = 0; i < THRALL_POSITIONS_COUNT; ++i)
|
||||
instance->LoadGrid(thrallPositions[i].GetPositionX(), thrallPositions[i].GetPositionY());
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "O H " << _encounterProgress << ' ' << _attemptsCount;
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
uint32 data0, data1;
|
||||
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1;
|
||||
|
||||
if (dataHead1 == 'O' && dataHead2 == 'H')
|
||||
{
|
||||
_encounterProgress = data0;
|
||||
_attemptsCount = data1;
|
||||
}
|
||||
else
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _encounterProgress;
|
||||
uint32 _barrelCount;
|
||||
uint32 _attemptsCount;
|
||||
|
||||
uint64 _thrallGUID;
|
||||
uint64 _tarethaGUID;
|
||||
std::set<uint64> _initalFlamesSet;
|
||||
std::set<uint64> _finalFlamesSet;
|
||||
std::set<uint64> _prisonersSet;
|
||||
|
||||
EventMap _events;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_instance_old_hillsbrad()
|
||||
{
|
||||
new instance_old_hillsbrad();
|
||||
}
|
||||
@@ -1,907 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "old_hillsbrad.h"
|
||||
#include "Player.h"
|
||||
|
||||
/*enum Erozion
|
||||
{
|
||||
QUEST_ENTRY_HILLSBRAD = 10282,
|
||||
QUEST_ENTRY_DIVERSION = 10283,
|
||||
QUEST_ENTRY_ESCAPE = 10284,
|
||||
QUEST_ENTRY_RETURN = 10285,
|
||||
ITEM_ENTRY_BOMBS = 25853
|
||||
};
|
||||
*/
|
||||
enum Says
|
||||
{
|
||||
SAY_START_EVENT_PART1 = 0,
|
||||
SAY_ARMORY = 1,
|
||||
SAY_SKARLOC_MEET = 2,
|
||||
SAY_SKARLOC_TAUNT = 3,
|
||||
SAY_START_EVENT_PART2 = 4,
|
||||
SAY_MOUNTS_UP = 5,
|
||||
SAY_CHURCH_END = 6,
|
||||
SAY_MEET_TARETHA = 7,
|
||||
SAY_EPOCH_WONDER = 8,
|
||||
SAY_EPOCH_KILL_TARETHA = 9,
|
||||
SAY_EVENT_COMPLETE = 10,
|
||||
SAY_RANDOM_LOW_HP = 11,
|
||||
SAY_RANDOM_DIE = 12,
|
||||
SAY_RANDOM_AGGRO = 13,
|
||||
SAY_RANDOM_KILL = 14,
|
||||
SAY_LEAVE_COMBAT = 15,
|
||||
SAY_KILL_ARMORER = 16,
|
||||
SAY_GO_ARMORED = 17,
|
||||
SAY_ENTER_CHURCH = 18,
|
||||
SAY_GREET_TARETHA = 19,
|
||||
SAY_CHAT_TARETHA1 = 20,
|
||||
|
||||
SAY_TARETHA_FREE = 0,
|
||||
SAY_TARETHA_ESCAPED = 1,
|
||||
SAY_TARETHA_TALK1 = 2,
|
||||
SAY_TARETHA_TALK2 = 3,
|
||||
|
||||
SAY_ARMORER_THRALL = 0,
|
||||
|
||||
SAY_LOOKOUT_SAW = 0,
|
||||
SAY_LOOKOUT_GO = 1,
|
||||
SAY_LOOKOUT_CHURCH = 2,
|
||||
SAY_LOOKOUT_INN = 3,
|
||||
|
||||
SAY_EPOCH_ENTER1 = 0,
|
||||
SAY_EPOCH_ENTER2 = 1,
|
||||
SAY_EPOCH_ENTER3 = 2,
|
||||
|
||||
SAY_EROZION_1 = 0,
|
||||
SAY_EROZION_2 = 1,
|
||||
SAY_EROZION_3 = 2,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_STRIKE = 14516,
|
||||
SPELL_SHIELD_BLOCK = 12169,
|
||||
SPELL_SUMMON_EROZION_IMAGE = 33954,
|
||||
|
||||
SPELL_SHADOW_PRISON = 33071,
|
||||
SPELL_SHADOW_SPIKE = 33125,
|
||||
|
||||
SPELL_TELEPORT = 34776,
|
||||
SPELL_MEMORY_WIPE = 33336,
|
||||
SPELL_MEMORY_WIPE_RESUME = 33337
|
||||
};
|
||||
|
||||
enum Npcs
|
||||
{
|
||||
NPC_TM_GUARDSMAN = 18092,
|
||||
NPC_TM_PROTECTOR = 18093,
|
||||
NPC_TM_LOOKOUT = 18094,
|
||||
|
||||
NPC_EPOCH_GUARDSMAN = 23175,
|
||||
NPC_EPOCH_PROTECTOR = 23179,
|
||||
NPC_EPOCH_LOOKOUT = 23177,
|
||||
|
||||
NPC_INFINITE_DEFILER = 18171,
|
||||
NPC_INFINITE_SABOTEUR = 18172,
|
||||
NPC_INFINITE_SLAYER = 18170
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
THRALL_WEAPON_ITEM = 927,
|
||||
THRALL_SHIELD_ITEM = 2129,
|
||||
THRALL_MODEL_UNEQUIPPED = 17292,
|
||||
THRALL_MODEL_EQUIPPED = 18165,
|
||||
|
||||
ACTION_SET_IMMUNE_FLAG = 1,
|
||||
ACTION_REMOVE_IMMUNE_FLAG = 2,
|
||||
ACTION_TRANSFORM = 3,
|
||||
ACTION_MOVE = 4,
|
||||
ACTION_START_COMBAT = 5
|
||||
};
|
||||
|
||||
#define SPEED_RUNNING 1.0f
|
||||
#define SPEED_MOUNTED 1.6f
|
||||
|
||||
enum Events
|
||||
{
|
||||
// Combat
|
||||
EVENT_CHECK_HEALTH = 1,
|
||||
EVENT_SPELL_STRIKE = 2,
|
||||
EVENT_SPELL_SHIELD_BLOCK = 3,
|
||||
|
||||
EVENT_OPEN_DOORS = 6,
|
||||
EVENT_START_WP = 7,
|
||||
|
||||
EVENT_SET_FACING = 9,
|
||||
EVENT_KILL_ARMORER = 10,
|
||||
EVENT_TALK_KILL_ARMORER = 11,
|
||||
|
||||
EVENT_DRESSING_KNEEL = 20,
|
||||
EVENT_DRESSING_ARMOR = 21,
|
||||
EVENT_DRESSING_STAND = 22,
|
||||
EVENT_DRESSING_AXE = 23,
|
||||
EVENT_DRESSING_SHIELD = 24,
|
||||
EVENT_DRESSING_TALK = 25,
|
||||
|
||||
EVENT_ENTER_MOUNT = 30,
|
||||
EVENT_TALK_START_RIDE = 31,
|
||||
|
||||
EVENT_LOOK_1 = 40,
|
||||
EVENT_MOVE_AROUND = 41,
|
||||
EVENT_LOOK_2 = 42,
|
||||
EVENT_LOOK_3 = 43,
|
||||
EVENT_SUMMON_GUARDS = 44,
|
||||
EVENT_SUMMON_TALK1 = 45,
|
||||
EVENT_SUMMON_TALK2 = 46,
|
||||
|
||||
EVENT_LOOK_4 = 50,
|
||||
EVENT_SUMMON_GUARDS_2 = 51,
|
||||
EVENT_SUMMON_TALK3 = 52,
|
||||
|
||||
EVENT_THRALL_TALK = 60,
|
||||
EVENT_SUMMON_CHRONO = 61,
|
||||
EVENT_THRALL_TALK_2 = 62,
|
||||
EVENT_TARETHA_FALL = 63,
|
||||
EVENT_THRALL_TALK_3 = 64,
|
||||
EVENT_THRALL_MOVE_DOWN = 65,
|
||||
|
||||
EVENT_EPOCH_INTRO = 70,
|
||||
EVENT_SUMMON_INFINITES = 71,
|
||||
EVENT_TRANSFORM = 72,
|
||||
EVENT_START_WAVE_1 = 73,
|
||||
EVENT_CHECK_WAVE_1 = 74,
|
||||
EVENT_CHECK_WAVE_2 = 75,
|
||||
EVENT_CHECK_WAVE_3 = 76,
|
||||
EVENT_CALL_EPOCH = 77,
|
||||
|
||||
EVENT_THRALL_FACE_TARETHA = 80,
|
||||
EVENT_THRALL_TALK_4 = 81,
|
||||
EVENT_TARETHA_TALK_1 = 82,
|
||||
EVENT_THRALL_TALK_5 = 83,
|
||||
EVENT_SUMMON_EROZION = 84,
|
||||
EVENT_EROZION_TALK_1 = 85,
|
||||
EVENT_EROZION_ACTION_1 = 86,
|
||||
EVENT_EROZION_TALK_2 = 87,
|
||||
EVENT_EROZION_ACTION_2 = 88,
|
||||
EVENT_EROZION_TALK_3 = 89,
|
||||
EVENT_THRALL_TALK_6 = 90,
|
||||
EVENT_THRALL_RUN_AWAY = 91,
|
||||
EVENT_TARETHA_TALK_2 = 92
|
||||
|
||||
};
|
||||
|
||||
class npc_thrall_old_hillsbrad : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_thrall_old_hillsbrad() : CreatureScript("npc_thrall_old_hillsbrad") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_thrall_old_hillsbradAI>(creature);
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
InstanceScript* instance = creature->GetInstanceScript();
|
||||
if (!instance)
|
||||
return true;
|
||||
|
||||
uint32 menuId = creature->GetCreatureTemplate()->GossipMenuId;
|
||||
if (instance->GetData(DATA_ESCORT_PROGRESS) == ENCOUNTER_PROGRESS_SKARLOC_KILLED)
|
||||
menuId = 7830;
|
||||
else if (instance->GetData(DATA_ESCORT_PROGRESS) == ENCOUNTER_PROGRESS_TARREN_MILL)
|
||||
menuId = 7840;
|
||||
else if (instance->GetData(DATA_ESCORT_PROGRESS) == ENCOUNTER_PROGRESS_TARETHA_MEET)
|
||||
menuId = 7853;
|
||||
|
||||
player->PrepareGossipMenu(creature, menuId, true);
|
||||
player->SendPreparedGossip(creature);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action)
|
||||
{
|
||||
GossipMenuItemData const* gossipMenuItemData = player->PlayerTalkClass->GetGossipMenu().GetItemData(0);
|
||||
InstanceScript* instance = creature->GetInstanceScript();
|
||||
if (!instance || (gossipMenuItemData && gossipMenuItemData->GossipActionMenuId != 0))
|
||||
return false;
|
||||
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
|
||||
creature->AI()->DoAction(instance->GetData(DATA_ESCORT_PROGRESS));
|
||||
creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct npc_thrall_old_hillsbradAI : public npc_escortAI
|
||||
{
|
||||
npc_thrall_old_hillsbradAI(Creature* creature) : npc_escortAI(creature), summons(me)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
switch (param)
|
||||
{
|
||||
case ENCOUNTER_PROGRESS_DRAKE_KILLED:
|
||||
events.ScheduleEvent(EVENT_OPEN_DOORS, 0);
|
||||
events.ScheduleEvent(EVENT_START_WP, 3000);
|
||||
break;
|
||||
case ENCOUNTER_PROGRESS_THRALL_ARMORED:
|
||||
case ENCOUNTER_PROGRESS_AMBUSHES_1:
|
||||
case ENCOUNTER_PROGRESS_SKARLOC_KILLED:
|
||||
case ENCOUNTER_PROGRESS_TARREN_MILL:
|
||||
SetEscortPaused(false);
|
||||
break;
|
||||
case ENCOUNTER_PROGRESS_TARETHA_MEET:
|
||||
events.ScheduleEvent(EVENT_SUMMON_CHRONO, 0);
|
||||
events.ScheduleEvent(EVENT_THRALL_TALK_2, 6000);
|
||||
events.ScheduleEvent(EVENT_TARETHA_FALL, 11000);
|
||||
events.ScheduleEvent(EVENT_THRALL_TALK_3, 14000);
|
||||
events.ScheduleEvent(EVENT_THRALL_MOVE_DOWN, 17000);
|
||||
break;
|
||||
case NPC_TARETHA:
|
||||
events.ScheduleEvent(EVENT_THRALL_FACE_TARETHA, 0);
|
||||
events.ScheduleEvent(EVENT_THRALL_TALK_4, 4000);
|
||||
events.ScheduleEvent(EVENT_TARETHA_TALK_1, 13000);
|
||||
events.ScheduleEvent(EVENT_THRALL_TALK_5, 17000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_EROZION, 17500);
|
||||
events.ScheduleEvent(EVENT_EROZION_TALK_1, 18000);
|
||||
events.ScheduleEvent(EVENT_EROZION_ACTION_1, 26000);
|
||||
events.ScheduleEvent(EVENT_EROZION_TALK_2, 29000);
|
||||
events.ScheduleEvent(EVENT_EROZION_TALK_3, 42000);
|
||||
events.ScheduleEvent(EVENT_EROZION_ACTION_2, 47000);
|
||||
events.ScheduleEvent(EVENT_THRALL_TALK_6, 48000);
|
||||
events.ScheduleEvent(EVENT_THRALL_RUN_AWAY, 51000);
|
||||
events.ScheduleEvent(EVENT_TARETHA_TALK_2, 53000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WaypointStart(uint32 waypointId)
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 30:
|
||||
Talk(SAY_START_EVENT_PART2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 0:
|
||||
Talk(SAY_START_EVENT_PART1);
|
||||
break;
|
||||
case 8:
|
||||
events.ScheduleEvent(EVENT_SET_FACING, 500);
|
||||
break;
|
||||
case 9:
|
||||
SetRun(false);
|
||||
events.ScheduleEvent(EVENT_KILL_ARMORER, 500);
|
||||
events.ScheduleEvent(EVENT_TALK_KILL_ARMORER, 4000);
|
||||
break;
|
||||
case 10:
|
||||
SetRun(true);
|
||||
events.ScheduleEvent(EVENT_DRESSING_KNEEL, 500);
|
||||
events.ScheduleEvent(EVENT_DRESSING_ARMOR, 3000);
|
||||
events.ScheduleEvent(EVENT_DRESSING_STAND, 4000);
|
||||
events.ScheduleEvent(EVENT_DRESSING_AXE, 7000);
|
||||
events.ScheduleEvent(EVENT_DRESSING_SHIELD, 9000);
|
||||
events.ScheduleEvent(EVENT_DRESSING_TALK, 12000);
|
||||
break;
|
||||
case 13:
|
||||
me->SummonCreature(NPC_DURNHOLDE_SENTRY, 2200.28f, 137.37f, 87.93f, 5.07f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_SENTRY, 2197.44f, 131.83f, 87.93f, 0.78f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_MAGE, 2203.62f, 135.40f, 87.93f, 3.70f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_VETERAN, 2200.75f, 130.13f, 87.93f, 1.48f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
break;
|
||||
case 16:
|
||||
me->SummonCreature(NPC_DURNHOLDE_SENTRY, 2147.43f, 122.194f, 76.422f, 0.67f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_SENTRY, 2146.27f, 126.13f, 76.241f, 0.60f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_MAGE, 2142.62f, 120.38f, 75.862f, 0.48f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_VETERAN, 2141.74f, 123.95f, 75.732f, 0.24f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
break;
|
||||
case 18:
|
||||
me->SummonCreature(NPC_DURNHOLDE_SENTRY, 2138.37f, 167.98f, 66.23f, 2.59f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_WARDEN, 2142.76f, 173.62f, 66.23f, 2.59f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_MAGE, 2140.96f, 168.64f, 66.23f, 2.59f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_VETERAN, 2142.53f, 171.03f, 66.23f, 2.59f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
break;
|
||||
case 22:
|
||||
me->SummonCreature(NPC_DURNHOLDE_SENTRY, 2108.73f, 190.43f, 66.23f, 5.56f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_MAGE, 2109.74f, 195.29f, 66.23f, 5.56f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_MAGE, 2107.74f, 192.59f, 66.23f, 5.56f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_SENTRY, 2112.26f, 195.13f, 66.23f, 5.56f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
break;
|
||||
case 27:
|
||||
instance->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_AMBUSHES_1);
|
||||
break;
|
||||
case 28:
|
||||
me->SummonCreature(NPC_CAPTAIN_SKARLOC, 1995.78f, 277.46f, 66.64f, 0.74f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
break;
|
||||
case 29:
|
||||
SetEscortPaused(true);
|
||||
Talk(SAY_SKARLOC_MEET);
|
||||
break;
|
||||
case 30:
|
||||
events.ScheduleEvent(EVENT_ENTER_MOUNT, 3000);
|
||||
events.ScheduleEvent(EVENT_TALK_START_RIDE, 7000);
|
||||
break;
|
||||
case 59:
|
||||
instance->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_TARREN_MILL);
|
||||
me->SummonCreature(NPC_SKARLOC_MOUNT, 2488.64f, 625.77f, 58.26f, 4.71f, TEMPSUMMON_TIMED_DESPAWN, 7000);
|
||||
UnMountSelf();
|
||||
_mounted = false;
|
||||
SetRun(false);
|
||||
break;
|
||||
case 60:
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
|
||||
if (Creature* horse = me->FindNearestCreature(NPC_SKARLOC_MOUNT, 10.0f))
|
||||
horse->GetMotionMaster()->MovePoint(0, 2501.15f, 572.14f, 54.13f);
|
||||
|
||||
SetEscortPaused(true);
|
||||
SetRun(true);
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
break;
|
||||
case 64:
|
||||
SetRun(false);
|
||||
break;
|
||||
case 67:
|
||||
events.ScheduleEvent(EVENT_LOOK_1, 500);
|
||||
events.ScheduleEvent(EVENT_MOVE_AROUND, 3500);
|
||||
events.ScheduleEvent(EVENT_LOOK_2, 5000);
|
||||
events.ScheduleEvent(EVENT_LOOK_3, 6700);
|
||||
events.ScheduleEvent(EVENT_SUMMON_GUARDS, 6000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_TALK1, 6500);
|
||||
events.ScheduleEvent(EVENT_SUMMON_TALK2, 12000);
|
||||
break;
|
||||
case 82:
|
||||
events.ScheduleEvent(EVENT_LOOK_4, 500);
|
||||
events.ScheduleEvent(EVENT_SUMMON_GUARDS_2, 1000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_TALK3, 1500);
|
||||
break;
|
||||
case 91:
|
||||
me->SummonCreature(NPC_TM_PROTECTOR, 2652.71f, 660.31f, 61.93f, 1.67f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_LOOKOUT, 2648.96f, 662.59f, 61.93f, 0.79f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_GUARDSMAN, 2657.36f, 662.34f, 61.93f, 2.68f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_GUARDSMAN, 2656.39f, 659.77f, 61.93f, 2.61f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
if (Creature* summon = summons.GetCreatureWithEntry(NPC_TM_LOOKOUT))
|
||||
summon->AI()->Talk(SAY_LOOKOUT_INN);
|
||||
break;
|
||||
case 92:
|
||||
SetRun(false);
|
||||
break;
|
||||
case 94:
|
||||
summons.DespawnAll();
|
||||
SetEscortPaused(true);
|
||||
SetRun(true);
|
||||
instance->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_TARETHA_MEET);
|
||||
if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TARETHA_GUID)))
|
||||
Taretha->AI()->Talk(SAY_TARETHA_ESCAPED);
|
||||
events.ScheduleEvent(EVENT_THRALL_TALK, 2000);
|
||||
break;
|
||||
case 101:
|
||||
SetEscortPaused(true);
|
||||
events.ScheduleEvent(EVENT_EPOCH_INTRO, 500);
|
||||
events.ScheduleEvent(EVENT_SUMMON_INFINITES, 1500);
|
||||
events.ScheduleEvent(EVENT_TRANSFORM, 8000);
|
||||
events.ScheduleEvent(EVENT_START_WAVE_1, 25000);
|
||||
break;
|
||||
case 103:
|
||||
if (Creature* erozion = summons.GetCreatureWithEntry(NPC_EROZION))
|
||||
erozion->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
instance->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_FINISHED);
|
||||
me->SetVisible(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MountSelf()
|
||||
{
|
||||
me->Mount(SKARLOC_MOUNT_MODEL);
|
||||
me->SetSpeed(MOVE_RUN, SPEED_MOUNTED);
|
||||
}
|
||||
|
||||
void UnMountSelf()
|
||||
{
|
||||
me->Dismount();
|
||||
me->SetSpeed(MOVE_RUN, SPEED_RUNNING);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 point)
|
||||
{
|
||||
npc_escortAI::MovementInform(type, point);
|
||||
if (type == POINT_MOTION_TYPE && point == 0xFFFFFF /*POINT_LAST_POINT*/)
|
||||
{
|
||||
if (roll_chance_i(30))
|
||||
Talk(SAY_LEAVE_COMBAT);
|
||||
if (_mounted)
|
||||
MountSelf();
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit*)
|
||||
{
|
||||
combatEvents.Reset();
|
||||
combatEvents.ScheduleEvent(EVENT_CHECK_HEALTH, 500);
|
||||
combatEvents.ScheduleEvent(EVENT_SPELL_SHIELD_BLOCK, 8000);
|
||||
combatEvents.ScheduleEvent(EVENT_SPELL_STRIKE, 2000);
|
||||
|
||||
if (roll_chance_i(50))
|
||||
Talk(SAY_RANDOM_AGGRO);
|
||||
|
||||
if (me->IsMounted())
|
||||
{
|
||||
_mounted = true;
|
||||
UnMountSelf();
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_mounted = false;
|
||||
events.Reset();
|
||||
combatEvents.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER);
|
||||
instance->SetData(DATA_THRALL_REPOSITION, 1);
|
||||
|
||||
uint32 data = instance->GetData(DATA_ESCORT_PROGRESS);
|
||||
if (data >= ENCOUNTER_PROGRESS_THRALL_ARMORED)
|
||||
ReorderInstance(data);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit*)
|
||||
{
|
||||
Talk(SAY_RANDOM_KILL);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
if (summon->GetEntry() == NPC_INFINITE_SLAYER || summon->GetEntry() == NPC_INFINITE_SABOTEUR || summon->GetEntry() == NPC_INFINITE_DEFILER)
|
||||
summon->GetMotionMaster()->MovePoint(10, 2634.25f, 672.01f, 54.445f);
|
||||
|
||||
summons.Summon(summon);
|
||||
}
|
||||
void SummonedCreatureDespawn(Creature* summon) { summons.Despawn(summon); }
|
||||
void SummonedCreatureDies(Creature* summon, Unit*) { summons.Despawn(summon); }
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
if (killer == me)
|
||||
return;
|
||||
|
||||
summons.DespawnAll();
|
||||
Talk(SAY_RANDOM_DIE);
|
||||
RemoveEscortState(STATE_ESCORT_ESCORTING);
|
||||
instance->SetData(DATA_THRALL_REPOSITION, 3);
|
||||
if (instance->GetData(DATA_ATTEMPTS_COUNT) < 20)
|
||||
me->CastSpell(me, SPELL_SUMMON_EROZION_IMAGE, true);
|
||||
else
|
||||
me->SetRespawnTime(DAY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_OPEN_DOORS:
|
||||
if (GameObject* doors = me->FindNearestGameObject(GO_PRISON_DOOR, 10.0f))
|
||||
doors->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case EVENT_START_WP:
|
||||
Start(true, true);
|
||||
SetDespawnAtEnd(false);
|
||||
break;
|
||||
case EVENT_SET_FACING:
|
||||
if (Creature* armorer = me->FindNearestCreature(NPC_DURNHOLDE_ARMORER, 30.0f))
|
||||
{
|
||||
armorer->AI()->Talk(SAY_ARMORER_THRALL);
|
||||
armorer->SetFacingToObject(me);
|
||||
me->SetFacingToObject(armorer);
|
||||
}
|
||||
break;
|
||||
case EVENT_KILL_ARMORER:
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK_UNARMED);
|
||||
if (Creature* armorer = me->FindNearestCreature(NPC_DURNHOLDE_ARMORER, 30.0f))
|
||||
armorer->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||
break;
|
||||
case EVENT_TALK_KILL_ARMORER:
|
||||
Talk(SAY_KILL_ARMORER);
|
||||
break;
|
||||
case EVENT_DRESSING_KNEEL:
|
||||
me->SetFacingTo(2.61f);
|
||||
Talk(SAY_ARMORY);
|
||||
me->SetStandState(UNIT_STAND_STATE_KNEEL);
|
||||
break;
|
||||
case EVENT_DRESSING_ARMOR:
|
||||
me->SetDisplayId(THRALL_MODEL_EQUIPPED);
|
||||
break;
|
||||
case EVENT_DRESSING_STAND:
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
break;
|
||||
case EVENT_DRESSING_AXE:
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, THRALL_WEAPON_ITEM);
|
||||
break;
|
||||
case EVENT_DRESSING_SHIELD:
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, THRALL_SHIELD_ITEM);
|
||||
break;
|
||||
case EVENT_DRESSING_TALK:
|
||||
instance->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_THRALL_ARMORED);
|
||||
Talk(SAY_GO_ARMORED);
|
||||
break;
|
||||
case EVENT_ENTER_MOUNT:
|
||||
MountSelf();
|
||||
if (Creature* mount = me->FindNearestCreature(NPC_SKARLOC_MOUNT, 10.0f))
|
||||
{
|
||||
me->SetFacingTo(mount->GetOrientation());
|
||||
mount->DespawnOrUnsummon();
|
||||
}
|
||||
break;
|
||||
case EVENT_TALK_START_RIDE:
|
||||
Talk(SAY_MOUNTS_UP);
|
||||
break;
|
||||
case EVENT_LOOK_1:
|
||||
me->SetFacingTo(5.058f);
|
||||
break;
|
||||
case EVENT_MOVE_AROUND:
|
||||
me->GetMotionMaster()->MovePoint(0, 2477.146f, 695.041f, 55.801f);
|
||||
break;
|
||||
case EVENT_LOOK_2:
|
||||
me->SetFacingTo(2.297f);
|
||||
break;
|
||||
case EVENT_LOOK_3:
|
||||
me->SetFacingTo(0.64f);
|
||||
break;
|
||||
case EVENT_SUMMON_GUARDS:
|
||||
SetRun(true);
|
||||
me->SummonCreature(NPC_TM_PROTECTOR, 2501.34f, 700.80f, 55.573f, 3.92f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_LOOKOUT, 2503.02f, 699.11f, 55.57f, 3.92f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_GUARDSMAN, 2503.04f, 702.495f, 50.63f, 3.92f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_GUARDSMAN, 2504.72f, 700.806f, 55.62f, 3.92f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
summons.DoAction(ACTION_SET_IMMUNE_FLAG);
|
||||
break;
|
||||
case EVENT_SUMMON_TALK1:
|
||||
if (Creature* summon = summons.GetCreatureWithEntry(NPC_TM_LOOKOUT))
|
||||
summon->AI()->Talk(SAY_LOOKOUT_SAW);
|
||||
break;
|
||||
case EVENT_SUMMON_TALK2:
|
||||
if (Creature* summon = summons.GetCreatureWithEntry(NPC_TM_LOOKOUT))
|
||||
summon->AI()->Talk(SAY_LOOKOUT_GO);
|
||||
summons.DoAction(ACTION_REMOVE_IMMUNE_FLAG);
|
||||
break;
|
||||
case EVENT_LOOK_4:
|
||||
me->SetFacingTo(0.41f);
|
||||
Talk(SAY_ENTER_CHURCH);
|
||||
break;
|
||||
case EVENT_SUMMON_GUARDS_2:
|
||||
me->SummonCreature(NPC_TM_PROTECTOR, 2630.75f, 664.80f, 54.28f, 4.37f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_LOOKOUT, 2632.20f, 661.98f, 54.30f, 4.37f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_GUARDSMAN, 2630.02f, 662.75f, 54.28f, 4.37f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_GUARDSMAN, 2632.86f, 664.05f, 54.31f, 4.37f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
break;
|
||||
case EVENT_SUMMON_TALK3:
|
||||
if (Creature* summon = summons.GetCreatureWithEntry(NPC_TM_LOOKOUT))
|
||||
summon->AI()->Talk(SAY_LOOKOUT_CHURCH);
|
||||
break;
|
||||
case EVENT_THRALL_TALK:
|
||||
Talk(SAY_MEET_TARETHA);
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
break;
|
||||
case EVENT_SUMMON_CHRONO:
|
||||
if (Creature* epoch = me->SummonCreature(NPC_EPOCH_HUNTER, 2640.49f, 696.15f, 64.31f, 4.51f, TEMPSUMMON_MANUAL_DESPAWN))
|
||||
{
|
||||
epoch->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
epoch->AI()->Talk(SAY_EPOCH_ENTER1);
|
||||
}
|
||||
break;
|
||||
case EVENT_THRALL_TALK_2:
|
||||
me->SetFacingTo(2.67f);
|
||||
Talk(SAY_EPOCH_WONDER);
|
||||
break;
|
||||
case EVENT_TARETHA_FALL:
|
||||
if (Creature* epoch = summons.GetCreatureWithEntry(NPC_EPOCH_HUNTER))
|
||||
epoch->AI()->Talk(SAY_EPOCH_ENTER2);
|
||||
if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TARETHA_GUID)))
|
||||
{
|
||||
Taretha->CastSpell(Taretha, SPELL_SHADOW_SPIKE);
|
||||
Taretha->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||
}
|
||||
break;
|
||||
case EVENT_THRALL_TALK_3:
|
||||
me->SetFacingTo(5.78f);
|
||||
Talk(SAY_EPOCH_KILL_TARETHA);
|
||||
break;
|
||||
case EVENT_THRALL_MOVE_DOWN:
|
||||
SetEscortPaused(false);
|
||||
break;
|
||||
case EVENT_EPOCH_INTRO:
|
||||
me->SetFacingTo(1.33f);
|
||||
if (Creature* epoch = summons.GetCreatureWithEntry(NPC_EPOCH_HUNTER))
|
||||
epoch->AI()->Talk(SAY_EPOCH_ENTER3);
|
||||
break;
|
||||
case EVENT_SUMMON_INFINITES:
|
||||
me->SummonCreature(NPC_EPOCH_LOOKOUT, 2647.57f, 701.17f, 56.215f, 4.3f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_EPOCH_GUARDSMAN, 2629.46f, 704.76f, 56.286f, 4.98f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_EPOCH_PROTECTOR, 2640.14f, 709.44f, 56.135f, 4.70f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
summons.DoAction(ACTION_SET_IMMUNE_FLAG);
|
||||
summons.DoAction(ACTION_MOVE);
|
||||
break;
|
||||
case EVENT_TRANSFORM:
|
||||
summons.DoAction(ACTION_TRANSFORM);
|
||||
summons.DoAction(ACTION_SET_IMMUNE_FLAG);
|
||||
break;
|
||||
case EVENT_START_WAVE_1:
|
||||
events.ScheduleEvent(EVENT_CHECK_WAVE_1, 500);
|
||||
summons.DoAction(ACTION_REMOVE_IMMUNE_FLAG);
|
||||
summons.DoAction(ACTION_START_COMBAT);
|
||||
break;
|
||||
case EVENT_CHECK_WAVE_1:
|
||||
if (summons.size() == 1)
|
||||
{
|
||||
me->SummonCreature(NPC_INFINITE_SABOTEUR, 2599.57f, 683.72f, 55.975f, 0.05f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_INFINITE_SLAYER, 2599.57f, 677.0f, 55.975f, 0.05f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_INFINITE_DEFILER, 2592.57f, 680.0f, 55.975f, 0.05f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
summons.DoAction(ACTION_START_COMBAT);
|
||||
events.ScheduleEvent(EVENT_CHECK_WAVE_2, 500);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_WAVE_1, 500);
|
||||
break;
|
||||
case EVENT_CHECK_WAVE_2:
|
||||
if (summons.size() == 1)
|
||||
{
|
||||
me->SummonCreature(NPC_INFINITE_SLAYER, 2642.62f, 701.43f, 55.965f, 4.46f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_INFINITE_SLAYER, 2638.62f, 701.43f, 55.965f, 4.46f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_INFINITE_SABOTEUR, 2638.62f, 705.43f, 55.965f, 4.46f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_INFINITE_DEFILER, 2642.62f, 705.43f, 55.965f, 4.46f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
summons.DoAction(ACTION_START_COMBAT);
|
||||
events.ScheduleEvent(EVENT_CHECK_WAVE_3, 500);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_WAVE_2, 500);
|
||||
break;
|
||||
case EVENT_CHECK_WAVE_3:
|
||||
if (summons.size() == 1)
|
||||
{
|
||||
me->SetHomePosition(2634.79f, 672.964f, 54.8577f, 1.33f);
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
events.ScheduleEvent(EVENT_CALL_EPOCH, 8000);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_WAVE_3, 500);
|
||||
break;
|
||||
case EVENT_CALL_EPOCH:
|
||||
if (Creature* epoch = summons.GetCreatureWithEntry(NPC_EPOCH_HUNTER))
|
||||
{
|
||||
epoch->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
epoch->GetMotionMaster()->MovePoint(0, *me, false, true);
|
||||
}
|
||||
break;
|
||||
case EVENT_THRALL_FACE_TARETHA:
|
||||
{
|
||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
||||
if (!players.isEmpty())
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
if (Player* player = itr->GetSource())
|
||||
player->KilledMonsterCredit(20156, 0);
|
||||
|
||||
me->SetFacingTo(5.76f);
|
||||
break;
|
||||
}
|
||||
case EVENT_THRALL_TALK_4:
|
||||
Talk(SAY_GREET_TARETHA);
|
||||
break;
|
||||
case EVENT_TARETHA_TALK_1:
|
||||
if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TARETHA_GUID)))
|
||||
Taretha->AI()->Talk(SAY_TARETHA_TALK1);
|
||||
break;
|
||||
case EVENT_THRALL_TALK_5:
|
||||
Talk(SAY_CHAT_TARETHA1);
|
||||
break;
|
||||
case EVENT_SUMMON_EROZION:
|
||||
if (Creature* erozion = me->SummonCreature(NPC_EROZION, 2646.31f, 680.01f, 55.36f, 3.76f, TEMPSUMMON_MANUAL_DESPAWN))
|
||||
erozion->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
|
||||
break;
|
||||
case EVENT_EROZION_TALK_1:
|
||||
if (Creature* erozion = summons.GetCreatureWithEntry(NPC_EROZION))
|
||||
{
|
||||
erozion->CastSpell(erozion, SPELL_TELEPORT, true);
|
||||
erozion->AI()->Talk(SAY_EROZION_1);
|
||||
}
|
||||
break;
|
||||
case EVENT_EROZION_ACTION_1:
|
||||
if (Creature* erozion = summons.GetCreatureWithEntry(NPC_EROZION))
|
||||
erozion->CastSpell(erozion, SPELL_MEMORY_WIPE, false);
|
||||
break;
|
||||
case EVENT_EROZION_TALK_2:
|
||||
if (Creature* erozion = summons.GetCreatureWithEntry(NPC_EROZION))
|
||||
erozion->AI()->Talk(SAY_EROZION_2);
|
||||
break;
|
||||
case EVENT_EROZION_TALK_3:
|
||||
if (Creature* erozion = summons.GetCreatureWithEntry(NPC_EROZION))
|
||||
erozion->AI()->Talk(SAY_EROZION_3);
|
||||
break;
|
||||
case EVENT_EROZION_ACTION_2:
|
||||
if (Creature* erozion = summons.GetCreatureWithEntry(NPC_EROZION))
|
||||
erozion->CastSpell(erozion, SPELL_MEMORY_WIPE_RESUME, false);
|
||||
break;
|
||||
case EVENT_THRALL_TALK_6:
|
||||
Talk(SAY_EVENT_COMPLETE);
|
||||
break;
|
||||
case EVENT_THRALL_RUN_AWAY:
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
SetEscortPaused(false);
|
||||
break;
|
||||
case EVENT_TARETHA_TALK_2:
|
||||
if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TARETHA_GUID)))
|
||||
{
|
||||
Taretha->SetFacingTo(4.233f);
|
||||
Taretha->AI()->Talk(SAY_TARETHA_TALK2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateEscortAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
combatEvents.Update(diff);
|
||||
switch (combatEvents.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CHECK_HEALTH:
|
||||
if (me->HealthBelowPct(20))
|
||||
{
|
||||
Talk(SAY_RANDOM_LOW_HP);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 500);
|
||||
break;
|
||||
case EVENT_SPELL_STRIKE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_STRIKE, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_STRIKE, 6000);
|
||||
break;
|
||||
case EVENT_SPELL_SHIELD_BLOCK:
|
||||
me->CastSpell(me, SPELL_SHIELD_BLOCK, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_SHIELD_BLOCK, 6000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void ReorderInstance(uint32 data)
|
||||
{
|
||||
Start(true, true);
|
||||
SetEscortPaused(true);
|
||||
SetDespawnAtEnd(false);
|
||||
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER);
|
||||
|
||||
if (data < ENCOUNTER_PROGRESS_THRALL_ARMORED)
|
||||
{
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
|
||||
me->SetDisplayId(THRALL_MODEL_UNEQUIPPED);
|
||||
}
|
||||
else
|
||||
{
|
||||
me->SetDisplayId(THRALL_MODEL_EQUIPPED);
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, THRALL_WEAPON_ITEM);
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, THRALL_SHIELD_ITEM);
|
||||
}
|
||||
|
||||
switch (data)
|
||||
{
|
||||
case ENCOUNTER_PROGRESS_THRALL_ARMORED:
|
||||
SetNextWaypoint(11, false);
|
||||
break;
|
||||
case ENCOUNTER_PROGRESS_AMBUSHES_1:
|
||||
SetNextWaypoint(27, false);
|
||||
break;
|
||||
case ENCOUNTER_PROGRESS_SKARLOC_KILLED:
|
||||
me->SummonCreature(NPC_SKARLOC_MOUNT, 2049.12f, 252.31f, 62.855f, me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN);
|
||||
SetNextWaypoint(30, false);
|
||||
break;
|
||||
case ENCOUNTER_PROGRESS_TARREN_MILL:
|
||||
SetNextWaypoint(61, false);
|
||||
break;
|
||||
case ENCOUNTER_PROGRESS_TARETHA_MEET:
|
||||
SetNextWaypoint(95, false);
|
||||
if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TARETHA_GUID)))
|
||||
Taretha->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
EventMap combatEvents;
|
||||
SummonList summons;
|
||||
|
||||
bool _mounted;
|
||||
};
|
||||
};
|
||||
|
||||
class npc_taretha : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_taretha() : CreatureScript("npc_taretha") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_tarethaAI>(creature);
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
struct npc_tarethaAI : public npc_escortAI
|
||||
{
|
||||
npc_tarethaAI(Creature* creature) : npc_escortAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
me->RemoveAllAuras();
|
||||
Start(false, true);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (waypointId == 7)
|
||||
{
|
||||
SetRun(false);
|
||||
Talk(SAY_TARETHA_FREE);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_CHEER);
|
||||
if (Creature* thrall = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_THRALL_GUID)))
|
||||
thrall->AI()->DoAction(me->GetEntry());
|
||||
}
|
||||
else if (waypointId == 9)
|
||||
me->SetVisible(false);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
|
||||
me->CastSpell(me, SPELL_SHADOW_PRISON, true);
|
||||
}
|
||||
|
||||
void AttackStart(Unit*) { }
|
||||
void MoveInLineOfSight(Unit*) { }
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_old_hillsbrad()
|
||||
{
|
||||
new npc_thrall_old_hillsbrad();
|
||||
new npc_taretha();
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef DEF_OLD_HILLSBRAD_H
|
||||
#define DEF_OLD_HILLSBRAD_H
|
||||
|
||||
enum DataIds
|
||||
{
|
||||
DATA_ESCORT_PROGRESS = 0,
|
||||
|
||||
DATA_BOMBS_PLACED = 10,
|
||||
DATA_THRALL_REPOSITION = 11,
|
||||
DATA_THRALL_ADD_FLAG = 12,
|
||||
DATA_THRALL_GUID = 13,
|
||||
DATA_TARETHA_GUID = 14,
|
||||
DATA_ATTEMPTS_COUNT = 15
|
||||
};
|
||||
|
||||
enum NpcIds
|
||||
{
|
||||
NPC_EROZION = 18723,
|
||||
NPC_THRALL = 17876,
|
||||
NPC_TARETHA = 18887,
|
||||
NPC_EPOCH_HUNTER = 18096,
|
||||
NPC_LIEUTENANT_DRAKE = 17848,
|
||||
|
||||
NPC_LODGE_QUEST_TRIGGER = 20155,
|
||||
NPC_ORC_PRISONER = 18598,
|
||||
|
||||
NPC_DURNHOLDE_ARMORER = 18764,
|
||||
NPC_DURNHOLDE_WARDEN = 17833,
|
||||
NPC_DURNHOLDE_VETERAN = 17860,
|
||||
NPC_DURNHOLDE_MAGE = 17860,
|
||||
NPC_DURNHOLDE_SENTRY = 17860,
|
||||
|
||||
NPC_CAPTAIN_SKARLOC = 17862,
|
||||
NPC_SKARLOC_MOUNT = 18798,
|
||||
|
||||
NPC_LORDAERON_SENTRY = 17815,
|
||||
NPC_LORDAERON_WATCHMAN = 17814,
|
||||
};
|
||||
|
||||
enum GobjectIds
|
||||
{
|
||||
GO_BARREL = 182589,
|
||||
GO_ROARING_FLAME = 182592,
|
||||
GO_PRISON_DOOR = 184393
|
||||
};
|
||||
|
||||
enum MiscIds
|
||||
{
|
||||
QUEST_DIVERSION = 10283,
|
||||
WORLD_STATE_BARRELS_PLANTED = 2436,
|
||||
SKARLOC_MOUNT_MODEL = 18223,
|
||||
|
||||
ENCOUNTER_PROGRESS_NONE = 0,
|
||||
ENCOUNTER_PROGRESS_BARRELS = 1,
|
||||
ENCOUNTER_PROGRESS_DRAKE_KILLED = 2,
|
||||
ENCOUNTER_PROGRESS_THRALL_ARMORED = 3,
|
||||
ENCOUNTER_PROGRESS_AMBUSHES_1 = 4,
|
||||
ENCOUNTER_PROGRESS_SKARLOC_KILLED = 5,
|
||||
ENCOUNTER_PROGRESS_TARREN_MILL = 6,
|
||||
ENCOUNTER_PROGRESS_TARETHA_MEET = 7,
|
||||
ENCOUNTER_PROGRESS_EPOCH_KILLED = 8,
|
||||
ENCOUNTER_PROGRESS_FINISHED = 9,
|
||||
|
||||
EVENT_INITIAL_BARRELS_FLAME = 1,
|
||||
EVENT_FINAL_BARRELS_FLAME = 2,
|
||||
EVENT_SUMMON_LIEUTENANT = 3,
|
||||
EVENT_THRALL_REPOSITION = 4,
|
||||
|
||||
INSTANCE_POSITIONS_COUNT = 3,
|
||||
THRALL_POSITIONS_COUNT = 5
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "the_black_morass.h"
|
||||
|
||||
enum Enums
|
||||
{
|
||||
SAY_ENTER = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_BANISH = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4,
|
||||
EMOTE_FRENZY = 5,
|
||||
|
||||
SPELL_CLEAVE = 40504,
|
||||
SPELL_TIME_STOP = 31422,
|
||||
SPELL_ENRAGE = 37605,
|
||||
SPELL_SAND_BREATH = 31473,
|
||||
SPELL_CORRUPT_MEDIVH = 37853,
|
||||
SPELL_BANISH_DRAGON_HELPER = 31550
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SANDBREATH = 1,
|
||||
EVENT_TIMESTOP = 2,
|
||||
EVENT_FRENZY = 3,
|
||||
EVENT_CLEAVE = 4
|
||||
};
|
||||
|
||||
class boss_aeonus : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_aeonus() : CreatureScript("boss_aeonus") { }
|
||||
|
||||
struct boss_aeonusAI : public ScriptedAI
|
||||
{
|
||||
boss_aeonusAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
if (Unit* medivh = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_MEDIVH)))
|
||||
if (me->GetDistance2d(medivh) < 20.0f)
|
||||
me->CastSpell(me, SPELL_CORRUPT_MEDIVH, false);
|
||||
}
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
Talk(SAY_ENTER);
|
||||
ScriptedAI::InitializeAI();
|
||||
|
||||
if (Unit* medivh = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_MEDIVH)))
|
||||
{
|
||||
me->SetHomePosition(medivh->GetPositionX() + 14.0f*cos(medivh->GetAngle(me)), medivh->GetPositionY() + 14.0f*sin(medivh->GetAngle(me)), medivh->GetPositionZ(), me->GetAngle(medivh));
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_CLEAVE, 5000);
|
||||
events.ScheduleEvent(EVENT_SANDBREATH, 20000);
|
||||
events.ScheduleEvent(EVENT_TIMESTOP, 15000);
|
||||
events.ScheduleEvent(EVENT_FRENZY, 30000);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_TIME_KEEPER)
|
||||
{
|
||||
if (me->IsWithinDistInMap(who, 20.0f))
|
||||
{
|
||||
Talk(SAY_BANISH);
|
||||
me->CastSpell(me, SPELL_BANISH_DRAGON_HELPER, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
instance->SetData(TYPE_AEONUS, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CLEAVE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
|
||||
events.ScheduleEvent(EVENT_CLEAVE, 10000);
|
||||
break;
|
||||
case EVENT_SANDBREATH:
|
||||
me->CastSpell(me->GetVictim(), SPELL_SAND_BREATH, false);
|
||||
events.ScheduleEvent(EVENT_SANDBREATH, 20000);
|
||||
break;
|
||||
case EVENT_TIMESTOP:
|
||||
me->CastSpell(me, SPELL_TIME_STOP, false);
|
||||
events.ScheduleEvent(EVENT_TIMESTOP, 25000);
|
||||
break;
|
||||
case EVENT_FRENZY:
|
||||
Talk(EMOTE_FRENZY);
|
||||
me->CastSpell(me, SPELL_ENRAGE, false);
|
||||
events.ScheduleEvent(EVENT_FRENZY, 30000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_aeonusAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_aeonus()
|
||||
{
|
||||
new boss_aeonus();
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "the_black_morass.h"
|
||||
|
||||
enum Enums
|
||||
{
|
||||
SAY_ENTER = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_BANISH = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4,
|
||||
|
||||
SPELL_ARCANE_BLAST = 31457,
|
||||
SPELL_ARCANE_DISCHARGE = 31472,
|
||||
SPELL_TIME_LAPSE = 31467,
|
||||
SPELL_ATTRACTION = 38540,
|
||||
|
||||
SPELL_BANISH_DRAGON_HELPER = 31550,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_ARCANE_BLAST = 1,
|
||||
EVENT_TIME_LAPSE = 2,
|
||||
EVENT_ARCANE_DISCHARGE = 3,
|
||||
EVENT_ATTRACTION = 4
|
||||
};
|
||||
|
||||
class boss_chrono_lord_deja : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_chrono_lord_deja() : CreatureScript("boss_chrono_lord_deja") { }
|
||||
|
||||
struct boss_chrono_lord_dejaAI : public ScriptedAI
|
||||
{
|
||||
boss_chrono_lord_dejaAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void OwnTalk(uint32 id)
|
||||
{
|
||||
if (me->GetEntry() == NPC_CHRONO_LORD_DEJA)
|
||||
Talk(id);
|
||||
}
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
OwnTalk(SAY_ENTER);
|
||||
ScriptedAI::InitializeAI();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_ARCANE_BLAST, 10000);
|
||||
events.ScheduleEvent(EVENT_TIME_LAPSE, 15000);
|
||||
events.ScheduleEvent(EVENT_ARCANE_DISCHARGE, 25000);
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_ATTRACTION, 20000);
|
||||
|
||||
OwnTalk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_TIME_KEEPER)
|
||||
{
|
||||
if (me->IsWithinDistInMap(who, 20.0f))
|
||||
{
|
||||
OwnTalk(SAY_BANISH);
|
||||
me->CastSpell(me, SPELL_BANISH_DRAGON_HELPER, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
OwnTalk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
OwnTalk(SAY_DEATH);
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
instance->SetData(TYPE_CHRONO_LORD_DEJA, DONE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_ARCANE_BLAST:
|
||||
me->CastSpell(me->GetVictim(), SPELL_ARCANE_BLAST, false);
|
||||
events.ScheduleEvent(EVENT_ARCANE_BLAST, 20000);
|
||||
break;
|
||||
case EVENT_TIME_LAPSE:
|
||||
me->CastSpell(me, SPELL_TIME_LAPSE, false);
|
||||
events.ScheduleEvent(EVENT_TIME_LAPSE, 20000);
|
||||
break;
|
||||
case EVENT_ARCANE_DISCHARGE:
|
||||
me->CastSpell(me, SPELL_ARCANE_DISCHARGE, false);
|
||||
events.ScheduleEvent(EVENT_ARCANE_DISCHARGE, 25000);
|
||||
break;
|
||||
case EVENT_ATTRACTION:
|
||||
me->CastSpell(me, SPELL_ATTRACTION, false);
|
||||
events.ScheduleEvent(EVENT_ATTRACTION, 30000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_chrono_lord_dejaAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_chrono_lord_deja()
|
||||
{
|
||||
new boss_chrono_lord_deja();
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "the_black_morass.h"
|
||||
|
||||
enum Enums
|
||||
{
|
||||
SAY_ENTER = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_BANISH = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4,
|
||||
|
||||
SPELL_HASTEN = 31458,
|
||||
SPELL_MORTAL_WOUND = 31464,
|
||||
SPELL_WING_BUFFET = 31475,
|
||||
SPELL_REFLECT = 38592,
|
||||
SPELL_BANISH_DRAGON_HELPER = 31550
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_HASTEN = 1,
|
||||
EVENT_MORTAL_WOUND = 2,
|
||||
EVENT_WING_BUFFET = 3,
|
||||
EVENT_SPELL_REFLECTION = 4
|
||||
};
|
||||
|
||||
class boss_temporus : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_temporus() : CreatureScript("boss_temporus") { }
|
||||
|
||||
struct boss_temporusAI : public ScriptedAI
|
||||
{
|
||||
boss_temporusAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
EventMap events;
|
||||
|
||||
void OwnTalk(uint32 id)
|
||||
{
|
||||
if (me->GetEntry() == NPC_TEMPORUS)
|
||||
Talk(id);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
OwnTalk(SAY_ENTER);
|
||||
ScriptedAI::InitializeAI();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_HASTEN, 12000);
|
||||
events.ScheduleEvent(EVENT_MORTAL_WOUND, 5000);
|
||||
events.ScheduleEvent(EVENT_WING_BUFFET, 20000);
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_SPELL_REFLECTION, 28000);
|
||||
|
||||
OwnTalk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
OwnTalk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
OwnTalk(SAY_DEATH);
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
instance->SetData(TYPE_TEMPORUS, DONE);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_TIME_KEEPER)
|
||||
{
|
||||
if (me->IsWithinDistInMap(who, 20.0f))
|
||||
{
|
||||
OwnTalk(SAY_BANISH);
|
||||
me->CastSpell(me, SPELL_BANISH_DRAGON_HELPER, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_HASTEN:
|
||||
me->CastSpell(me, SPELL_HASTEN, false);
|
||||
events.ScheduleEvent(EVENT_HASTEN, 20000);
|
||||
break;
|
||||
case EVENT_MORTAL_WOUND:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MORTAL_WOUND, false);
|
||||
events.ScheduleEvent(EVENT_MORTAL_WOUND, 10000);
|
||||
break;
|
||||
case EVENT_WING_BUFFET:
|
||||
me->CastSpell(me, SPELL_WING_BUFFET, false);
|
||||
events.ScheduleEvent(EVENT_WING_BUFFET, 20000);
|
||||
break;
|
||||
case EVENT_SPELL_REFLECTION:
|
||||
me->CastSpell(me, SPELL_REFLECT, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_REFLECTION, 30000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_temporusAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_temporus()
|
||||
{
|
||||
new boss_temporus();
|
||||
}
|
||||
@@ -1,341 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "the_black_morass.h"
|
||||
#include "Player.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
|
||||
const Position PortalLocation[4]=
|
||||
{
|
||||
{-2041.06f, 7042.08f, 29.99f, 1.30f},
|
||||
{-1968.18f, 7042.11f, 21.93f, 2.12f},
|
||||
{-1885.82f, 7107.36f, 22.32f, 3.07f},
|
||||
{-1928.11f, 7175.95f, 22.11f, 3.44f}
|
||||
};
|
||||
|
||||
class instance_the_black_morass : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_the_black_morass() : InstanceMapScript("instance_the_black_morass", 269) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_the_black_morass_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
struct instance_the_black_morass_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_the_black_morass_InstanceMapScript(Map* map) : InstanceScript(map) { }
|
||||
|
||||
std::set<uint64> encounterNPCs;
|
||||
uint32 encounters[MAX_ENCOUNTER];
|
||||
uint64 _medivhGUID;
|
||||
uint8 _currentRift;
|
||||
uint8 _shieldPercent;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
memset(&encounters, 0, sizeof(encounters));
|
||||
_medivhGUID = 0;
|
||||
_currentRift = 0;
|
||||
_shieldPercent = 100;
|
||||
encounterNPCs.clear();
|
||||
}
|
||||
|
||||
void CleanupInstance()
|
||||
{
|
||||
Events.Reset();
|
||||
_currentRift = 0;
|
||||
_shieldPercent = 100;
|
||||
|
||||
instance->LoadGrid(-2023.0f, 7121.0f);
|
||||
if (Creature* medivh = instance->GetCreature(_medivhGUID))
|
||||
{
|
||||
medivh->DespawnOrUnsummon();
|
||||
medivh->SetRespawnTime(3);
|
||||
}
|
||||
|
||||
std::set<uint64> eCopy = encounterNPCs;
|
||||
for (std::set<uint64>::const_iterator itr = eCopy.begin(); itr != eCopy.end(); ++itr)
|
||||
if (Creature* creature = instance->GetCreature(*itr))
|
||||
creature->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnPlayerEnter(Player* player)
|
||||
{
|
||||
if (instance->GetPlayersCountExceptGMs() <= 1 && GetData(TYPE_AEONUS) != DONE)
|
||||
CleanupInstance();
|
||||
|
||||
player->SendUpdateWorldState(WORLD_STATE_BM, _currentRift > 0 ? 1 : 0);
|
||||
player->SendUpdateWorldState(WORLD_STATE_BM_SHIELD, _shieldPercent);
|
||||
player->SendUpdateWorldState(WORLD_STATE_BM_RIFT, _currentRift);
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_MEDIVH:
|
||||
_medivhGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_TIME_RIFT:
|
||||
case NPC_CHRONO_LORD_DEJA:
|
||||
case NPC_INFINITE_CHRONO_LORD:
|
||||
case NPC_TEMPORUS:
|
||||
case NPC_INFINITE_TIMEREAVER:
|
||||
case NPC_AEONUS:
|
||||
case NPC_RIFT_KEEPER_WARLOCK:
|
||||
case NPC_RIFT_KEEPER_MAGE:
|
||||
case NPC_RIFT_LORD:
|
||||
case NPC_RIFT_LORD_2:
|
||||
case NPC_INFINITE_ASSASIN:
|
||||
case NPC_INFINITE_WHELP:
|
||||
case NPC_INFINITE_CRONOMANCER:
|
||||
case NPC_INFINITE_EXECUTIONER:
|
||||
case NPC_INFINITE_VANQUISHER:
|
||||
encounterNPCs.insert(creature->GetGUID());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnCreatureRemove(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_TIME_RIFT:
|
||||
case NPC_CHRONO_LORD_DEJA:
|
||||
case NPC_INFINITE_CHRONO_LORD:
|
||||
case NPC_TEMPORUS:
|
||||
case NPC_INFINITE_TIMEREAVER:
|
||||
case NPC_AEONUS:
|
||||
case NPC_RIFT_KEEPER_WARLOCK:
|
||||
case NPC_RIFT_KEEPER_MAGE:
|
||||
case NPC_RIFT_LORD:
|
||||
case NPC_RIFT_LORD_2:
|
||||
case NPC_INFINITE_ASSASIN:
|
||||
case NPC_INFINITE_WHELP:
|
||||
case NPC_INFINITE_CRONOMANCER:
|
||||
case NPC_INFINITE_EXECUTIONER:
|
||||
case NPC_INFINITE_VANQUISHER:
|
||||
encounterNPCs.erase(creature->GetGUID());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_AEONUS:
|
||||
{
|
||||
encounters[type] = DONE;
|
||||
SaveToDB();
|
||||
|
||||
if (Creature* medivh = instance->GetCreature(_medivhGUID))
|
||||
medivh->AI()->DoAction(ACTION_OUTRO);
|
||||
|
||||
Map::PlayerList const& players = instance->GetPlayers();
|
||||
if (!players.isEmpty())
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
if (Player* player = itr->GetSource())
|
||||
{
|
||||
if (player->GetQuestStatus(QUEST_OPENING_PORTAL) == QUEST_STATUS_INCOMPLETE)
|
||||
player->AreaExploredOrEventHappens(QUEST_OPENING_PORTAL);
|
||||
|
||||
if (player->GetQuestStatus(QUEST_MASTER_TOUCH) == QUEST_STATUS_INCOMPLETE)
|
||||
player->AreaExploredOrEventHappens(QUEST_MASTER_TOUCH);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYPE_CHRONO_LORD_DEJA:
|
||||
case TYPE_TEMPORUS:
|
||||
encounters[type] = DONE;
|
||||
Events.RescheduleEvent(EVENT_NEXT_PORTAL, 60000);
|
||||
Events.SetPhase(1);
|
||||
SaveToDB();
|
||||
break;
|
||||
case DATA_RIFT_KILLED:
|
||||
if (!Events.IsInPhase(1))
|
||||
Events.RescheduleEvent(EVENT_NEXT_PORTAL, 4000);
|
||||
break;
|
||||
case DATA_MEDIVH:
|
||||
DoUpdateWorldState(WORLD_STATE_BM, 1);
|
||||
DoUpdateWorldState(WORLD_STATE_BM_SHIELD, _shieldPercent);
|
||||
DoUpdateWorldState(WORLD_STATE_BM_RIFT, _currentRift);
|
||||
Events.RescheduleEvent(EVENT_NEXT_PORTAL, 3000);
|
||||
break;
|
||||
case DATA_DAMAGE_SHIELD:
|
||||
--_shieldPercent;
|
||||
DoUpdateWorldState(WORLD_STATE_BM_SHIELD, _shieldPercent);
|
||||
if (!_shieldPercent)
|
||||
if (Creature* medivh = instance->GetCreature(_medivhGUID))
|
||||
if (medivh->IsAlive())
|
||||
{
|
||||
Unit::Kill(medivh, medivh);
|
||||
|
||||
// Xinef: delete all spawns
|
||||
std::set<uint64> eCopy = encounterNPCs;
|
||||
for (std::set<uint64>::iterator itr = eCopy.begin(); itr != eCopy.end(); ++itr)
|
||||
if (Creature* creature = instance->GetCreature(*itr))
|
||||
creature->DespawnOrUnsummon();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_CHRONO_LORD_DEJA:
|
||||
case TYPE_TEMPORUS:
|
||||
case TYPE_AEONUS:
|
||||
return encounters[type];
|
||||
case DATA_SHIELD_PERCENT:
|
||||
return _shieldPercent;
|
||||
case DATA_RIFT_NUMBER:
|
||||
return _currentRift;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetData64(uint32 type, uint64 data)
|
||||
{
|
||||
if (type == DATA_SUMMONED_NPC)
|
||||
encounterNPCs.insert(data);
|
||||
else if (type == DATA_DELETED_NPC)
|
||||
encounterNPCs.erase(data);
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 data) const
|
||||
{
|
||||
if (data == DATA_MEDIVH)
|
||||
return _medivhGUID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SummonPortalKeeper()
|
||||
{
|
||||
Creature* rift = NULL;
|
||||
for (std::set<uint64>::const_iterator itr = encounterNPCs.begin(); itr != encounterNPCs.end(); ++itr)
|
||||
if (Creature* summon = instance->GetCreature(*itr))
|
||||
if (summon->GetEntry() == NPC_TIME_RIFT)
|
||||
{
|
||||
rift = summon;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rift)
|
||||
return;
|
||||
|
||||
int32 entry = 0;
|
||||
switch (_currentRift)
|
||||
{
|
||||
case 6: entry = GetData(TYPE_CHRONO_LORD_DEJA) == DONE ? (instance->IsHeroic() ? NPC_INFINITE_CHRONO_LORD : -NPC_CHRONO_LORD_DEJA) : NPC_CHRONO_LORD_DEJA; break;
|
||||
case 12: entry = GetData(TYPE_TEMPORUS) == DONE ? (instance->IsHeroic() ? NPC_INFINITE_TIMEREAVER : -NPC_TEMPORUS) : NPC_TEMPORUS; break;
|
||||
case 18: entry = NPC_AEONUS; break;
|
||||
default: entry = RAND(NPC_RIFT_KEEPER_WARLOCK, NPC_RIFT_KEEPER_MAGE, NPC_RIFT_LORD, NPC_RIFT_LORD_2); break;
|
||||
}
|
||||
|
||||
Position pos;
|
||||
rift->GetNearPosition(pos, 10.0f, 2*M_PI*rand_norm());
|
||||
|
||||
if (TempSummon* summon = instance->SummonCreature(abs(entry), pos))
|
||||
{
|
||||
summon->SetTempSummonType(TEMPSUMMON_CORPSE_TIMED_DESPAWN);
|
||||
summon->SetTimer(3*MINUTE*IN_MILLISECONDS);
|
||||
|
||||
if (entry < 0)
|
||||
summon->SetLootMode(0);
|
||||
|
||||
if (summon->GetEntry() != NPC_AEONUS)
|
||||
{
|
||||
rift->AI()->SetGUID(summon->GetGUID());
|
||||
rift->CastSpell(summon, SPELL_RIFT_CHANNEL, false);
|
||||
}
|
||||
else
|
||||
summon->SetReactState(REACT_DEFENSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void Update(uint32 diff)
|
||||
{
|
||||
Events.Update(diff);
|
||||
switch (Events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_NEXT_PORTAL:
|
||||
++_currentRift;
|
||||
DoUpdateWorldState(WORLD_STATE_BM_RIFT, _currentRift);
|
||||
Events.ScheduleEvent(EVENT_SUMMON_KEEPER, 6000);
|
||||
Events.SetPhase(0);
|
||||
|
||||
if (Creature* medivh = instance->GetCreature(_medivhGUID))
|
||||
{
|
||||
uint8 position = (_currentRift-1)%4;
|
||||
instance->SummonCreature(NPC_TIME_RIFT, PortalLocation[position]);
|
||||
}
|
||||
break;
|
||||
case EVENT_SUMMON_KEEPER:
|
||||
SummonPortalKeeper();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "B M " << encounters[0] << ' ' << encounters[1] << ' ' << encounters[2];
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2;
|
||||
if (dataHead1 == 'B' && dataHead2 == 'M')
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
loadStream >> encounters[i];
|
||||
}
|
||||
else
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
protected:
|
||||
EventMap Events;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_instance_the_black_morass()
|
||||
{
|
||||
new instance_the_black_morass();
|
||||
}
|
||||
@@ -1,402 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "the_black_morass.h"
|
||||
#include "MoveSplineInit.h"
|
||||
|
||||
enum medivhSays
|
||||
{
|
||||
SAY_WEAK75 = 0,
|
||||
SAY_WEAK50 = 1,
|
||||
SAY_WEAK25 = 2,
|
||||
SAY_ENTER = 3,
|
||||
SAY_INTRO = 4,
|
||||
SAY_DEATH = 5,
|
||||
SAY_WIN = 6,
|
||||
SAY_ORCS_ENTER = 7,
|
||||
|
||||
SAY_ORCS_ANSWER = 0
|
||||
};
|
||||
|
||||
enum medivhSpells
|
||||
{
|
||||
SPELL_MANA_SHIELD = 31635,
|
||||
SPELL_MEDIVH_CHANNEL = 31556,
|
||||
SPELL_BLACK_CRYSTAL = 32563,
|
||||
SPELL_PORTAL_CRYSTALS = 32564,
|
||||
SPELL_BANISH_PURPLE = 32566,
|
||||
SPELL_BANISH_GREEN = 32567,
|
||||
|
||||
SPELL_CORRUPT = 31326,
|
||||
SPELL_CORRUPT_AEONUS = 37853,
|
||||
};
|
||||
|
||||
enum medivhMisc
|
||||
{
|
||||
NPC_DP_EMITTER_STALKER = 18582,
|
||||
NPC_DP_CRYSTAL_STALKER = 18553,
|
||||
NPC_SHADOW_COUNCIL_ENFORCER = 17023,
|
||||
GO_DARK_PORTAL = 185103,
|
||||
|
||||
EVENT_CHECK_HEALTH_25 = 1,
|
||||
EVENT_CHECK_HEALTH_50 = 2,
|
||||
EVENT_CHECK_HEALTH_75 = 3,
|
||||
EVENT_SUMMON_CRYSTAL = 4,
|
||||
EVENT_SUMMON_FLYING_CRYSTAL = 5,
|
||||
|
||||
EVENT_OUTRO_1 = 10,
|
||||
EVENT_OUTRO_2 = 11,
|
||||
EVENT_OUTRO_3 = 12,
|
||||
EVENT_OUTRO_4 = 13,
|
||||
EVENT_OUTRO_5 = 14,
|
||||
EVENT_OUTRO_6 = 15,
|
||||
EVENT_OUTRO_7 = 16,
|
||||
EVENT_OUTRO_8 = 17
|
||||
};
|
||||
|
||||
class NpcRunToHome : public BasicEvent
|
||||
{
|
||||
public:
|
||||
NpcRunToHome(Creature& owner) : _owner(owner) { }
|
||||
|
||||
bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/)
|
||||
{
|
||||
_owner.GetMotionMaster()->MoveTargetedHome();
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
Creature& _owner;
|
||||
};
|
||||
|
||||
class npc_medivh_bm : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_medivh_bm() : CreatureScript("npc_medivh_bm") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_medivh_bmAI(creature);
|
||||
}
|
||||
|
||||
struct npc_medivh_bmAI : public ScriptedAI
|
||||
{
|
||||
npc_medivh_bmAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
|
||||
groundArray.clear();
|
||||
airArray.clear();
|
||||
|
||||
groundArray.push_back(G3D::Vector3(creature->GetPositionX() + 8.0f, creature->GetPositionY(), creature->GetPositionZ()));
|
||||
airArray.push_back(G3D::Vector3(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ()));
|
||||
for (uint8 i = 0; i < 10; ++i)
|
||||
groundArray.push_back(G3D::Vector3(creature->GetPositionX() + 8.0f*cos(2.0f*M_PI*i/10.0f), creature->GetPositionY() + 8.0f*sin(2.0f*M_PI*i/10.0f), creature->GetPositionZ()));
|
||||
|
||||
for (uint8 i = 0; i < 40; ++i)
|
||||
airArray.push_back(G3D::Vector3(creature->GetPositionX() + i*0.25f*cos(2.0f*M_PI*i/10.0f), creature->GetPositionY() + i*0.25f*sin(2.0f*M_PI*i/10.0f), creature->GetPositionZ() + i/4.0f));
|
||||
for (uint8 i = 40; i < 80; ++i)
|
||||
airArray.push_back(G3D::Vector3(creature->GetPositionX() + 10.0f*cos(2.0f*M_PI*i/10.0f), creature->GetPositionY() + 10.0f*sin(2.0f*M_PI*i/10.0f), creature->GetPositionZ() + i/4.0f));
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
Movement::PointsArray groundArray;
|
||||
Movement::PointsArray airArray;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
me->CastSpell(me, SPELL_MANA_SHIELD, true);
|
||||
|
||||
if (instance->GetData(TYPE_AEONUS) != DONE)
|
||||
me->CastSpell(me, SPELL_MEDIVH_CHANNEL, false);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
instance->SetData64(DATA_SUMMONED_NPC, summon->GetGUID());
|
||||
if (summon->GetEntry() == NPC_DP_CRYSTAL_STALKER)
|
||||
{
|
||||
summon->DespawnOrUnsummon(25000);
|
||||
summon->CastSpell(summon, RAND(SPELL_BANISH_PURPLE, SPELL_BANISH_GREEN), true);
|
||||
summon->GetMotionMaster()->MoveSplinePath(&airArray);
|
||||
}
|
||||
else if (summon->GetEntry() == NPC_DP_EMITTER_STALKER)
|
||||
{
|
||||
summon->CastSpell(summon, SPELL_BLACK_CRYSTAL, true);
|
||||
Movement::MoveSplineInit init(summon);
|
||||
init.MovebyPath(groundArray);
|
||||
init.SetCyclic();
|
||||
init.Launch();
|
||||
}
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* summon)
|
||||
{
|
||||
instance->SetData64(DATA_DELETED_NPC, summon->GetGUID());
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (!events.Empty() || instance->GetData(TYPE_AEONUS) == DONE)
|
||||
return;
|
||||
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 20.0f))
|
||||
{
|
||||
Talk(SAY_ENTER);
|
||||
instance->SetData(DATA_MEDIVH, 1);
|
||||
me->CastSpell(me, SPELL_MEDIVH_CHANNEL, false);
|
||||
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH_75, 500);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH_50, 500);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH_25, 500);
|
||||
events.ScheduleEvent(EVENT_SUMMON_CRYSTAL, 2000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_CRYSTAL, 4000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_CRYSTAL, 6000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_FLYING_CRYSTAL, 8000);
|
||||
}
|
||||
}
|
||||
|
||||
void AttackStart(Unit* ) { }
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_OUTRO)
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_OUTRO_1, 4000);
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
|
||||
me->SummonGameObject(GO_DARK_PORTAL, -2086.0f, 7125.6215f, 30.5f, 6.148f, 0.0f, 0.0f, 0.0f, 0.0f, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* )
|
||||
{
|
||||
me->SetRespawnTime(DAY);
|
||||
events.Reset();
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
events.Update(diff);
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CHECK_HEALTH_25:
|
||||
case EVENT_CHECK_HEALTH_50:
|
||||
case EVENT_CHECK_HEALTH_75:
|
||||
if (instance->GetData(DATA_SHIELD_PERCENT) <= eventId*25)
|
||||
{
|
||||
Talk(eventId-1);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(eventId, 500);
|
||||
break;
|
||||
case EVENT_SUMMON_CRYSTAL:
|
||||
me->SummonCreature(NPC_DP_EMITTER_STALKER, me->GetPositionX() + 8.0f, me->GetPositionY(), me->GetPositionZ());
|
||||
break;
|
||||
case EVENT_SUMMON_FLYING_CRYSTAL:
|
||||
me->CastSpell(me, SPELL_PORTAL_CRYSTALS, true);
|
||||
events.ScheduleEvent(EVENT_SUMMON_FLYING_CRYSTAL, 1000);
|
||||
break;
|
||||
case EVENT_OUTRO_1:
|
||||
me->SetFacingTo(6.21f);
|
||||
Talk(SAY_WIN);
|
||||
events.ScheduleEvent(EVENT_OUTRO_2, 17000);
|
||||
break;
|
||||
case EVENT_OUTRO_2:
|
||||
me->SetFacingTo(3.07f);
|
||||
events.ScheduleEvent(EVENT_OUTRO_3, 2000);
|
||||
break;
|
||||
case EVENT_OUTRO_3:
|
||||
SummonOrcs(-2046.158f, -3.0f, 37000, 30000, true);
|
||||
events.ScheduleEvent(EVENT_OUTRO_4, 2000);
|
||||
break;
|
||||
case EVENT_OUTRO_4:
|
||||
SummonOrcs(-2055.97f, -2.0f, 33000, 28000, false);
|
||||
events.ScheduleEvent(EVENT_OUTRO_5, 2000);
|
||||
break;
|
||||
case EVENT_OUTRO_5:
|
||||
SummonOrcs(-2064.0f, -1.5f, 29000, 26000, false);
|
||||
events.ScheduleEvent(EVENT_OUTRO_6, 2000);
|
||||
break;
|
||||
case EVENT_OUTRO_6:
|
||||
SummonOrcs(-2074.35f, -0.1f, 26000, 24000, false);
|
||||
events.ScheduleEvent(EVENT_OUTRO_7, 7000);
|
||||
break;
|
||||
case EVENT_OUTRO_7:
|
||||
Talk(SAY_ORCS_ENTER);
|
||||
events.ScheduleEvent(EVENT_OUTRO_8, 7000);
|
||||
break;
|
||||
case EVENT_OUTRO_8:
|
||||
if (Creature* cr = me->FindNearestCreature(NPC_SHADOW_COUNCIL_ENFORCER, 20.0f))
|
||||
{
|
||||
cr->SetFacingTo(3.07f);
|
||||
cr->AI()->Talk(SAY_ORCS_ANSWER);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void SummonOrcs(float x, float y, uint32 duration, uint32 homeTime, bool first)
|
||||
{
|
||||
for (uint8 i = 0; i < 6; ++i)
|
||||
{
|
||||
if (Creature* cr = me->SummonCreature(NPC_SHADOW_COUNCIL_ENFORCER, -2091.731f, 7133.083f - 3.0f*i, 34.589f, 0.0f))
|
||||
{
|
||||
cr->GetMotionMaster()->MovePoint(0, (first && i == 3) ? x+2.0f : x, cr->GetPositionY()+y, cr->GetMap()->GetHeight(x, cr->GetPositionY()+y, MAX_HEIGHT, true));
|
||||
cr->m_Events.AddEvent(new NpcRunToHome(*cr), cr->m_Events.CalculateTime(homeTime+urand(0, 2000)));
|
||||
cr->DespawnOrUnsummon(duration+urand(0, 2000));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
enum timeRift
|
||||
{
|
||||
EVENT_SUMMON_AT_RIFT = 1,
|
||||
EVENT_CHECK_DEATH = 2
|
||||
};
|
||||
|
||||
class npc_time_rift : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_time_rift() : CreatureScript("npc_time_rift") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_time_riftAI(creature);
|
||||
}
|
||||
|
||||
struct npc_time_riftAI : public NullCreatureAI
|
||||
{
|
||||
npc_time_riftAI(Creature* creature) : NullCreatureAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
riftKeeperGUID = 0;
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
InstanceScript* instance;
|
||||
uint64 riftKeeperGUID;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (instance->GetData(DATA_RIFT_NUMBER) >= 18)
|
||||
{
|
||||
me->DespawnOrUnsummon(30000);
|
||||
return;
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_SUMMON_AT_RIFT, 16000);
|
||||
events.ScheduleEvent(EVENT_CHECK_DEATH, 8000);
|
||||
}
|
||||
|
||||
void SetGUID(uint64 guid, int32)
|
||||
{
|
||||
riftKeeperGUID = guid;
|
||||
}
|
||||
|
||||
void DoSummonAtRift(uint32 entry)
|
||||
{
|
||||
Position pos;
|
||||
me->GetNearPosition(pos, 10.0f, 2*M_PI*rand_norm());
|
||||
|
||||
if (Creature* summon = me->SummonCreature(entry, pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000))
|
||||
if (Unit* medivh = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_MEDIVH)))
|
||||
{
|
||||
float o = medivh->GetAngle(summon)+frand(-1.0f, 1.0f);
|
||||
summon->SetHomePosition(medivh->GetPositionX() + 14.0f*cos(o), medivh->GetPositionY() + 14.0f*sin(o), medivh->GetPositionZ(), summon->GetAngle(medivh));
|
||||
summon->GetMotionMaster()->MoveTargetedHome();
|
||||
summon->SetReactState(REACT_DEFENSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void DoSelectSummon()
|
||||
{
|
||||
uint32 entry = RAND(NPC_INFINITE_ASSASIN, NPC_INFINITE_WHELP, NPC_INFINITE_CRONOMANCER, NPC_INFINITE_EXECUTIONER, NPC_INFINITE_VANQUISHER);
|
||||
if (entry == NPC_INFINITE_WHELP)
|
||||
{
|
||||
DoSummonAtRift(entry);
|
||||
DoSummonAtRift(entry);
|
||||
DoSummonAtRift(entry);
|
||||
}
|
||||
else
|
||||
DoSummonAtRift(entry);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SUMMON_AT_RIFT:
|
||||
DoSelectSummon();
|
||||
events.ScheduleEvent(EVENT_SUMMON_AT_RIFT, 15000);
|
||||
break;
|
||||
case EVENT_CHECK_DEATH:
|
||||
if (!me->HasUnitState(UNIT_STATE_CASTING))
|
||||
{
|
||||
Creature* riftKeeper = ObjectAccessor::GetCreature(*me, riftKeeperGUID);
|
||||
if (!riftKeeper || !riftKeeper->IsAlive())
|
||||
{
|
||||
instance->SetData(DATA_RIFT_KILLED, 1);
|
||||
me->DespawnOrUnsummon(0);
|
||||
break;
|
||||
}
|
||||
else
|
||||
me->CastSpell(riftKeeper, SPELL_RIFT_CHANNEL, false);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_DEATH, 500);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_black_morass_corrupt_medivh : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_black_morass_corrupt_medivh() : SpellScriptLoader("spell_black_morass_corrupt_medivh") { }
|
||||
|
||||
class spell_black_morass_corrupt_medivh_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_black_morass_corrupt_medivh_AuraScript);
|
||||
|
||||
void PeriodicTick(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
if (InstanceScript* instance = GetUnitOwner()->GetInstanceScript())
|
||||
instance->SetData(DATA_DAMAGE_SHIELD, 1);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_black_morass_corrupt_medivh_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_black_morass_corrupt_medivh_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_the_black_morass()
|
||||
{
|
||||
new npc_medivh_bm();
|
||||
new npc_time_rift();
|
||||
new spell_black_morass_corrupt_medivh();
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef DEF_THEBLACKMORASS_H
|
||||
#define DEF_THEBLACKMORASS_H
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
TYPE_CHRONO_LORD_DEJA = 0,
|
||||
TYPE_TEMPORUS = 1,
|
||||
TYPE_AEONUS = 2,
|
||||
MAX_ENCOUNTER = 3,
|
||||
|
||||
DATA_MEDIVH = 10,
|
||||
DATA_RIFT_KILLED = 11,
|
||||
DATA_DAMAGE_SHIELD = 12,
|
||||
DATA_SHIELD_PERCENT = 13,
|
||||
DATA_RIFT_NUMBER = 14,
|
||||
|
||||
DATA_SUMMONED_NPC = 20,
|
||||
DATA_DELETED_NPC = 21,
|
||||
};
|
||||
|
||||
enum WorldStateIds
|
||||
{
|
||||
WORLD_STATE_BM = 2541,
|
||||
WORLD_STATE_BM_SHIELD = 2540,
|
||||
WORLD_STATE_BM_RIFT = 2784
|
||||
};
|
||||
|
||||
enum QuestIds
|
||||
{
|
||||
QUEST_OPENING_PORTAL = 10297,
|
||||
QUEST_MASTER_TOUCH = 9836
|
||||
};
|
||||
|
||||
enum CreatureIds
|
||||
{
|
||||
NPC_MEDIVH = 15608,
|
||||
NPC_TIME_RIFT = 17838,
|
||||
NPC_TIME_KEEPER = 17918,
|
||||
|
||||
NPC_RIFT_KEEPER_WARLOCK = 21104,
|
||||
NPC_RIFT_KEEPER_MAGE = 21148,
|
||||
NPC_RIFT_LORD = 17839,
|
||||
NPC_RIFT_LORD_2 = 21140,
|
||||
|
||||
NPC_CHRONO_LORD_DEJA = 17879,
|
||||
NPC_INFINITE_CHRONO_LORD = 21697,
|
||||
NPC_TEMPORUS = 17880,
|
||||
NPC_INFINITE_TIMEREAVER = 21698,
|
||||
NPC_AEONUS = 17881,
|
||||
|
||||
NPC_INFINITE_ASSASIN = 17835,
|
||||
NPC_INFINITE_WHELP = 21818,
|
||||
NPC_INFINITE_CRONOMANCER = 17892,
|
||||
NPC_INFINITE_EXECUTIONER = 18994,
|
||||
NPC_INFINITE_VANQUISHER = 18995
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
SPELL_RIFT_CHANNEL = 31387,
|
||||
|
||||
EVENT_NEXT_PORTAL = 1,
|
||||
EVENT_SUMMON_KEEPER = 2,
|
||||
|
||||
ACTION_OUTRO = 1
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef DEF_DIRE_MAUL_H
|
||||
#define DEF_DIRE_MAUL_H
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
TYPE_EAST_WING_PROGRESS = 0,
|
||||
TYPE_WEST_WING_PROGRESS = 1,
|
||||
TYPE_PYLONS_STATE = 2,
|
||||
TYPE_NORTH_WING_PROGRESS = 3,
|
||||
TYPE_NORTH_WING_BOSSES = 4,
|
||||
|
||||
ALL_PYLONS_OFF = 0x1F
|
||||
};
|
||||
|
||||
enum GoIds
|
||||
{
|
||||
GO_DIRE_MAUL_FORCE_FIELD = 179503,
|
||||
GO_GORDOK_TRIBUTE = 179564
|
||||
};
|
||||
|
||||
enum NpcIds
|
||||
{
|
||||
NPC_IMMOL_THAR = 11496,
|
||||
NPC_HIGHBORNE_SUMMONER = 11466
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "dire_maul.h"
|
||||
|
||||
class instance_dire_maul : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_dire_maul() : InstanceMapScript("instance_dire_maul", 429) { }
|
||||
|
||||
struct instance_dire_maul_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_dire_maul_InstanceMapScript(Map* map) : InstanceScript(map) { }
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_eastWingProgress = 0;
|
||||
_westWingProgress = 0;
|
||||
_pylonsState = 0;
|
||||
_northWingProgress = 0;
|
||||
_northWingBosses = 0;
|
||||
_immoltharGUID = 0;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_IMMOL_THAR:
|
||||
_immoltharGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_HIGHBORNE_SUMMONER:
|
||||
if (_pylonsState == ALL_PYLONS_OFF)
|
||||
creature->DespawnOrUnsummon(5000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* gameobject)
|
||||
{
|
||||
switch (gameobject->GetEntry())
|
||||
{
|
||||
case GO_DIRE_MAUL_FORCE_FIELD:
|
||||
if (_pylonsState == ALL_PYLONS_OFF)
|
||||
gameobject->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_GORDOK_TRIBUTE:
|
||||
{
|
||||
uint32 fullLootMode = 0x3F;
|
||||
for (uint32 i = 0; i < _northWingBosses; ++i)
|
||||
fullLootMode >>= 1;
|
||||
|
||||
gameobject->SetLootMode(fullLootMode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_EAST_WING_PROGRESS:
|
||||
_eastWingProgress = data;
|
||||
instance->LoadGrid(-56.59f, -269.12f);
|
||||
break;
|
||||
case TYPE_WEST_WING_PROGRESS:
|
||||
_westWingProgress = data;
|
||||
instance->LoadGrid(132.626f, 625.913f);
|
||||
break;
|
||||
case TYPE_NORTH_WING_PROGRESS:
|
||||
_northWingProgress = data;
|
||||
break;
|
||||
case TYPE_NORTH_WING_BOSSES:
|
||||
_northWingBosses |= (1 << _northWingBosses);
|
||||
break;
|
||||
case TYPE_PYLONS_STATE:
|
||||
if (_pylonsState & data)
|
||||
return;
|
||||
_pylonsState |= data;
|
||||
if (_pylonsState == ALL_PYLONS_OFF) // all five active, 31
|
||||
{
|
||||
instance->LoadGrid(-38.08f, 812.44f);
|
||||
if (Creature* immol = instance->GetCreature(_immoltharGUID))
|
||||
{
|
||||
immol->setActive(true);
|
||||
immol->GetAI()->SetData(1, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const
|
||||
{
|
||||
if (type == TYPE_EAST_WING_PROGRESS)
|
||||
return _eastWingProgress;
|
||||
else if (type == TYPE_WEST_WING_PROGRESS)
|
||||
return _westWingProgress;
|
||||
else if (type == TYPE_NORTH_WING_PROGRESS)
|
||||
return _northWingProgress;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "D M " << _eastWingProgress << ' ' << _westWingProgress << ' ' << _pylonsState << ' ' << _northWingProgress << ' ' << _northWingBosses;
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
return;
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2;
|
||||
if (dataHead1 == 'D' && dataHead2 == 'M')
|
||||
{
|
||||
loadStream >> _eastWingProgress;
|
||||
loadStream >> _westWingProgress;
|
||||
loadStream >> _pylonsState;
|
||||
loadStream >> _northWingProgress;
|
||||
loadStream >> _northWingBosses;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _eastWingProgress;
|
||||
uint32 _westWingProgress;
|
||||
uint32 _pylonsState;
|
||||
uint32 _northWingProgress;
|
||||
uint32 _northWingBosses;
|
||||
|
||||
uint64 _immoltharGUID;
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_dire_maul_InstanceMapScript(map);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_dire_maul()
|
||||
{
|
||||
new instance_dire_maul();
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "maraudon.h"
|
||||
|
||||
class instance_maraudon : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_maraudon() : InstanceMapScript("instance_maraudon", 349) { }
|
||||
|
||||
struct instance_maraudon_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_maraudon_InstanceMapScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
memset(&_encounters, 0, sizeof(_encounters));
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* gameobject)
|
||||
{
|
||||
switch (gameobject->GetEntry())
|
||||
{
|
||||
case GO_CORRUPTION_SPEWER:
|
||||
if (_encounters[TYPE_NOXXION] == DONE)
|
||||
HandleGameObject(0, true, gameobject);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_NOXXION:
|
||||
_encounters[type] = data;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data == DONE)
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "M A " << _encounters[0];
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
return;
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2;
|
||||
if (dataHead1 == 'M' && dataHead2 == 'A')
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
|
||||
{
|
||||
loadStream >> _encounters[i];
|
||||
if (_encounters[i] == IN_PROGRESS)
|
||||
_encounters[i] = NOT_STARTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _encounters[MAX_ENCOUNTERS];
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_maraudon_InstanceMapScript(map);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_maraudon()
|
||||
{
|
||||
new instance_maraudon();
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef DEF_MARAUDON_H
|
||||
#define DEF_MARAUDON_H
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
TYPE_NOXXION = 0,
|
||||
MAX_ENCOUNTERS = 1,
|
||||
};
|
||||
|
||||
enum GoIds
|
||||
{
|
||||
GO_CORRUPTION_SPEWER = 178570
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,659 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "onyxias_lair.h"
|
||||
#include "Player.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
enum // Spells
|
||||
{
|
||||
SPELL_WINGBUFFET = 18500,
|
||||
SPELL_FLAMEBREATH = 18435,
|
||||
SPELL_CLEAVE = 68868,
|
||||
SPELL_TAILSWEEP = 68867,
|
||||
SPELL_FIREBALL = 18392,
|
||||
SPELL_BELLOWINGROAR = 18431,
|
||||
|
||||
SPELL_SUMMON_WHELP = 17646,
|
||||
SPELL_SUMMON_LAIR_GUARD = 68968,
|
||||
SPELL_ERUPTION = 17731,
|
||||
|
||||
SPELL_OLG_BLASTNOVA = 68958,
|
||||
SPELL_OLG_IGNITEWEAPON = 68959,
|
||||
|
||||
SPELL_BREATH_N_TO_S = 17086,
|
||||
SPELL_BREATH_S_TO_N = 18351,
|
||||
SPELL_BREATH_E_TO_W = 18576,
|
||||
SPELL_BREATH_W_TO_E = 18609,
|
||||
SPELL_BREATH_SE_TO_NW = 18564,
|
||||
SPELL_BREATH_NW_TO_SE = 18584,
|
||||
SPELL_BREATH_SW_TO_NE = 18596,
|
||||
SPELL_BREATH_NE_TO_SW = 18617,
|
||||
};
|
||||
|
||||
enum // Events
|
||||
{
|
||||
EVENT_SPELL_WINGBUFFET = 1,
|
||||
EVENT_SPELL_FLAMEBREATH = 2,
|
||||
EVENT_SPELL_TAILSWEEP = 3,
|
||||
EVENT_SPELL_CLEAVE = 4,
|
||||
EVENT_START_PHASE_2 = 5,
|
||||
EVENT_SPELL_FIREBALL_FIRST = 6,
|
||||
EVENT_SPELL_FIREBALL_SECOND = 7,
|
||||
EVENT_PHASE_2_STEP_CW = 8,
|
||||
EVENT_PHASE_2_STEP_ACW = 9,
|
||||
EVENT_PHASE_2_STEP_ACROSS = 10,
|
||||
EVENT_SPELL_BREATH = 11,
|
||||
EVENT_START_PHASE_3 = 12,
|
||||
EVENT_PHASE_3_ATTACK = 13,
|
||||
EVENT_SPELL_BELLOWINGROAR = 14,
|
||||
EVENT_WHELP_SPAM = 15,
|
||||
EVENT_SUMMON_LAIR_GUARD = 16,
|
||||
EVENT_SUMMON_WHELP = 17,
|
||||
EVENT_OLG_SPELL_BLASTNOVA = 18,
|
||||
EVENT_OLG_SPELL_IGNITEWEAPON = 19,
|
||||
EVENT_ERUPTION = 20,
|
||||
|
||||
EVENT_LIFTOFF = 31,
|
||||
EVENT_FLY_S_TO_N = 32,
|
||||
EVENT_LAND = 33,
|
||||
EVENT_END_MANY_WHELPS_TIME,
|
||||
};
|
||||
|
||||
struct sOnyxMove
|
||||
{
|
||||
uint8 CurrId, DestId;
|
||||
uint32 spellId;
|
||||
float x, y, z, o;
|
||||
};
|
||||
|
||||
static sOnyxMove OnyxiaMoveData[] =
|
||||
{
|
||||
{0, 0, 0, -64.496f, -214.906f, -84.4f, 0.0f}, // south ground
|
||||
{1, 5, SPELL_BREATH_S_TO_N, -64.496f, -214.906f, -60.0f, 0.0f}, // south
|
||||
{2, 6, SPELL_BREATH_SW_TO_NE, -59.809f, -190.758f, -60.0f, 7*M_PI/4}, // south-west
|
||||
{3, 7, SPELL_BREATH_W_TO_E, -29.450f, -180.600f, -60.0f, M_PI+M_PI/2}, // west
|
||||
{4, 8, SPELL_BREATH_NW_TO_SE, 6.895f, -180.246f, -60.0f, M_PI+M_PI/4}, // north-west
|
||||
{5, 1, SPELL_BREATH_N_TO_S, 22.876f, -217.152f, -60.0f, M_PI}, // north
|
||||
{6, 2, SPELL_BREATH_NE_TO_SW, 10.2191f, -247.912f, -60.0f, 3*M_PI/4}, // north-east
|
||||
{7, 3, SPELL_BREATH_E_TO_W, -31.496f, -250.123f, -60.0f, M_PI/2}, // east
|
||||
{8, 4, SPELL_BREATH_SE_TO_NW, -63.5156f, -240.096f, -60.0f, M_PI/4}, // south-east
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
// Say
|
||||
SAY_AGGRO = 0,
|
||||
SAY_KILL = 1,
|
||||
SAY_PHASE_2_TRANS = 2,
|
||||
SAY_PHASE_3_TRANS = 3,
|
||||
|
||||
// Emote
|
||||
EMOTE_BREATH = 4
|
||||
};
|
||||
|
||||
class boss_onyxia : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_onyxia() : CreatureScript("boss_onyxia") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_onyxiaAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_onyxiaAI : public ScriptedAI
|
||||
{
|
||||
boss_onyxiaAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
|
||||
InstanceScript* m_pInstance;
|
||||
uint8 Phase;
|
||||
int8 CurrentWP;
|
||||
|
||||
bool whelpSpam;
|
||||
uint8 whelpCount;
|
||||
int32 whelpSpamTimer;
|
||||
bool bManyWhelpsAvailable;
|
||||
|
||||
void SetPhase(uint8 ph)
|
||||
{
|
||||
events.Reset();
|
||||
Phase = ph;
|
||||
switch( ph )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
events.ScheduleEvent(EVENT_SPELL_WINGBUFFET, urand(10000, 20000));
|
||||
events.ScheduleEvent(EVENT_SPELL_FLAMEBREATH, urand(10000, 20000));
|
||||
events.ScheduleEvent(EVENT_SPELL_TAILSWEEP, urand(15000, 20000));
|
||||
events.ScheduleEvent(EVENT_SPELL_CLEAVE, urand(2000, 5000));
|
||||
break;
|
||||
case 2:
|
||||
events.ScheduleEvent(EVENT_START_PHASE_2, 0);
|
||||
break;
|
||||
case 3:
|
||||
events.ScheduleEvent(EVENT_START_PHASE_3, 5000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
CurrentWP = 0;
|
||||
SetPhase(0);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetCanFly(false);
|
||||
me->SetDisableGravity(false);
|
||||
me->SetHover(false);
|
||||
me->SetSpeed(MOVE_RUN, me->GetCreatureTemplate()->speed_run, false);
|
||||
|
||||
whelpSpam = false;
|
||||
whelpCount = 0;
|
||||
whelpSpamTimer = 0;
|
||||
bManyWhelpsAvailable = false;
|
||||
|
||||
if( m_pInstance )
|
||||
{
|
||||
m_pInstance->SetData(DATA_ONYXIA, NOT_STARTED);
|
||||
m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit *who)
|
||||
{
|
||||
if( me->GetVictim() || me->GetDistance(who) > 30.0f )
|
||||
return;
|
||||
|
||||
if( who->GetTypeId() == TYPEID_PLAYER )
|
||||
AttackStart(who);
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
switch( param )
|
||||
{
|
||||
case -1:
|
||||
if( bManyWhelpsAvailable && m_pInstance )
|
||||
m_pInstance->SetData(DATA_WHELP_SUMMONED, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BindPlayers()
|
||||
{
|
||||
me->GetMap()->ToInstanceMap()->PermBindAllPlayers();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
DoZoneInCombat();
|
||||
SetPhase(1);
|
||||
|
||||
if( m_pInstance )
|
||||
{
|
||||
m_pInstance->SetData(DATA_ONYXIA, IN_PROGRESS);
|
||||
m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT); // just in case at reset some players already left the instance
|
||||
m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
|
||||
}
|
||||
BindPlayers();
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
if( m_pInstance )
|
||||
m_pInstance->SetData(DATA_ONYXIA, DONE);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
switch( Phase )
|
||||
{
|
||||
case 1:
|
||||
if( me->GetHealth()*100 / me->GetMaxHealth() <= 65 )
|
||||
SetPhase(2);
|
||||
break;
|
||||
case 2:
|
||||
if( me->GetHealth()*100 / me->GetMaxHealth() <= 40 )
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
SetPhase(3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature *pSummoned)
|
||||
{
|
||||
if( !pSummoned )
|
||||
return;
|
||||
if( pSummoned->GetEntry() != NPC_ONYXIAN_WHELP && pSummoned->GetEntry() != NPC_ONYXIAN_LAIR_GUARD )
|
||||
return;
|
||||
if( Unit* target = pSummoned->SelectNearestTarget(300.0f) )
|
||||
{
|
||||
pSummoned->AI()->AttackStart(target);
|
||||
DoZoneInCombat(pSummoned);
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if( type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE )
|
||||
return;
|
||||
|
||||
if( id < 9 )
|
||||
{
|
||||
if( id > 0 && Phase == 2 )
|
||||
{
|
||||
me->SetFacingTo(OnyxiaMoveData[id].o);
|
||||
me->SetSpeed(MOVE_RUN, 1.6f, false);
|
||||
CurrentWP = id;
|
||||
events.ScheduleEvent(EVENT_SPELL_FIREBALL_FIRST, 1000);
|
||||
}
|
||||
}
|
||||
else switch( id )
|
||||
{
|
||||
case 10:
|
||||
me->SetFacingTo(OnyxiaMoveData[0].o);
|
||||
events.ScheduleEvent(EVENT_LIFTOFF, 0);
|
||||
break;
|
||||
case 11:
|
||||
me->SetFacingTo(OnyxiaMoveData[1].o);
|
||||
events.ScheduleEvent(EVENT_FLY_S_TO_N, 0);
|
||||
break;
|
||||
case 12:
|
||||
me->SetFacingTo(OnyxiaMoveData[1].o);
|
||||
events.ScheduleEvent(EVENT_LAND, 0);
|
||||
break;
|
||||
case 13:
|
||||
me->SetCanFly(false);
|
||||
me->SetDisableGravity(false);
|
||||
me->SetHover(false);
|
||||
me->SetSpeed(MOVE_RUN, me->GetCreatureTemplate()->speed_run, false);
|
||||
events.ScheduleEvent(EVENT_PHASE_3_ATTACK, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleWhelpSpam(const uint32 diff)
|
||||
{
|
||||
if( whelpSpam )
|
||||
{
|
||||
if( whelpCount < 40 )
|
||||
{
|
||||
whelpSpamTimer -= diff;
|
||||
if( whelpSpamTimer <= 0 )
|
||||
{
|
||||
float angle = rand_norm()*2*M_PI;
|
||||
float dist = rand_norm()*4.0f;
|
||||
me->CastSpell(-33.18f + cos(angle)*dist, -258.80f + sin(angle)*dist, -89.0f, 17646, true);
|
||||
me->CastSpell(-32.535f + cos(angle)*dist, -170.190f + sin(angle)*dist, -89.0f, 17646, true);
|
||||
whelpCount += 2;
|
||||
whelpSpamTimer += 600;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
whelpSpam = false;
|
||||
whelpCount = 0;
|
||||
whelpSpamTimer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
HandleWhelpSpam(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_SPELL_WINGBUFFET:
|
||||
{
|
||||
me->CastSpell(me, SPELL_WINGBUFFET, false);
|
||||
events.RepeatEvent(urand(15000, 30000));
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_FLAMEBREATH:
|
||||
{
|
||||
me->CastSpell(me, SPELL_FLAMEBREATH, false);
|
||||
events.RepeatEvent(urand(10000, 20000));
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_TAILSWEEP:
|
||||
{
|
||||
me->CastSpell(me, SPELL_TAILSWEEP, false);
|
||||
events.RepeatEvent(urand(15000, 20000));
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_CLEAVE:
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
|
||||
events.RepeatEvent(urand(2000, 5000));
|
||||
}
|
||||
break;
|
||||
case EVENT_START_PHASE_2:
|
||||
{
|
||||
me->AttackStop();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->StopMoving();
|
||||
DoResetThreat();
|
||||
me->GetMotionMaster()->MovePoint(10, OnyxiaMoveData[0].x, OnyxiaMoveData[0].y, OnyxiaMoveData[0].z);
|
||||
events.PopEvent();
|
||||
}
|
||||
break;
|
||||
case EVENT_LIFTOFF:
|
||||
{
|
||||
Talk(SAY_PHASE_2_TRANS);
|
||||
me->SendMeleeAttackStop(me->GetVictim());
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->DisableSpline();
|
||||
me->SetCanFly(true);
|
||||
me->SetDisableGravity(true);
|
||||
me->SetHover(true);
|
||||
me->SetOrientation(OnyxiaMoveData[0].o);
|
||||
me->SendMovementFlagUpdate();
|
||||
me->GetMotionMaster()->MoveTakeoff(11, OnyxiaMoveData[1].x+1.0f, OnyxiaMoveData[1].y, OnyxiaMoveData[1].z, 12.0f);
|
||||
bManyWhelpsAvailable = true;
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(EVENT_END_MANY_WHELPS_TIME, 10000);
|
||||
}
|
||||
break;
|
||||
case EVENT_END_MANY_WHELPS_TIME:
|
||||
bManyWhelpsAvailable = false;
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_FLY_S_TO_N:
|
||||
{
|
||||
me->SetSpeed(MOVE_RUN, 2.95f, false);
|
||||
me->GetMotionMaster()->MovePoint(5, OnyxiaMoveData[5].x, OnyxiaMoveData[5].y, OnyxiaMoveData[5].z);
|
||||
events.PopEvent();
|
||||
whelpSpam = true;
|
||||
events.ScheduleEvent(EVENT_WHELP_SPAM, 90000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_LAIR_GUARD, 30000);
|
||||
}
|
||||
break;
|
||||
case EVENT_SUMMON_LAIR_GUARD:
|
||||
{
|
||||
me->CastSpell(-101.654f, -214.491f, -80.70f, SPELL_SUMMON_LAIR_GUARD, true);
|
||||
events.RepeatEvent(30000);
|
||||
}
|
||||
break;
|
||||
case EVENT_WHELP_SPAM:
|
||||
{
|
||||
whelpSpam = true;
|
||||
events.RepeatEvent(90000);
|
||||
}
|
||||
break;
|
||||
case EVENT_LAND:
|
||||
{
|
||||
Talk(SAY_PHASE_3_TRANS);
|
||||
me->SendMeleeAttackStop(me->GetVictim());
|
||||
me->GetMotionMaster()->MoveLand(13, OnyxiaMoveData[0].x+1.0f, OnyxiaMoveData[0].y, OnyxiaMoveData[0].z, 12.0f);
|
||||
events.PopEvent();
|
||||
DoResetThreat();
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_FIREBALL_FIRST:
|
||||
{
|
||||
if( Unit* v = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true) )
|
||||
{
|
||||
me->SetFacingToObject(v);
|
||||
me->CastSpell(v, SPELL_FIREBALL, false);
|
||||
}
|
||||
events.PopEvent();
|
||||
events.ScheduleEvent(EVENT_SPELL_FIREBALL_SECOND, 4000);
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_FIREBALL_SECOND:
|
||||
{
|
||||
if( Unit* v = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true) )
|
||||
{
|
||||
me->SetFacingToObject(v);
|
||||
me->CastSpell(v, SPELL_FIREBALL, false);
|
||||
}
|
||||
events.PopEvent();
|
||||
|
||||
uint8 rand = urand(0, 99);
|
||||
if( rand < 33 )
|
||||
events.ScheduleEvent(EVENT_PHASE_2_STEP_CW, 4000);
|
||||
else if( rand < 66 )
|
||||
events.ScheduleEvent(EVENT_PHASE_2_STEP_ACW, 4000);
|
||||
else
|
||||
events.ScheduleEvent(EVENT_PHASE_2_STEP_ACROSS, 4000);
|
||||
}
|
||||
break;
|
||||
case EVENT_PHASE_2_STEP_CW:
|
||||
{
|
||||
uint8 newWP = CurrentWP + 1;
|
||||
if( newWP > 8 )
|
||||
newWP = 1;
|
||||
me->GetMotionMaster()->MovePoint(newWP, OnyxiaMoveData[newWP].x, OnyxiaMoveData[newWP].y, OnyxiaMoveData[newWP].z);
|
||||
events.PopEvent();
|
||||
}
|
||||
break;
|
||||
case EVENT_PHASE_2_STEP_ACW:
|
||||
{
|
||||
uint8 newWP = CurrentWP - 1;
|
||||
if( newWP < 1 )
|
||||
newWP = 8;
|
||||
me->GetMotionMaster()->MovePoint(newWP, OnyxiaMoveData[newWP].x, OnyxiaMoveData[newWP].y, OnyxiaMoveData[newWP].z);
|
||||
events.PopEvent();
|
||||
}
|
||||
break;
|
||||
case EVENT_PHASE_2_STEP_ACROSS:
|
||||
{
|
||||
me->SetFacingTo(OnyxiaMoveData[CurrentWP].o);
|
||||
me->MonsterTextEmote("Onyxia takes in a deep breath...", 0, true);
|
||||
me->CastSpell(me, OnyxiaMoveData[CurrentWP].spellId, false);
|
||||
events.PopEvent();
|
||||
events.ScheduleEvent(EVENT_SPELL_BREATH, 8250);
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_BREATH:
|
||||
{
|
||||
uint8 newWP = OnyxiaMoveData[CurrentWP].DestId;
|
||||
me->SetSpeed(MOVE_RUN, 2.95f, false);
|
||||
me->GetMotionMaster()->MovePoint(newWP, OnyxiaMoveData[newWP].x, OnyxiaMoveData[newWP].y, OnyxiaMoveData[newWP].z);
|
||||
events.PopEvent();
|
||||
}
|
||||
break;
|
||||
case EVENT_START_PHASE_3:
|
||||
{
|
||||
me->SetSpeed(MOVE_RUN, 2.95f, false);
|
||||
me->GetMotionMaster()->MovePoint(12, OnyxiaMoveData[1].x, OnyxiaMoveData[1].y, OnyxiaMoveData[1].z);
|
||||
events.PopEvent();
|
||||
}
|
||||
break;
|
||||
case EVENT_PHASE_3_ATTACK:
|
||||
{
|
||||
events.PopEvent();
|
||||
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
AttackStart(SelectTarget(SELECT_TARGET_TOPAGGRO, 0, 0, false));
|
||||
me->CastSpell(me, SPELL_BELLOWINGROAR, false);
|
||||
|
||||
events.ScheduleEvent(EVENT_ERUPTION, 0);
|
||||
events.ScheduleEvent(EVENT_SPELL_WINGBUFFET, urand(10000, 20000));
|
||||
events.ScheduleEvent(EVENT_SPELL_FLAMEBREATH, urand(10000, 20000));
|
||||
events.ScheduleEvent(EVENT_SPELL_TAILSWEEP, urand(15000, 20000));
|
||||
events.ScheduleEvent(EVENT_SPELL_CLEAVE, urand(2000, 5000));
|
||||
events.ScheduleEvent(EVENT_SPELL_BELLOWINGROAR, 15000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_WHELP, 10000);
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_BELLOWINGROAR:
|
||||
{
|
||||
me->CastSpell(me, SPELL_BELLOWINGROAR, false);
|
||||
events.RepeatEvent(22000);
|
||||
events.ScheduleEvent(EVENT_ERUPTION, 0);
|
||||
}
|
||||
break;
|
||||
case EVENT_ERUPTION:
|
||||
{
|
||||
if( Creature* trigger = me->SummonCreature(12758, *me, TEMPSUMMON_TIMED_DESPAWN, 1000) )
|
||||
trigger->CastSpell(trigger, 17731, false);
|
||||
|
||||
events.PopEvent();
|
||||
}
|
||||
break;
|
||||
case EVENT_SUMMON_WHELP:
|
||||
{
|
||||
float angle = rand_norm()*2*M_PI;
|
||||
float dist = rand_norm()*4.0f;
|
||||
me->CastSpell(-33.18f + cos(angle)*dist, -258.80f + sin(angle)*dist, -89.0f, 17646, true);
|
||||
me->CastSpell(-32.535f + cos(angle)*dist, -170.190f + sin(angle)*dist, -89.0f, 17646, true);
|
||||
events.RepeatEvent(30000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, const SpellInfo* spell)
|
||||
{
|
||||
if (target->GetTypeId() == TYPEID_PLAYER && spell->DurationEntry && spell->DurationEntry->ID == 328 && spell->Effects[EFFECT_1].TargetA.GetTarget() == 1 && (spell->Effects[EFFECT_1].Amplitude == 50 || spell->Effects[EFFECT_1].Amplitude == 215)) // Deep Breath
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(DATA_DEEP_BREATH_FAILED, 1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_onyxian_lair_guard : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_onyxian_lair_guard() : CreatureScript("npc_onyxian_lair_guard") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_onyxian_lair_guardAI (pCreature);
|
||||
}
|
||||
|
||||
struct npc_onyxian_lair_guardAI : public ScriptedAI
|
||||
{
|
||||
npc_onyxian_lair_guardAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_OLG_SPELL_BLASTNOVA, 15000);
|
||||
events.ScheduleEvent(EVENT_OLG_SPELL_IGNITEWEAPON, 10000);
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
|
||||
void MoveInLineOfSight(Unit *who)
|
||||
{
|
||||
if( me->GetVictim() || me->GetDistance(who) > 20.0f )
|
||||
return;
|
||||
|
||||
if( who->GetTypeId() == TYPEID_PLAYER )
|
||||
AttackStart(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_OLG_SPELL_BLASTNOVA:
|
||||
me->CastSpell(me, SPELL_OLG_BLASTNOVA, false);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
case EVENT_OLG_SPELL_IGNITEWEAPON:
|
||||
if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED))
|
||||
events.RepeatEvent(5000);
|
||||
else
|
||||
{
|
||||
me->CastSpell(me, SPELL_OLG_IGNITEWEAPON, false);
|
||||
events.RepeatEvent(urand(18000, 21000));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!me->HasUnitState(UNIT_STATE_CASTING) && me->isAttackReady())
|
||||
if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED))
|
||||
if (me->HasAura(SPELL_OLG_IGNITEWEAPON))
|
||||
me->RemoveAura(SPELL_OLG_IGNITEWEAPON);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_onyxia_whelp : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_onyxia_whelp() : CreatureScript("npc_onyxia_whelp") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_onyxia_whelpAI (pCreature);
|
||||
}
|
||||
|
||||
struct npc_onyxia_whelpAI : public ScriptedAI
|
||||
{
|
||||
npc_onyxia_whelpAI(Creature* pCreature) : ScriptedAI(pCreature) {}
|
||||
|
||||
void MoveInLineOfSight(Unit *who)
|
||||
{
|
||||
if( me->GetVictim() || me->GetDistance(who) > 20.0f )
|
||||
return;
|
||||
|
||||
if( who->GetTypeId() == TYPEID_PLAYER )
|
||||
AttackStart(who);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_onyxia_trigger : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_onyxia_trigger() : CreatureScript("npc_onyxia_trigger") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_onyxia_triggerAI (pCreature);
|
||||
}
|
||||
|
||||
struct npc_onyxia_triggerAI : public ScriptedAI
|
||||
{
|
||||
npc_onyxia_triggerAI(Creature* pCreature) : ScriptedAI(pCreature) {}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) {}
|
||||
void UpdateAI(uint32 diff) {}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_boss_onyxia()
|
||||
{
|
||||
new boss_onyxia();
|
||||
new npc_onyxian_lair_guard();
|
||||
new npc_onyxia_whelp();
|
||||
new npc_onyxia_trigger();
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "onyxias_lair.h"
|
||||
|
||||
class instance_onyxias_lair : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_onyxias_lair() : InstanceMapScript("instance_onyxias_lair", 249) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* pMap) const
|
||||
{
|
||||
return new instance_onyxias_lair_InstanceMapScript(pMap);
|
||||
}
|
||||
|
||||
struct instance_onyxias_lair_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_onyxias_lair_InstanceMapScript(Map* pMap) : InstanceScript(pMap) {Initialize();};
|
||||
|
||||
uint64 m_uiOnyxiasGUID;
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
std::string str_data;
|
||||
uint16 ManyWhelpsCounter;
|
||||
std::vector<uint64> minions;
|
||||
bool bDeepBreath;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
m_uiOnyxiasGUID = 0;
|
||||
ManyWhelpsCounter = 0;
|
||||
bDeepBreath = true;
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
for( uint8 i=0; i<MAX_ENCOUNTER; ++i )
|
||||
if( m_auiEncounter[i] == IN_PROGRESS )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* pCreature)
|
||||
{
|
||||
switch( pCreature->GetEntry() )
|
||||
{
|
||||
case NPC_ONYXIA:
|
||||
m_uiOnyxiasGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_ONYXIAN_WHELP:
|
||||
case NPC_ONYXIAN_LAIR_GUARD:
|
||||
minions.push_back(pCreature->GetGUID());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go)
|
||||
{
|
||||
switch( go->GetEntry() )
|
||||
{
|
||||
case GO_WHELP_SPAWNER:
|
||||
go->CastSpell((Unit*)NULL, 17646);
|
||||
if( Creature* onyxia = instance->GetCreature(m_uiOnyxiasGUID) )
|
||||
onyxia->AI()->DoAction(-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 uiType, uint32 uiData)
|
||||
{
|
||||
switch(uiType)
|
||||
{
|
||||
case DATA_ONYXIA:
|
||||
m_auiEncounter[0] = uiData;
|
||||
ManyWhelpsCounter = 0;
|
||||
bDeepBreath = true;
|
||||
if( uiData == NOT_STARTED )
|
||||
{
|
||||
for( std::vector<uint64>::iterator itr = minions.begin(); itr != minions.end(); ++itr )
|
||||
if( Creature* c = instance->GetCreature(*itr) )
|
||||
c->DespawnOrUnsummon();
|
||||
minions.clear();
|
||||
}
|
||||
break;
|
||||
case DATA_WHELP_SUMMONED:
|
||||
++ManyWhelpsCounter;
|
||||
break;
|
||||
case DATA_DEEP_BREATH_FAILED:
|
||||
bDeepBreath = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (uiType < MAX_ENCOUNTER && uiData == DONE)
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 uiType) const
|
||||
{
|
||||
switch(uiType)
|
||||
{
|
||||
case DATA_ONYXIA:
|
||||
return m_auiEncounter[0];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 uiData) const
|
||||
{
|
||||
switch(uiData)
|
||||
{
|
||||
case DATA_ONYXIA:
|
||||
return m_uiOnyxiasGUID;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "O L " << m_auiEncounter[0];
|
||||
str_data = saveStream.str();
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return str_data;
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if( !in )
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
uint16 data0;
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2 >> data0;
|
||||
|
||||
if( dataHead1 == 'O' && dataHead2 == 'L' )
|
||||
{
|
||||
m_auiEncounter[0] = data0;
|
||||
|
||||
for( uint8 i = 0; i < MAX_ENCOUNTER; ++i )
|
||||
if( m_auiEncounter[i] == IN_PROGRESS )
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
}
|
||||
else
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* target = NULL, uint32 miscvalue1 = 0)
|
||||
{
|
||||
switch(criteria_id)
|
||||
{
|
||||
case ACHIEV_CRITERIA_MANY_WHELPS_10_PLAYER:
|
||||
case ACHIEV_CRITERIA_MANY_WHELPS_25_PLAYER:
|
||||
return ManyWhelpsCounter>=50;
|
||||
case ACHIEV_CRITERIA_DEEP_BREATH_10_PLAYER:
|
||||
case ACHIEV_CRITERIA_DEEP_BREATH_25_PLAYER:
|
||||
return bDeepBreath;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_instance_onyxias_lair()
|
||||
{
|
||||
new instance_onyxias_lair();
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#ifndef DEF_ONYXIAS_LAIR_H
|
||||
#define DEF_ONYXIAS_LAIR_H
|
||||
|
||||
enum eInstanceData
|
||||
{
|
||||
DATA_ONYXIA = 0,
|
||||
MAX_ENCOUNTER = 1,
|
||||
DATA_WHELP_SUMMONED,
|
||||
DATA_DEEP_BREATH_FAILED,
|
||||
};
|
||||
|
||||
enum eCreatures
|
||||
{
|
||||
NPC_ONYXIA = 10184,
|
||||
NPC_ONYXIAN_WHELP = 11262,
|
||||
NPC_ONYXIAN_LAIR_GUARD = 36561,
|
||||
};
|
||||
|
||||
enum eGameObjects
|
||||
{
|
||||
GO_WHELP_SPAWNER = 176510,
|
||||
GO_WHELP_EGG = 176511
|
||||
};
|
||||
|
||||
enum eAchievementData
|
||||
{
|
||||
ACHIEV_CRITERIA_MANY_WHELPS_10_PLAYER = 12565, // Criteria for achievement 4403: Many Whelps! Handle It! (10 player) Hatch 50 eggs in 10s
|
||||
ACHIEV_CRITERIA_MANY_WHELPS_25_PLAYER = 12568, // Criteria for achievement 4406: Many Whelps! Handle It! (25 player) Hatch 50 eggs in 10s
|
||||
ACHIEV_CRITERIA_DEEP_BREATH_10_PLAYER = 12566, // Criteria for achievement 4404: She Deep Breaths More (10 player) Everybody evade Deep Breath
|
||||
ACHIEV_CRITERIA_DEEP_BREATH_25_PLAYER = 12569, // Criteria for achievement 4407: She Deep Breaths More (25 player) Everybody evade Deep Breath
|
||||
ACHIEV_TIMED_START_EVENT = 6601, // Timed event for achievement 4402, 4005: More Dots! (10,25 player) 5 min kill
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
|
||||
class instance_ragefire_chasm : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_ragefire_chasm() : InstanceMapScript("instance_ragefire_chasm", 389) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_ragefire_chasm_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
struct instance_ragefire_chasm_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_ragefire_chasm_InstanceMapScript(Map* map) : InstanceScript(map) { }
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_instance_ragefire_chasm()
|
||||
{
|
||||
new instance_ragefire_chasm();
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "razorfen_downs.h"
|
||||
|
||||
class instance_razorfen_downs : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_razorfen_downs() : InstanceMapScript("instance_razorfen_downs", 129) { }
|
||||
|
||||
struct instance_razorfen_downs_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_razorfen_downs_InstanceMapScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_gongPhase = 0;
|
||||
_firesState = 0;
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* gameobject)
|
||||
{
|
||||
switch (gameobject->GetEntry())
|
||||
{
|
||||
case GO_IDOL_OVEN_FIRE:
|
||||
case GO_IDOL_CUP_FIRE:
|
||||
case GO_IDOL_MOUTH_FIRE:
|
||||
if (_firesState == DONE)
|
||||
gameobject->Delete();
|
||||
break;
|
||||
case GO_GONG:
|
||||
if (_gongPhase == DONE)
|
||||
gameobject->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const
|
||||
{
|
||||
if (type == GO_GONG)
|
||||
return _gongPhase;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
if (type == GO_GONG)
|
||||
_gongPhase = data;
|
||||
else if (type == GO_BELNISTRASZS_BRAZIER)
|
||||
_firesState = DONE;
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "R D " << _gongPhase << ' ' << _firesState;
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* str)
|
||||
{
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
std::istringstream loadStream(str);
|
||||
loadStream >> dataHead1 >> dataHead2;
|
||||
|
||||
if (dataHead1 == 'R' && dataHead2 == 'D')
|
||||
{
|
||||
loadStream >> _gongPhase;
|
||||
loadStream >> _firesState;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _gongPhase;
|
||||
uint32 _firesState;
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_razorfen_downs_InstanceMapScript(map);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_razorfen_downs()
|
||||
{
|
||||
new instance_razorfen_downs();
|
||||
}
|
||||
@@ -1,272 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "razorfen_downs.h"
|
||||
#include "Player.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "Cell.h"
|
||||
#include "CellImpl.h"
|
||||
|
||||
/*######
|
||||
## npc_belnistrasz for Quest 3525 "Extinguishing the Idol"
|
||||
######*/
|
||||
|
||||
Position const PosSummonSpawner[3] =
|
||||
{
|
||||
{ 2582.789f, 954.3925f, 52.48214f, 3.787364f },
|
||||
{ 2569.42f, 956.3801f, 52.27323f, 5.427974f },
|
||||
{ 2570.62f, 942.3934f, 53.7433f, 0.715585f }
|
||||
};
|
||||
|
||||
enum Belnistrasz
|
||||
{
|
||||
EVENT_CHANNEL = 1,
|
||||
EVENT_IDOL_ROOM_SPAWNER = 2,
|
||||
EVENT_PROGRESS = 3,
|
||||
EVENT_COMPLETE = 4,
|
||||
EVENT_FIREBALL = 5,
|
||||
EVENT_FROST_NOVA = 6,
|
||||
|
||||
FACTION_ESCORT = 250,
|
||||
|
||||
PATH_ESCORT = 871710,
|
||||
POINT_REACH_IDOL = 17,
|
||||
|
||||
QUEST_EXTINGUISHING_THE_IDOL = 3525,
|
||||
|
||||
SAY_QUEST_ACCEPTED = 0,
|
||||
SAY_EVENT_START = 1,
|
||||
SAY_EVENT_THREE_MIN_LEFT = 2,
|
||||
SAY_EVENT_TWO_MIN_LEFT = 3,
|
||||
SAY_EVENT_ONE_MIN_LEFT = 4,
|
||||
SAY_EVENT_END = 5,
|
||||
SAY_AGGRO = 6, // Combat
|
||||
SAY_WATCH_OUT = 7, // 25% chance to target random creature and say on wave spawn
|
||||
|
||||
SPELL_ARCANE_INTELLECT = 13326,
|
||||
SPELL_FIREBALL = 9053,
|
||||
SPELL_FROST_NOVA = 11831,
|
||||
SPELL_IDOL_SHUTDOWN_VISUAL = 12774, // Hits Unit Entry: 8662
|
||||
SPELL_IDOM_ROOM_CAMERA_SHAKE = 12816 // Dummy needs scripting
|
||||
};
|
||||
|
||||
class npc_belnistrasz : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_belnistrasz() : CreatureScript("npc_belnistrasz") { }
|
||||
|
||||
struct npc_belnistraszAI : public ScriptedAI
|
||||
{
|
||||
npc_belnistraszAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
eventInProgress = false;
|
||||
spawnerCount = 0;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (!eventInProgress)
|
||||
{
|
||||
if (!me->HasAura(SPELL_ARCANE_INTELLECT))
|
||||
DoCast(me, SPELL_ARCANE_INTELLECT);
|
||||
|
||||
channeling = false;
|
||||
eventProgress = 0;
|
||||
spawnerCount = 0;
|
||||
me->SetFlag(UNIT_NPC_FLAGS, GOSSIP_OPTION_QUESTGIVER);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
if (channeling)
|
||||
Talk(SAY_WATCH_OUT, who);
|
||||
else
|
||||
{
|
||||
events.ScheduleEvent(EVENT_FIREBALL, 1000);
|
||||
events.ScheduleEvent(EVENT_FROST_NOVA, urand(8000, 12000));
|
||||
if (urand(0, 100) > 40)
|
||||
Talk(SAY_AGGRO, who);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
me->DespawnOrUnsummon(5000);
|
||||
}
|
||||
|
||||
void sQuestAccept(Player* /*player*/, Quest const* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_EXTINGUISHING_THE_IDOL)
|
||||
{
|
||||
eventInProgress = true;
|
||||
Talk(SAY_QUEST_ACCEPTED);
|
||||
me->RemoveFlag(UNIT_NPC_FLAGS, GOSSIP_OPTION_QUESTGIVER);
|
||||
me->setFaction(FACTION_ESCORT);
|
||||
me->GetMotionMaster()->MovePath(PATH_ESCORT, false);
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type == WAYPOINT_MOTION_TYPE && id == POINT_REACH_IDOL)
|
||||
{
|
||||
channeling = true;
|
||||
events.ScheduleEvent(EVENT_CHANNEL, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!eventInProgress)
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_CHANNEL:
|
||||
Talk(SAY_EVENT_START);
|
||||
DoCast(me, SPELL_IDOL_SHUTDOWN_VISUAL);
|
||||
events.ScheduleEvent(EVENT_IDOL_ROOM_SPAWNER, 100);
|
||||
events.ScheduleEvent(EVENT_PROGRESS, 120000);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
break;
|
||||
case EVENT_IDOL_ROOM_SPAWNER:
|
||||
if (Creature* creature = me->SummonCreature(NPC_IDOL_ROOM_SPAWNER, PosSummonSpawner[urand(0,2)], TEMPSUMMON_TIMED_DESPAWN, 4000))
|
||||
creature->AI()->SetData(0,spawnerCount);
|
||||
if (++spawnerCount < 8)
|
||||
events.ScheduleEvent(EVENT_IDOL_ROOM_SPAWNER, 35000);
|
||||
break;
|
||||
case EVENT_PROGRESS:
|
||||
{
|
||||
switch (eventProgress)
|
||||
{
|
||||
case 0:
|
||||
Talk(SAY_EVENT_THREE_MIN_LEFT);
|
||||
++eventProgress;
|
||||
events.ScheduleEvent(EVENT_PROGRESS, 60000);
|
||||
break;
|
||||
case 1:
|
||||
Talk(SAY_EVENT_TWO_MIN_LEFT);
|
||||
++eventProgress;
|
||||
events.ScheduleEvent(EVENT_PROGRESS, 60000);
|
||||
break;
|
||||
case 2:
|
||||
Talk(SAY_EVENT_ONE_MIN_LEFT);
|
||||
++eventProgress;
|
||||
events.ScheduleEvent(EVENT_PROGRESS, 60000);
|
||||
break;
|
||||
case 3:
|
||||
events.CancelEvent(EVENT_IDOL_ROOM_SPAWNER);
|
||||
me->InterruptSpell(CURRENT_CHANNELED_SPELL);
|
||||
Talk(SAY_EVENT_END);
|
||||
events.ScheduleEvent(EVENT_COMPLETE, 3000);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_COMPLETE:
|
||||
{
|
||||
DoCast(me, SPELL_IDOM_ROOM_CAMERA_SHAKE);
|
||||
me->SummonGameObject(GO_BELNISTRASZS_BRAZIER, 2577.196f, 947.0781f, 53.16757f, 2.356195f, 0, 0, 0.9238796f, 0.3826832f, 3600);
|
||||
std::list<WorldObject*> ClusterList;
|
||||
Trinity::AllWorldObjectsInRange objects(me, 50.0f);
|
||||
Trinity::WorldObjectListSearcher<Trinity::AllWorldObjectsInRange> searcher(me, ClusterList, objects);
|
||||
me->VisitNearbyObject(50.0f, searcher);
|
||||
for (std::list<WorldObject*>::const_iterator itr = ClusterList.begin(); itr != ClusterList.end(); ++itr)
|
||||
{
|
||||
if (Player* player = (*itr)->ToPlayer())
|
||||
{
|
||||
if (player->GetQuestStatus(QUEST_EXTINGUISHING_THE_IDOL) == QUEST_STATUS_INCOMPLETE)
|
||||
player->CompleteQuest(QUEST_EXTINGUISHING_THE_IDOL);
|
||||
}
|
||||
else if (GameObject* go = (*itr)->ToGameObject())
|
||||
{
|
||||
if (go->GetEntry() == GO_IDOL_OVEN_FIRE || go->GetEntry() == GO_IDOL_CUP_FIRE || go->GetEntry() == GO_IDOL_MOUTH_FIRE)
|
||||
go->Delete();
|
||||
}
|
||||
}
|
||||
instance->SetData(GO_BELNISTRASZS_BRAZIER, DONE);
|
||||
me->DespawnOrUnsummon();
|
||||
break;
|
||||
}
|
||||
case EVENT_FIREBALL:
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING) || !UpdateVictim())
|
||||
return;
|
||||
DoCastVictim(SPELL_FIREBALL);
|
||||
events.ScheduleEvent(EVENT_FIREBALL, 8000);
|
||||
break;
|
||||
case EVENT_FROST_NOVA:
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING) || !UpdateVictim())
|
||||
return;
|
||||
DoCast(me, SPELL_FROST_NOVA);
|
||||
events.ScheduleEvent(EVENT_FROST_NOVA, 15000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!channeling)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
bool eventInProgress;
|
||||
bool channeling;
|
||||
uint8 eventProgress;
|
||||
uint8 spawnerCount;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_belnistraszAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_idol_room_spawner : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_idol_room_spawner() : CreatureScript("npc_idol_room_spawner") { }
|
||||
|
||||
struct npc_idol_room_spawnerAI : public NullCreatureAI
|
||||
{
|
||||
npc_idol_room_spawnerAI(Creature* creature) : NullCreatureAI(creature)
|
||||
{
|
||||
}
|
||||
|
||||
void SetData(uint32 /*type*/, uint32 data)
|
||||
{
|
||||
if (data < 7)
|
||||
{
|
||||
me->SummonCreature(NPC_WITHERED_BATTLE_BOAR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
|
||||
if (data > 0 && me->GetOrientation() < 4.0f)
|
||||
me->SummonCreature(NPC_WITHERED_BATTLE_BOAR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
|
||||
me->SummonCreature(NPC_DEATHS_HEAD_GEOMANCER, me->GetPositionX() + (cos(me->GetOrientation() - (M_PI/2)) * 2), me->GetPositionY() + (sin(me->GetOrientation() - (M_PI/2)) * 2), me->GetPositionZ(), me->GetOrientation());
|
||||
me->SummonCreature(NPC_WITHERED_QUILGUARD, me->GetPositionX() + (cos(me->GetOrientation() + (M_PI/2)) * 2), me->GetPositionY() + (sin(me->GetOrientation() + (M_PI/2)) * 2), me->GetPositionZ(), me->GetOrientation());
|
||||
}
|
||||
else if (data == 7)
|
||||
me->SummonCreature(NPC_PLAGUEMAW_THE_ROTTING, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_idol_room_spawnerAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_razorfen_downs()
|
||||
{
|
||||
new npc_belnistrasz();
|
||||
new npc_idol_room_spawner();
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef DEF_RAZORFEN_DOWNS_H
|
||||
#define DEF_RAZORFEN_DOWNS_H
|
||||
|
||||
enum CreatureIds
|
||||
{
|
||||
NPC_IDOL_ROOM_SPAWNER = 8611,
|
||||
NPC_WITHERED_BATTLE_BOAR = 7333,
|
||||
NPC_DEATHS_HEAD_GEOMANCER = 7335,
|
||||
NPC_WITHERED_QUILGUARD = 7329,
|
||||
NPC_PLAGUEMAW_THE_ROTTING = 7356
|
||||
};
|
||||
|
||||
enum GameObjectIds
|
||||
{
|
||||
GO_GONG = 148917,
|
||||
|
||||
GO_IDOL_OVEN_FIRE = 151951,
|
||||
GO_IDOL_CUP_FIRE = 151952,
|
||||
GO_IDOL_MOUTH_FIRE = 151973,
|
||||
GO_BELNISTRASZS_BRAZIER = 152097
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
|
||||
class instance_razorfen_kraul : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_razorfen_kraul() : InstanceMapScript("instance_razorfen_kraul", 47) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_razorfen_kraul_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
struct instance_razorfen_kraul_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_razorfen_kraul_InstanceMapScript(Map* map) : InstanceScript(map) { }
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_instance_razorfen_kraul()
|
||||
{
|
||||
new instance_razorfen_kraul();
|
||||
}
|
||||
@@ -1,297 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "Player.h"
|
||||
#include "ruins_of_ahnqiraj.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_STINGER_SPRAY = 25749,
|
||||
SPELL_POISON_STINGER = 25748,
|
||||
SPELL_PARALYZE = 25725,
|
||||
SPELL_TRASH = 3391,
|
||||
SPELL_FRENZY = 8269,
|
||||
SPELL_LASH = 25852,
|
||||
SPELL_FEED = 25721
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_STINGER_SPRAY = 1,
|
||||
EVENT_POISON_STINGER = 2,
|
||||
EVENT_SUMMON_SWARMER = 3,
|
||||
EVENT_SWARMER_ATTACK = 4,
|
||||
EVENT_PARALYZE = 5,
|
||||
EVENT_LASH = 6,
|
||||
EVENT_TRASH = 7
|
||||
};
|
||||
|
||||
enum Emotes
|
||||
{
|
||||
EMOTE_FRENZY = 0
|
||||
};
|
||||
|
||||
enum Phases
|
||||
{
|
||||
PHASE_AIR = 0,
|
||||
PHASE_GROUND = 1
|
||||
};
|
||||
|
||||
enum Points
|
||||
{
|
||||
POINT_AIR = 0,
|
||||
POINT_GROUND = 1,
|
||||
POINT_PARALYZE = 2
|
||||
};
|
||||
|
||||
const Position AyamissAirPos = { -9689.292f, 1547.912f, 48.02729f, 0.0f };
|
||||
const Position AltarPos = { -9717.18f, 1517.72f, 27.4677f, 0.0f };
|
||||
/// @todo These below are probably incorrect, taken from SD2
|
||||
const Position SwarmerPos = { -9647.352f, 1578.062f, 55.32f, 0.0f };
|
||||
const Position LarvaPos[2] =
|
||||
{
|
||||
{ -9674.4707f, 1528.4133f, 22.457f, 0.0f },
|
||||
{ -9701.6005f, 1566.9993f, 24.118f, 0.0f }
|
||||
};
|
||||
|
||||
class boss_ayamiss : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_ayamiss() : CreatureScript("boss_ayamiss") { }
|
||||
|
||||
struct boss_ayamissAI : public BossAI
|
||||
{
|
||||
boss_ayamissAI(Creature* creature) : BossAI(creature, DATA_AYAMISS)
|
||||
{
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
_phase = PHASE_AIR;
|
||||
_enraged = false;
|
||||
SetCombatMovement(false);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* who)
|
||||
{
|
||||
switch (who->GetEntry())
|
||||
{
|
||||
case NPC_SWARMER:
|
||||
_swarmers.push_back(who->GetGUID());
|
||||
break;
|
||||
case NPC_LARVA:
|
||||
who->GetMotionMaster()->MovePoint(POINT_PARALYZE, AltarPos);
|
||||
break;
|
||||
case NPC_HORNET:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
|
||||
who->AI()->AttackStart(target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case POINT_AIR:
|
||||
me->AddUnitState(UNIT_STATE_ROOT);
|
||||
break;
|
||||
case POINT_GROUND:
|
||||
me->ClearUnitState(UNIT_STATE_ROOT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
me->ClearUnitState(UNIT_STATE_ROOT);
|
||||
BossAI::EnterEvadeMode();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* attacker)
|
||||
{
|
||||
BossAI::EnterCombat(attacker);
|
||||
|
||||
events.ScheduleEvent(EVENT_STINGER_SPRAY, urand(20000, 30000));
|
||||
events.ScheduleEvent(EVENT_POISON_STINGER, 5000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_SWARMER, 5000);
|
||||
events.ScheduleEvent(EVENT_SWARMER_ATTACK, 60000);
|
||||
events.ScheduleEvent(EVENT_PARALYZE, 15000);
|
||||
|
||||
me->SetCanFly(true);
|
||||
me->SetDisableGravity(true);
|
||||
me->GetMotionMaster()->MovePoint(POINT_AIR, AyamissAirPos);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (_phase == PHASE_AIR && me->GetHealthPct() < 70.0f)
|
||||
{
|
||||
_phase = PHASE_GROUND;
|
||||
SetCombatMovement(true);
|
||||
me->SetCanFly(false);
|
||||
Position VictimPos;
|
||||
me->GetVictim()->GetPosition(&VictimPos);
|
||||
me->GetMotionMaster()->MovePoint(POINT_GROUND, VictimPos);
|
||||
DoResetThreat();
|
||||
events.ScheduleEvent(EVENT_LASH, urand(5000, 8000));
|
||||
events.ScheduleEvent(EVENT_TRASH, urand(3000, 6000));
|
||||
events.CancelEvent(EVENT_POISON_STINGER);
|
||||
}
|
||||
else
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
if (!_enraged && me->GetHealthPct() < 20.0f)
|
||||
{
|
||||
DoCast(me, SPELL_FRENZY);
|
||||
Talk(EMOTE_FRENZY);
|
||||
_enraged = true;
|
||||
}
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_STINGER_SPRAY:
|
||||
DoCast(me, SPELL_STINGER_SPRAY);
|
||||
events.ScheduleEvent(EVENT_STINGER_SPRAY, urand(15000, 20000));
|
||||
break;
|
||||
case EVENT_POISON_STINGER:
|
||||
DoCastVictim(SPELL_POISON_STINGER);
|
||||
events.ScheduleEvent(EVENT_POISON_STINGER, urand(2000, 3000));
|
||||
break;
|
||||
case EVENT_PARALYZE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true))
|
||||
{
|
||||
DoCast(target, SPELL_PARALYZE);
|
||||
instance->SetData64(DATA_PARALYZED, target->GetGUID());
|
||||
uint8 Index = urand(0, 1);
|
||||
me->SummonCreature(NPC_LARVA, LarvaPos[Index], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_PARALYZE, 15000);
|
||||
break;
|
||||
case EVENT_SWARMER_ATTACK:
|
||||
for (std::list<uint64>::iterator i = _swarmers.begin(); i != _swarmers.end(); ++i)
|
||||
if (Creature* swarmer = me->GetMap()->GetCreature(*i))
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
|
||||
swarmer->AI()->AttackStart(target);
|
||||
|
||||
_swarmers.clear();
|
||||
events.ScheduleEvent(EVENT_SWARMER_ATTACK, 60000);
|
||||
break;
|
||||
case EVENT_SUMMON_SWARMER:
|
||||
Position Pos;
|
||||
me->GetRandomPoint(SwarmerPos, 80.0f, Pos);
|
||||
me->SummonCreature(NPC_SWARMER, Pos);
|
||||
events.ScheduleEvent(EVENT_SUMMON_SWARMER, 5000);
|
||||
break;
|
||||
case EVENT_TRASH:
|
||||
DoCastVictim(SPELL_TRASH);
|
||||
events.ScheduleEvent(EVENT_TRASH, urand(5000, 7000));
|
||||
break;
|
||||
case EVENT_LASH:
|
||||
DoCastVictim(SPELL_LASH);
|
||||
events.ScheduleEvent(EVENT_LASH, urand(8000, 15000));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
std::list<uint64> _swarmers;
|
||||
uint8 _phase;
|
||||
bool _enraged;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_ayamissAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_hive_zara_larva : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_hive_zara_larva() : CreatureScript("npc_hive_zara_larva") { }
|
||||
|
||||
struct npc_hive_zara_larvaAI : public ScriptedAI
|
||||
{
|
||||
npc_hive_zara_larvaAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
_instance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE)
|
||||
if (id == POINT_PARALYZE)
|
||||
if (Player* target = ObjectAccessor::GetPlayer(*me, _instance->GetData64(DATA_PARALYZED)))
|
||||
DoCast(target, SPELL_FEED); // Omnomnom
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
|
||||
{
|
||||
if (_instance->GetBossState(DATA_AYAMISS) == IN_PROGRESS)
|
||||
return;
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* victim)
|
||||
{
|
||||
if (_instance->GetBossState(DATA_AYAMISS) == IN_PROGRESS)
|
||||
return;
|
||||
|
||||
ScriptedAI::AttackStart(victim);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (_instance->GetBossState(DATA_AYAMISS) == IN_PROGRESS)
|
||||
return;
|
||||
|
||||
ScriptedAI::UpdateAI(diff);
|
||||
}
|
||||
private:
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_hive_zara_larvaAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_ayamiss()
|
||||
{
|
||||
new boss_ayamiss();
|
||||
new npc_hive_zara_larva();
|
||||
}
|
||||
@@ -1,282 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "ruins_of_ahnqiraj.h"
|
||||
|
||||
enum Emotes
|
||||
{
|
||||
EMOTE_TARGET = 0
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CREEPING_PLAGUE = 20512,
|
||||
SPELL_DISMEMBER = 96,
|
||||
SPELL_GATHERING_SPEED = 1834,
|
||||
SPELL_FULL_SPEED = 1557,
|
||||
SPELL_THORNS = 25640,
|
||||
SPELL_BURU_TRANSFORM = 24721,
|
||||
SPELL_SUMMON_HATCHLING = 1881,
|
||||
SPELL_EXPLODE = 19593,
|
||||
SPELL_EXPLODE_2 = 5255,
|
||||
SPELL_BURU_EGG_TRIGGER = 26646
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_DISMEMBER = 1,
|
||||
EVENT_GATHERING_SPEED = 2,
|
||||
EVENT_FULL_SPEED = 3,
|
||||
EVENT_CREEPING_PLAGUE = 4,
|
||||
EVENT_RESPAWN_EGG = 5
|
||||
};
|
||||
|
||||
enum Phases
|
||||
{
|
||||
PHASE_EGG = 0,
|
||||
PHASE_TRANSFORM = 1
|
||||
};
|
||||
|
||||
enum Actions
|
||||
{
|
||||
ACTION_EXPLODE = 0
|
||||
};
|
||||
|
||||
class boss_buru : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_buru() : CreatureScript("boss_buru") { }
|
||||
|
||||
struct boss_buruAI : public BossAI
|
||||
{
|
||||
boss_buruAI(Creature* creature) : BossAI(creature, DATA_BURU)
|
||||
{
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
BossAI::EnterEvadeMode();
|
||||
|
||||
for (std::list<uint64>::iterator i = Eggs.begin(); i != Eggs.end(); ++i)
|
||||
if (Creature* egg = me->GetMap()->GetCreature(*Eggs.begin()))
|
||||
egg->Respawn();
|
||||
|
||||
Eggs.clear();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
_EnterCombat();
|
||||
Talk(EMOTE_TARGET, who);
|
||||
DoCast(me, SPELL_THORNS);
|
||||
|
||||
events.ScheduleEvent(EVENT_DISMEMBER, 5000);
|
||||
events.ScheduleEvent(EVENT_GATHERING_SPEED, 9000);
|
||||
events.ScheduleEvent(EVENT_FULL_SPEED, 60000);
|
||||
|
||||
_phase = PHASE_EGG;
|
||||
}
|
||||
|
||||
void DoAction(int32 action)
|
||||
{
|
||||
if (action == ACTION_EXPLODE)
|
||||
if (_phase == PHASE_EGG)
|
||||
Unit::DealDamage(me, me, 45000);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
ChaseNewVictim();
|
||||
}
|
||||
|
||||
void ChaseNewVictim()
|
||||
{
|
||||
if (_phase != PHASE_EGG)
|
||||
return;
|
||||
|
||||
me->RemoveAurasDueToSpell(SPELL_FULL_SPEED);
|
||||
me->RemoveAurasDueToSpell(SPELL_GATHERING_SPEED);
|
||||
events.ScheduleEvent(EVENT_GATHERING_SPEED, 9000);
|
||||
events.ScheduleEvent(EVENT_FULL_SPEED, 60000);
|
||||
|
||||
if (Unit* victim = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
|
||||
{
|
||||
DoResetThreat();
|
||||
AttackStart(victim);
|
||||
Talk(EMOTE_TARGET, victim);
|
||||
}
|
||||
}
|
||||
|
||||
void ManageRespawn(uint64 EggGUID)
|
||||
{
|
||||
ChaseNewVictim();
|
||||
Eggs.push_back(EggGUID);
|
||||
events.ScheduleEvent(EVENT_RESPAWN_EGG, 100000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_DISMEMBER:
|
||||
DoCastVictim(SPELL_DISMEMBER);
|
||||
events.ScheduleEvent(EVENT_DISMEMBER, 5000);
|
||||
break;
|
||||
case EVENT_GATHERING_SPEED:
|
||||
DoCast(me, SPELL_GATHERING_SPEED);
|
||||
events.ScheduleEvent(EVENT_GATHERING_SPEED, 9000);
|
||||
break;
|
||||
case EVENT_FULL_SPEED:
|
||||
DoCast(me, SPELL_FULL_SPEED);
|
||||
break;
|
||||
case EVENT_CREEPING_PLAGUE:
|
||||
DoCast(me, SPELL_CREEPING_PLAGUE);
|
||||
events.ScheduleEvent(EVENT_CREEPING_PLAGUE, 6000);
|
||||
break;
|
||||
case EVENT_RESPAWN_EGG:
|
||||
if (Creature* egg = me->GetMap()->GetCreature(*Eggs.begin()))
|
||||
{
|
||||
egg->Respawn();
|
||||
Eggs.pop_front();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (me->GetHealthPct() < 20.0f && _phase == PHASE_EGG)
|
||||
{
|
||||
DoCast(me, SPELL_BURU_TRANSFORM); // Enrage
|
||||
DoCast(me, SPELL_FULL_SPEED, true);
|
||||
me->RemoveAurasDueToSpell(SPELL_THORNS);
|
||||
_phase = PHASE_TRANSFORM;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
uint8 _phase;
|
||||
std::list<uint64> Eggs;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_buruAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_buru_egg : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_buru_egg() : CreatureScript("npc_buru_egg") { }
|
||||
|
||||
struct npc_buru_eggAI : public ScriptedAI
|
||||
{
|
||||
npc_buru_eggAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
_instance = me->GetInstanceScript();
|
||||
SetCombatMovement(false);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* attacker)
|
||||
{
|
||||
if (Creature* buru = me->GetMap()->GetCreature(_instance->GetData64(DATA_BURU)))
|
||||
if (!buru->IsInCombat())
|
||||
buru->AI()->AttackStart(attacker);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* who)
|
||||
{
|
||||
if (who->GetEntry() == NPC_HATCHLING)
|
||||
if (Creature* buru = me->GetMap()->GetCreature(_instance->GetData64(DATA_BURU)))
|
||||
if (Unit* target = buru->AI()->SelectTarget(SELECT_TARGET_RANDOM))
|
||||
who->AI()->AttackStart(target);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
DoCastAOE(SPELL_EXPLODE, true);
|
||||
DoCastAOE(SPELL_EXPLODE_2, true); // Unknown purpose
|
||||
DoCast(me, SPELL_SUMMON_HATCHLING, true);
|
||||
|
||||
if (Creature* buru = me->GetMap()->GetCreature(_instance->GetData64(DATA_BURU)))
|
||||
if (boss_buru::boss_buruAI* buruAI = dynamic_cast<boss_buru::boss_buruAI*>(buru->AI()))
|
||||
buruAI->ManageRespawn(me->GetGUID());
|
||||
}
|
||||
private:
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_buru_eggAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_egg_explosion : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_egg_explosion() : SpellScriptLoader("spell_egg_explosion") { }
|
||||
|
||||
class spell_egg_explosion_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_egg_explosion_SpellScript);
|
||||
|
||||
void HandleAfterCast()
|
||||
{
|
||||
if (Creature* buru = GetCaster()->FindNearestCreature(NPC_BURU, 5.f))
|
||||
buru->AI()->DoAction(ACTION_EXPLODE);
|
||||
}
|
||||
|
||||
void HandleDummyHitTarget(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Unit* target = GetHitUnit())
|
||||
Unit::DealDamage(GetCaster(), target, -16 * GetCaster()->GetDistance(target) + 500);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
AfterCast += SpellCastFn(spell_egg_explosion_SpellScript::HandleAfterCast);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_egg_explosion_SpellScript::HandleDummyHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_egg_explosion_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_buru()
|
||||
{
|
||||
new boss_buru();
|
||||
new npc_buru_egg();
|
||||
new spell_egg_explosion();
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "ObjectMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ruins_of_ahnqiraj.h"
|
||||
#include "CreatureTextMgr.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_MORTALWOUND = 25646,
|
||||
SPELL_SANDTRAP = 25648,
|
||||
SPELL_ENRAGE = 26527,
|
||||
SPELL_SUMMON_PLAYER = 26446,
|
||||
SPELL_TRASH = 3391, // Should perhaps be triggered by an aura? Couldn't find any though
|
||||
SPELL_WIDE_SLASH = 25814
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_MORTAL_WOUND = 1,
|
||||
EVENT_SANDTRAP = 2,
|
||||
EVENT_TRASH = 3,
|
||||
EVENT_WIDE_SLASH = 4
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_KURINAXX_DEATH = 5, // Yelled by Ossirian the Unscarred
|
||||
};
|
||||
|
||||
class boss_kurinnaxx : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_kurinnaxx() : CreatureScript("boss_kurinnaxx") { }
|
||||
|
||||
struct boss_kurinnaxxAI : public BossAI
|
||||
{
|
||||
boss_kurinnaxxAI(Creature* creature) : BossAI(creature, DATA_KURINNAXX)
|
||||
{
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
_enraged = false;
|
||||
events.ScheduleEvent(EVENT_MORTAL_WOUND, 8000);
|
||||
events.ScheduleEvent(EVENT_SANDTRAP, urand(5000, 15000));
|
||||
events.ScheduleEvent(EVENT_TRASH, 1000);
|
||||
events.ScheduleEvent(EVENT_WIDE_SLASH, 11000);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (!_enraged && HealthBelowPct(30))
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
_enraged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
_JustDied();
|
||||
if (Creature* Ossirian = me->GetMap()->GetCreature(instance->GetData64(DATA_OSSIRIAN)))
|
||||
sCreatureTextMgr->SendChat(Ossirian, SAY_KURINAXX_DEATH, NULL, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_ZONE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_MORTAL_WOUND:
|
||||
DoCastVictim(SPELL_MORTALWOUND);
|
||||
events.ScheduleEvent(EVENT_MORTAL_WOUND, 8000);
|
||||
break;
|
||||
case EVENT_SANDTRAP:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
target->CastSpell(target, SPELL_SANDTRAP, true);
|
||||
else if (Unit* victim = me->GetVictim())
|
||||
victim->CastSpell(victim, SPELL_SANDTRAP, true);
|
||||
events.ScheduleEvent(EVENT_SANDTRAP, urand(5000, 15000));
|
||||
break;
|
||||
case EVENT_WIDE_SLASH:
|
||||
DoCast(me, SPELL_WIDE_SLASH);
|
||||
events.ScheduleEvent(EVENT_WIDE_SLASH, 11000);
|
||||
break;
|
||||
case EVENT_TRASH:
|
||||
DoCast(me, SPELL_TRASH);
|
||||
events.ScheduleEvent(EVENT_WIDE_SLASH, 16000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
bool _enraged;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_kurinnaxxAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_kurinnaxx()
|
||||
{
|
||||
new boss_kurinnaxx();
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "ruins_of_ahnqiraj.h"
|
||||
|
||||
enum Texts
|
||||
{
|
||||
EMOTE_AGGRO = 0,
|
||||
EMOTE_MANA_FULL = 1
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_TRAMPLE = 15550,
|
||||
SPELL_DRAIN_MANA = 25671,
|
||||
SPELL_ARCANE_ERUPTION = 25672,
|
||||
SPELL_SUMMON_MANA_FIEND_1 = 25681, // TARGET_DEST_CASTER_FRONT
|
||||
SPELL_SUMMON_MANA_FIEND_2 = 25682, // TARGET_DEST_CASTER_LEFT
|
||||
SPELL_SUMMON_MANA_FIEND_3 = 25683, // TARGET_DEST_CASTER_RIGHT
|
||||
SPELL_ENERGIZE = 25685
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_TRAMPLE = 1,
|
||||
EVENT_DRAIN_MANA = 2,
|
||||
EVENT_STONE_PHASE = 3,
|
||||
EVENT_STONE_PHASE_END = 4,
|
||||
EVENT_WIDE_SLASH = 5,
|
||||
};
|
||||
|
||||
enum Actions
|
||||
{
|
||||
ACTION_STONE_PHASE_START = 1,
|
||||
ACTION_STONE_PHASE_END = 2,
|
||||
};
|
||||
|
||||
class boss_moam : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_moam() : CreatureScript("boss_moam") { }
|
||||
|
||||
struct boss_moamAI : public BossAI
|
||||
{
|
||||
boss_moamAI(Creature* creature) : BossAI(creature, DATA_MOAM)
|
||||
{
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
me->SetPower(POWER_MANA, 0);
|
||||
_isStonePhase = false;
|
||||
events.ScheduleEvent(EVENT_STONE_PHASE, 90000);
|
||||
//events.ScheduleEvent(EVENT_WIDE_SLASH, 11000);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (!_isStonePhase && HealthBelowPct(45))
|
||||
{
|
||||
_isStonePhase = true;
|
||||
DoAction(ACTION_STONE_PHASE_START);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_STONE_PHASE_END:
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_ENERGIZE);
|
||||
events.ScheduleEvent(EVENT_STONE_PHASE, 90000);
|
||||
_isStonePhase = false;
|
||||
break;
|
||||
}
|
||||
case ACTION_STONE_PHASE_START:
|
||||
{
|
||||
DoCast(me, SPELL_SUMMON_MANA_FIEND_1);
|
||||
DoCast(me, SPELL_SUMMON_MANA_FIEND_2);
|
||||
DoCast(me, SPELL_SUMMON_MANA_FIEND_3);
|
||||
DoCast(me, SPELL_ENERGIZE);
|
||||
events.ScheduleEvent(EVENT_STONE_PHASE_END, 90000);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->GetPower(POWER_MANA) == me->GetMaxPower(POWER_MANA))
|
||||
{
|
||||
if (_isStonePhase)
|
||||
DoAction(ACTION_STONE_PHASE_END);
|
||||
DoCastAOE(SPELL_ARCANE_ERUPTION);
|
||||
me->SetPower(POWER_MANA, 0);
|
||||
}
|
||||
|
||||
if (_isStonePhase)
|
||||
{
|
||||
if (events.ExecuteEvent() == EVENT_STONE_PHASE_END)
|
||||
DoAction(ACTION_STONE_PHASE_END);
|
||||
return;
|
||||
}
|
||||
|
||||
// Messing up mana-drain channel
|
||||
//if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
// return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_STONE_PHASE:
|
||||
DoAction(ACTION_STONE_PHASE_START);
|
||||
break;
|
||||
case EVENT_DRAIN_MANA:
|
||||
{
|
||||
std::list<Unit*> targetList;
|
||||
{
|
||||
const std::list<HostileReference*>& threatlist = me->getThreatManager().getThreatList();
|
||||
for (std::list<HostileReference*>::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
|
||||
if ((*itr)->getTarget()->GetTypeId() == TYPEID_PLAYER && (*itr)->getTarget()->getPowerType() == POWER_MANA)
|
||||
targetList.push_back((*itr)->getTarget());
|
||||
}
|
||||
|
||||
Trinity::Containers::RandomResizeList(targetList, 5);
|
||||
|
||||
for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
|
||||
DoCast(*itr, SPELL_DRAIN_MANA);
|
||||
|
||||
events.ScheduleEvent(EVENT_DRAIN_MANA, urand(5000, 15000));
|
||||
break;
|
||||
}/*
|
||||
case EVENT_WIDE_SLASH:
|
||||
DoCast(me, SPELL_WIDE_SLASH);
|
||||
events.ScheduleEvent(EVENT_WIDE_SLASH, 11000);
|
||||
break;
|
||||
case EVENT_TRASH:
|
||||
DoCast(me, SPELL_TRASH);
|
||||
events.ScheduleEvent(EVENT_WIDE_SLASH, 16000);
|
||||
break;*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
bool _isStonePhase;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_moamAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_moam()
|
||||
{
|
||||
new boss_moam();
|
||||
}
|
||||
@@ -1,301 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "ruins_of_ahnqiraj.h"
|
||||
#include "Player.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Opcodes.h"
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_SUPREME = 0,
|
||||
SAY_INTRO = 1,
|
||||
SAY_AGGRO = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_SILENCE = 25195,
|
||||
SPELL_CYCLONE = 25189,
|
||||
SPELL_STOMP = 25188,
|
||||
SPELL_SUPREME = 25176,
|
||||
SPELL_SUMMON = 20477,
|
||||
SPELL_SAND_STORM = 25160,
|
||||
SPELL_SUMMON_CRYSTAL = 25192
|
||||
};
|
||||
|
||||
enum Actions
|
||||
{
|
||||
ACTION_TRIGGER_WEAKNESS = 1
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SILENCE = 1,
|
||||
EVENT_CYCLONE = 2,
|
||||
EVENT_STOMP = 3
|
||||
};
|
||||
|
||||
uint8 const NUM_CRYSTALS = 9;
|
||||
|
||||
// You spin me right round, baby
|
||||
// right round like a record, baby
|
||||
// right round round round
|
||||
Position CrystalCoordinates[NUM_CRYSTALS] =
|
||||
{
|
||||
{ -9394.230469f, 1951.808594f, 85.97733f, 0.0f },
|
||||
{ -9357.931641f, 1930.596802f, 85.556198f, 0.0f },
|
||||
{ -9383.113281f, 2011.042725f, 85.556389f, 0.0f },
|
||||
{ -9243.36f, 1979.04f, 85.556f, 0.0f },
|
||||
{ -9281.68f, 1886.66f, 85.5558f, 0.0f },
|
||||
{ -9241.8f, 1806.39f, 85.5557f, 0.0f },
|
||||
{ -9366.78f, 1781.76f, 85.5561f, 0.0f },
|
||||
{ -9430.37f, 1786.86f, 85.557f, 0.0f },
|
||||
{ -9406.73f, 1863.13f, 85.5558f, 0.0f }
|
||||
};
|
||||
|
||||
float RoomRadius = 165.0f;
|
||||
uint8 const NUM_TORNADOS = 5; /// @todo This number is completly random!
|
||||
uint8 const NUM_WEAKNESS = 5;
|
||||
uint32 const SpellWeakness[NUM_WEAKNESS] = { 25177, 25178, 25180, 25181, 25183 };
|
||||
Position const RoomCenter = { -9343.041992f, 1923.278198f, 85.555984f, 0.0 };
|
||||
|
||||
class boss_ossirian : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_ossirian() : CreatureScript("boss_ossirian") { }
|
||||
|
||||
struct boss_ossirianAI : public BossAI
|
||||
{
|
||||
boss_ossirianAI(Creature* creature) : BossAI(creature, DATA_OSSIRIAN)
|
||||
{
|
||||
SaidIntro = false;
|
||||
}
|
||||
|
||||
uint64 TriggerGUID;
|
||||
uint64 CrystalGUID;
|
||||
uint8 CrystalIterator;
|
||||
bool SaidIntro;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
CrystalIterator = 0;
|
||||
TriggerGUID = 0;
|
||||
CrystalGUID = 0;
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, SpellInfo const* spell)
|
||||
{
|
||||
for (uint8 i = 0; i < NUM_WEAKNESS; ++i)
|
||||
{
|
||||
if (spell->Id == SpellWeakness[i])
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_SUPREME);
|
||||
((TempSummon*)caster)->UnSummon();
|
||||
SpawnNextCrystal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 action)
|
||||
{
|
||||
if (action == ACTION_TRIGGER_WEAKNESS)
|
||||
if (Creature* Trigger = me->GetMap()->GetCreature(TriggerGUID))
|
||||
if (!Trigger->HasUnitState(UNIT_STATE_CASTING))
|
||||
Trigger->CastSpell(Trigger, SpellWeakness[urand(0, 4)], false);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_SILENCE, 30000);
|
||||
events.ScheduleEvent(EVENT_CYCLONE, 20000);
|
||||
events.ScheduleEvent(EVENT_STOMP, 30000);
|
||||
|
||||
DoCast(me, SPELL_SUPREME);
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
Map* map = me->GetMap();
|
||||
if (!map->IsDungeon())
|
||||
return;
|
||||
|
||||
WorldPacket data(SMSG_WEATHER, (4+4+4));
|
||||
data << uint32(WEATHER_STATE_HEAVY_SANDSTORM) << float(1) << uint8(0);
|
||||
map->SendToPlayers(&data);
|
||||
|
||||
for (uint8 i = 0; i < NUM_TORNADOS; ++i)
|
||||
{
|
||||
Position Point;
|
||||
me->GetRandomPoint(RoomCenter, RoomRadius, Point);
|
||||
if (Creature* Tornado = me->GetMap()->SummonCreature(NPC_SAND_VORTEX, Point))
|
||||
Tornado->CastSpell(Tornado, SPELL_SAND_STORM, true);
|
||||
}
|
||||
|
||||
SpawnNextCrystal();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
Cleanup();
|
||||
summons.DespawnAll();
|
||||
BossAI::EnterEvadeMode();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Cleanup();
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void Cleanup()
|
||||
{
|
||||
if (GameObject* Crystal = me->GetMap()->GetGameObject(CrystalGUID))
|
||||
Crystal->Use(me);
|
||||
}
|
||||
|
||||
void SpawnNextCrystal()
|
||||
{
|
||||
if (CrystalIterator == NUM_CRYSTALS)
|
||||
CrystalIterator = 0;
|
||||
|
||||
if (Creature* Trigger = me->GetMap()->SummonCreature(NPC_OSSIRIAN_TRIGGER, CrystalCoordinates[CrystalIterator]))
|
||||
{
|
||||
TriggerGUID = Trigger->GetGUID();
|
||||
if (GameObject* Crystal = Trigger->SummonGameObject(GO_OSSIRIAN_CRYSTAL,
|
||||
CrystalCoordinates[CrystalIterator].GetPositionX(),
|
||||
CrystalCoordinates[CrystalIterator].GetPositionY(),
|
||||
CrystalCoordinates[CrystalIterator].GetPositionZ(),
|
||||
0, 0, 0, 0, 0, uint32(-1)))
|
||||
{
|
||||
CrystalGUID = Crystal->GetGUID();
|
||||
++CrystalIterator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
|
||||
{
|
||||
if (!SaidIntro)
|
||||
{
|
||||
Talk(SAY_INTRO);
|
||||
SaidIntro = true;
|
||||
}
|
||||
BossAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
// No kiting!
|
||||
if (me->GetDistance(me->GetVictim()) > 60.00f && me->GetDistance(me->GetVictim()) < 120.00f)
|
||||
DoCastVictim(SPELL_SUMMON);
|
||||
|
||||
bool ApplySupreme = true;
|
||||
|
||||
if (me->HasAura(SPELL_SUPREME))
|
||||
ApplySupreme = false;
|
||||
else
|
||||
{
|
||||
for (uint8 i = 0; i < NUM_WEAKNESS; ++i)
|
||||
{
|
||||
if (me->HasAura(SpellWeakness[i]))
|
||||
{
|
||||
ApplySupreme = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ApplySupreme)
|
||||
{
|
||||
DoCast(me, SPELL_SUPREME);
|
||||
Talk(SAY_SUPREME);
|
||||
}
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SILENCE:
|
||||
DoCast(me, SPELL_SILENCE);
|
||||
events.ScheduleEvent(EVENT_SILENCE, urand(20000, 30000));
|
||||
break;
|
||||
case EVENT_CYCLONE:
|
||||
DoCastVictim(SPELL_CYCLONE);
|
||||
events.ScheduleEvent(EVENT_CYCLONE, 20000);
|
||||
break;
|
||||
case EVENT_STOMP:
|
||||
DoCast(me, SPELL_STOMP);
|
||||
events.ScheduleEvent(EVENT_STOMP, 30000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_ossirianAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class go_ossirian_crystal : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_ossirian_crystal() : GameObjectScript("go_ossirian_crystal") { }
|
||||
|
||||
bool OnGossipHello(Player* player, GameObject* /*go*/)
|
||||
{
|
||||
InstanceScript* Instance = player->GetInstanceScript();
|
||||
if (!Instance)
|
||||
return false;
|
||||
|
||||
Creature* Ossirian = player->FindNearestCreature(NPC_OSSIRIAN, 30.0f);
|
||||
if (!Ossirian || Instance->GetBossState(DATA_OSSIRIAN) != IN_PROGRESS)
|
||||
return false;
|
||||
|
||||
Ossirian->AI()->DoAction(ACTION_TRIGGER_WEAKNESS);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_ossirian()
|
||||
{
|
||||
new boss_ossirian();
|
||||
new go_ossirian_crystal();
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "ObjectMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ruins_of_ahnqiraj.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
// The time of our retribution is at hand! Let darkness reign in the hearts of our enemies! Sound: 8645 Emote: 35
|
||||
SAY_ANDOROV_INTRO = 0, // Before for the first wave
|
||||
SAY_ANDOROV_ATTACK = 1, // Beginning the event
|
||||
|
||||
SAY_WAVE3 = 0,
|
||||
SAY_WAVE4 = 1,
|
||||
SAY_WAVE5 = 2,
|
||||
SAY_WAVE6 = 3,
|
||||
SAY_WAVE7 = 4,
|
||||
SAY_INTRO = 5,
|
||||
SAY_UNK1 = 6,
|
||||
SAY_UNK2 = 7,
|
||||
SAY_UNK3 = 8,
|
||||
SAY_DEATH = 9,
|
||||
SAY_CHANGEAGGRO = 10,
|
||||
SAY_KILLS_ANDOROV = 11,
|
||||
SAY_COMPLETE_QUEST = 12 // Yell when realm complete quest 8743 for world event
|
||||
// Warriors, Captains, continue the fight! Sound: 8640
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_DISARM = 6713,
|
||||
SPELL_FRENZY = 8269,
|
||||
SPELL_THUNDERCRASH = 25599
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_DISARM = 1, // 03:58:27, 03:58:49
|
||||
EVENT_THUNDERCRASH = 2, // 03:58:29, 03:58:50
|
||||
EVENT_CHANGE_AGGRO = 3,
|
||||
};
|
||||
|
||||
class boss_rajaxx : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_rajaxx() : CreatureScript("boss_rajaxx") { }
|
||||
|
||||
struct boss_rajaxxAI : public BossAI
|
||||
{
|
||||
boss_rajaxxAI(Creature* creature) : BossAI(creature, DATA_RAJAXX)
|
||||
{
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
enraged = false;
|
||||
events.ScheduleEvent(EVENT_DISARM, 10000);
|
||||
events.ScheduleEvent(EVENT_THUNDERCRASH, 12000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
//SAY_DEATH
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*victim*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_DISARM:
|
||||
DoCastVictim(SPELL_DISARM);
|
||||
events.ScheduleEvent(EVENT_DISARM, 22000);
|
||||
break;
|
||||
case EVENT_THUNDERCRASH:
|
||||
DoCast(me, SPELL_THUNDERCRASH);
|
||||
events.ScheduleEvent(EVENT_THUNDERCRASH, 21000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
bool enraged;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_rajaxxAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_rajaxx()
|
||||
{
|
||||
new boss_rajaxx();
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "InstanceScript.h"
|
||||
#include "ruins_of_ahnqiraj.h"
|
||||
|
||||
class instance_ruins_of_ahnqiraj : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_ruins_of_ahnqiraj() : InstanceMapScript("instance_ruins_of_ahnqiraj", 509) { }
|
||||
|
||||
struct instance_ruins_of_ahnqiraj_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_ruins_of_ahnqiraj_InstanceMapScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
SetBossNumber(NUM_ENCOUNTER);
|
||||
|
||||
_kurinaxxGUID = 0;
|
||||
_rajaxxGUID = 0;
|
||||
_moamGUID = 0;
|
||||
_buruGUID = 0;
|
||||
_ayamissGUID = 0;
|
||||
_ossirianGUID = 0;
|
||||
_paralyzedGUID = 0;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_KURINAXX:
|
||||
_kurinaxxGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_RAJAXX:
|
||||
_rajaxxGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_MOAM:
|
||||
_moamGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_BURU:
|
||||
_buruGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_AYAMISS:
|
||||
_ayamissGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_OSSIRIAN:
|
||||
_ossirianGUID = creature->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool SetBossState(uint32 bossId, EncounterState state)
|
||||
{
|
||||
if (!InstanceScript::SetBossState(bossId, state))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetData64(uint32 type, uint64 data)
|
||||
{
|
||||
if (type == DATA_PARALYZED)
|
||||
_paralyzedGUID = data;
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_KURINNAXX:
|
||||
return _kurinaxxGUID;
|
||||
case DATA_RAJAXX:
|
||||
return _rajaxxGUID;
|
||||
case DATA_MOAM:
|
||||
return _moamGUID;
|
||||
case DATA_BURU:
|
||||
return _buruGUID;
|
||||
case DATA_AYAMISS:
|
||||
return _ayamissGUID;
|
||||
case DATA_OSSIRIAN:
|
||||
return _ossirianGUID;
|
||||
case DATA_PARALYZED:
|
||||
return _paralyzedGUID;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "R A" << GetBossSaveData();
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(char const* data)
|
||||
{
|
||||
if (!data)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(data);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
|
||||
std::istringstream loadStream(data);
|
||||
loadStream >> dataHead1 >> dataHead2;
|
||||
|
||||
if (dataHead1 == 'R' && dataHead2 == 'A')
|
||||
{
|
||||
for (uint8 i = 0; i < NUM_ENCOUNTER; ++i)
|
||||
{
|
||||
uint32 tmpState;
|
||||
loadStream >> tmpState;
|
||||
if (tmpState == IN_PROGRESS || tmpState > TO_BE_DECIDED)
|
||||
tmpState = NOT_STARTED;
|
||||
SetBossState(i, EncounterState(tmpState));
|
||||
}
|
||||
}
|
||||
else
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
private:
|
||||
uint64 _kurinaxxGUID;
|
||||
uint64 _rajaxxGUID;
|
||||
uint64 _moamGUID;
|
||||
uint64 _buruGUID;
|
||||
uint64 _ayamissGUID;
|
||||
uint64 _ossirianGUID;
|
||||
uint64 _paralyzedGUID;
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_ruins_of_ahnqiraj_InstanceMapScript(map);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_ruins_of_ahnqiraj()
|
||||
{
|
||||
new instance_ruins_of_ahnqiraj();
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef DEF_RUINS_OF_AHNQIRAJ_H
|
||||
#define DEF_RUINS_OF_AHNQIRAJ_H
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
DATA_KURINNAXX = 0,
|
||||
DATA_RAJAXX = 1,
|
||||
DATA_MOAM = 2,
|
||||
DATA_BURU = 3,
|
||||
DATA_AYAMISS = 4,
|
||||
DATA_OSSIRIAN = 5,
|
||||
NUM_ENCOUNTER = 6,
|
||||
|
||||
DATA_PARALYZED = 7
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
NPC_KURINAXX = 15348,
|
||||
NPC_RAJAXX = 15341,
|
||||
NPC_MOAM = 15340,
|
||||
NPC_BURU = 15370,
|
||||
NPC_AYAMISS = 15369,
|
||||
NPC_OSSIRIAN = 15339,
|
||||
NPC_HIVEZARA_HORNET = 15934,
|
||||
NPC_HIVEZARA_SWARMER = 15546,
|
||||
NPC_HIVEZARA_LARVA = 15555,
|
||||
NPC_SAND_VORTEX = 15428,
|
||||
NPC_OSSIRIAN_TRIGGER = 15590,
|
||||
NPC_HATCHLING = 15521,
|
||||
NPC_LARVA = 15555,
|
||||
NPC_SWARMER = 15546,
|
||||
NPC_HORNET = 15934
|
||||
};
|
||||
|
||||
enum GameObjects
|
||||
{
|
||||
GO_OSSIRIAN_CRYSTAL = 180619
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,340 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: boss_kri, boss_yauj, boss_vem : The Bug Trio
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "temple_of_ahnqiraj.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CLEAVE = 26350,
|
||||
SPELL_TOXIC_VOLLEY = 25812,
|
||||
SPELL_POISON_CLOUD = 38718, //Only Spell with right dmg.
|
||||
SPELL_ENRAGE = 34624, //Changed cause 25790 is cast on gamers too. Same prob with old explosion of twin emperors.
|
||||
|
||||
SPELL_CHARGE = 26561,
|
||||
SPELL_KNOCKBACK = 26027,
|
||||
|
||||
SPELL_HEAL = 25807,
|
||||
SPELL_FEAR = 19408
|
||||
};
|
||||
|
||||
class boss_kri : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_kri() : CreatureScript("boss_kri") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_kriAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_kriAI : public ScriptedAI
|
||||
{
|
||||
boss_kriAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 Cleave_Timer;
|
||||
uint32 ToxicVolley_Timer;
|
||||
uint32 Check_Timer;
|
||||
|
||||
bool VemDead;
|
||||
bool Death;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Cleave_Timer = urand(4000, 8000);
|
||||
ToxicVolley_Timer = urand(6000, 12000);
|
||||
Check_Timer = 2000;
|
||||
|
||||
VemDead = false;
|
||||
Death = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
|
||||
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
||||
|
||||
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
|
||||
}
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Cleave_Timer
|
||||
if (Cleave_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
Cleave_Timer = urand(5000, 12000);
|
||||
} else Cleave_Timer -= diff;
|
||||
|
||||
//ToxicVolley_Timer
|
||||
if (ToxicVolley_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_TOXIC_VOLLEY);
|
||||
ToxicVolley_Timer = urand(10000, 15000);
|
||||
} else ToxicVolley_Timer -= diff;
|
||||
|
||||
if (!HealthAbovePct(5) && !Death)
|
||||
{
|
||||
DoCastVictim(SPELL_POISON_CLOUD);
|
||||
Death = true;
|
||||
}
|
||||
|
||||
if (!VemDead)
|
||||
{
|
||||
//Checking if Vem is dead. If yes we will enrage.
|
||||
if (Check_Timer <= diff)
|
||||
{
|
||||
if (instance->GetData(DATA_VEMISDEAD))
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
VemDead = true;
|
||||
}
|
||||
Check_Timer = 2000;
|
||||
} else Check_Timer -=diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class boss_vem : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_vem() : CreatureScript("boss_vem") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_vemAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_vemAI : public ScriptedAI
|
||||
{
|
||||
boss_vemAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 Charge_Timer;
|
||||
uint32 KnockBack_Timer;
|
||||
uint32 Enrage_Timer;
|
||||
|
||||
bool Enraged;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Charge_Timer = urand(15000, 27000);
|
||||
KnockBack_Timer = urand(8000, 20000);
|
||||
Enrage_Timer = 120000;
|
||||
|
||||
Enraged = false;
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
instance->SetData(DATA_VEM_DEATH, 0);
|
||||
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
|
||||
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
||||
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Charge_Timer
|
||||
if (Charge_Timer <= diff)
|
||||
{
|
||||
Unit* target = NULL;
|
||||
target = SelectTarget(SELECT_TARGET_RANDOM, 0);
|
||||
if (target)
|
||||
{
|
||||
DoCast(target, SPELL_CHARGE);
|
||||
//me->SendMonsterMove(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, true, 1);
|
||||
AttackStart(target);
|
||||
}
|
||||
|
||||
Charge_Timer = urand(8000, 16000);
|
||||
} else Charge_Timer -= diff;
|
||||
|
||||
//KnockBack_Timer
|
||||
if (KnockBack_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_KNOCKBACK);
|
||||
if (DoGetThreat(me->GetVictim()))
|
||||
DoModifyThreatPercent(me->GetVictim(), -80);
|
||||
KnockBack_Timer = urand(15000, 25000);
|
||||
} else KnockBack_Timer -= diff;
|
||||
|
||||
//Enrage_Timer
|
||||
if (!Enraged && Enrage_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
Enraged = true;
|
||||
} else Charge_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class boss_yauj : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_yauj() : CreatureScript("boss_yauj") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_yaujAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_yaujAI : public ScriptedAI
|
||||
{
|
||||
boss_yaujAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 Heal_Timer;
|
||||
uint32 Fear_Timer;
|
||||
uint32 Check_Timer;
|
||||
|
||||
bool VemDead;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Heal_Timer = urand(25000, 40000);
|
||||
Fear_Timer = urand(12000, 24000);
|
||||
Check_Timer = 2000;
|
||||
|
||||
VemDead = false;
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
|
||||
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
||||
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
|
||||
|
||||
for (uint8 i = 0; i < 10; ++i)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
if (Creature* Summoned = me->SummonCreature(15621, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90000))
|
||||
Summoned->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Fear_Timer
|
||||
if (Fear_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_FEAR);
|
||||
DoResetThreat();
|
||||
Fear_Timer = 20000;
|
||||
} else Fear_Timer -= diff;
|
||||
|
||||
//Casting Heal to other twins or herself.
|
||||
if (Heal_Timer <= diff)
|
||||
{
|
||||
switch (urand(0, 2))
|
||||
{
|
||||
case 0:
|
||||
if (Creature* kri = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KRI)))
|
||||
DoCast(kri, SPELL_HEAL);
|
||||
break;
|
||||
case 1:
|
||||
if (Creature* vem = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_VEM)))
|
||||
DoCast(vem, SPELL_HEAL);
|
||||
break;
|
||||
case 2:
|
||||
DoCast(me, SPELL_HEAL);
|
||||
break;
|
||||
}
|
||||
|
||||
Heal_Timer = 15000+rand()%15000;
|
||||
} else Heal_Timer -= diff;
|
||||
|
||||
//Checking if Vem is dead. If yes we will enrage.
|
||||
if (Check_Timer <= diff)
|
||||
{
|
||||
if (!VemDead)
|
||||
{
|
||||
if (instance->GetData(DATA_VEMISDEAD))
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
VemDead = true;
|
||||
}
|
||||
}
|
||||
Check_Timer = 2000;
|
||||
} else Check_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_bug_trio()
|
||||
{
|
||||
new boss_kri();
|
||||
new boss_vem();
|
||||
new boss_yauj();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,212 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Boss_Fankriss
|
||||
SD%Complete: 100
|
||||
SDComment: sound not implemented
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
#define SOUND_SENTENCE_YOU 8588
|
||||
#define SOUND_SERVE_TO 8589
|
||||
#define SOUND_LAWS 8590
|
||||
#define SOUND_TRESPASS 8591
|
||||
#define SOUND_WILL_BE 8592
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_MORTAL_WOUND = 28467,
|
||||
SPELL_ROOT = 28858,
|
||||
|
||||
// Enrage for his spawns
|
||||
SPELL_ENRAGE = 28798
|
||||
};
|
||||
|
||||
class boss_fankriss : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_fankriss() : CreatureScript("boss_fankriss") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_fankrissAI(creature);
|
||||
}
|
||||
|
||||
struct boss_fankrissAI : public ScriptedAI
|
||||
{
|
||||
boss_fankrissAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 MortalWound_Timer;
|
||||
uint32 SpawnHatchlings_Timer;
|
||||
uint32 SpawnSpawns_Timer;
|
||||
int Rand;
|
||||
float RandX;
|
||||
float RandY;
|
||||
|
||||
Creature* Hatchling;
|
||||
Creature* Spawn;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
MortalWound_Timer = urand(10000, 15000);
|
||||
SpawnHatchlings_Timer = urand(6000, 12000);
|
||||
SpawnSpawns_Timer = urand(15000, 45000);
|
||||
}
|
||||
|
||||
void SummonSpawn(Unit* victim)
|
||||
{
|
||||
if (!victim)
|
||||
return;
|
||||
|
||||
Rand = 10 + (rand()%10);
|
||||
switch (rand()%2)
|
||||
{
|
||||
case 0: RandX = 0.0f - Rand; break;
|
||||
case 1: RandX = 0.0f + Rand; break;
|
||||
}
|
||||
|
||||
Rand = 10 + (rand()%10);
|
||||
switch (rand()%2)
|
||||
{
|
||||
case 0: RandY = 0.0f - Rand; break;
|
||||
case 1: RandY = 0.0f + Rand; break;
|
||||
}
|
||||
Rand = 0;
|
||||
Spawn = DoSpawnCreature(15630, RandX, RandY, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||
if (Spawn)
|
||||
Spawn->AI()->AttackStart(victim);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//MortalWound_Timer
|
||||
if (MortalWound_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_MORTAL_WOUND);
|
||||
MortalWound_Timer = urand(10000, 20000);
|
||||
} else MortalWound_Timer -= diff;
|
||||
|
||||
//Summon 1-3 Spawns of Fankriss at random time.
|
||||
if (SpawnSpawns_Timer <= diff)
|
||||
{
|
||||
switch (urand(0, 2))
|
||||
{
|
||||
case 0:
|
||||
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
|
||||
break;
|
||||
case 1:
|
||||
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
|
||||
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
|
||||
break;
|
||||
case 2:
|
||||
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
|
||||
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
|
||||
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
|
||||
break;
|
||||
}
|
||||
SpawnSpawns_Timer = urand(30000, 60000);
|
||||
} else SpawnSpawns_Timer -= diff;
|
||||
|
||||
// Teleporting Random Target to one of the three tunnels and spawn 4 hatchlings near the gamer.
|
||||
//We will only telport if fankriss has more than 3% of hp so teleported gamers can always loot.
|
||||
if (HealthAbovePct(3))
|
||||
{
|
||||
if (SpawnHatchlings_Timer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
|
||||
{
|
||||
DoCast(target, SPELL_ROOT);
|
||||
|
||||
if (DoGetThreat(target))
|
||||
DoModifyThreatPercent(target, -100);
|
||||
|
||||
switch (urand(0, 2))
|
||||
{
|
||||
case 0:
|
||||
DoTeleportPlayer(target, -8106.0142f, 1289.2900f, -74.419533f, 5.112f);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()-3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
break;
|
||||
case 1:
|
||||
DoTeleportPlayer(target, -7990.135354f, 1155.1907f, -78.849319f, 2.608f);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()-3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
break;
|
||||
case 2:
|
||||
DoTeleportPlayer(target, -8159.7753f, 1127.9064f, -76.868660f, 0.675f);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()-3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
SpawnHatchlings_Timer = urand(45000, 60000);
|
||||
} else SpawnHatchlings_Timer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_fankriss()
|
||||
{
|
||||
new boss_fankriss();
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Boss_Huhuran
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
enum Huhuran
|
||||
{
|
||||
EMOTE_FRENZY_KILL = 0,
|
||||
EMOTE_BERSERK = 1,
|
||||
|
||||
SPELL_FRENZY = 26051,
|
||||
SPELL_BERSERK = 26068,
|
||||
SPELL_POISONBOLT = 26052,
|
||||
SPELL_NOXIOUSPOISON = 26053,
|
||||
SPELL_WYVERNSTING = 26180,
|
||||
SPELL_ACIDSPIT = 26050
|
||||
};
|
||||
|
||||
class boss_huhuran : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_huhuran() : CreatureScript("boss_huhuran") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_huhuranAI(creature);
|
||||
}
|
||||
|
||||
struct boss_huhuranAI : public ScriptedAI
|
||||
{
|
||||
boss_huhuranAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 Frenzy_Timer;
|
||||
uint32 Wyvern_Timer;
|
||||
uint32 Spit_Timer;
|
||||
uint32 PoisonBolt_Timer;
|
||||
uint32 NoxiousPoison_Timer;
|
||||
uint32 FrenzyBack_Timer;
|
||||
|
||||
bool Frenzy;
|
||||
bool Berserk;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Frenzy_Timer = urand(25000, 35000);
|
||||
Wyvern_Timer = urand(18000, 28000);
|
||||
Spit_Timer = 8000;
|
||||
PoisonBolt_Timer = 4000;
|
||||
NoxiousPoison_Timer = urand(10000, 20000);
|
||||
FrenzyBack_Timer = 15000;
|
||||
|
||||
Frenzy = false;
|
||||
Berserk = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Frenzy_Timer
|
||||
if (!Frenzy && Frenzy_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_FRENZY);
|
||||
Talk(EMOTE_FRENZY_KILL);
|
||||
Frenzy = true;
|
||||
PoisonBolt_Timer = 3000;
|
||||
Frenzy_Timer = urand(25000, 35000);
|
||||
} else Frenzy_Timer -= diff;
|
||||
|
||||
// Wyvern Timer
|
||||
if (Wyvern_Timer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_WYVERNSTING);
|
||||
Wyvern_Timer = urand(15000, 32000);
|
||||
} else Wyvern_Timer -= diff;
|
||||
|
||||
//Spit Timer
|
||||
if (Spit_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_ACIDSPIT);
|
||||
Spit_Timer = urand(5000, 10000);
|
||||
} else Spit_Timer -= diff;
|
||||
|
||||
//NoxiousPoison_Timer
|
||||
if (NoxiousPoison_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_NOXIOUSPOISON);
|
||||
NoxiousPoison_Timer = urand(12000, 24000);
|
||||
} else NoxiousPoison_Timer -= diff;
|
||||
|
||||
//PoisonBolt only if frenzy or berserk
|
||||
if (Frenzy || Berserk)
|
||||
{
|
||||
if (PoisonBolt_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_POISONBOLT);
|
||||
PoisonBolt_Timer = 3000;
|
||||
} else PoisonBolt_Timer -= diff;
|
||||
}
|
||||
|
||||
//FrenzyBack_Timer
|
||||
if (Frenzy && FrenzyBack_Timer <= diff)
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
Frenzy = false;
|
||||
FrenzyBack_Timer = 15000;
|
||||
} else FrenzyBack_Timer -= diff;
|
||||
|
||||
if (!Berserk && HealthBelowPct(31))
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
Talk(EMOTE_BERSERK);
|
||||
DoCast(me, SPELL_BERSERK);
|
||||
Berserk = true;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_huhuran()
|
||||
{
|
||||
new boss_huhuran();
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Boss_Ouro
|
||||
SD%Complete: 85
|
||||
SDComment: No model for submerging. Currently just invisible.
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "temple_of_ahnqiraj.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_SWEEP = 26103,
|
||||
SPELL_SANDBLAST = 26102,
|
||||
SPELL_GROUND_RUPTURE = 26100,
|
||||
SPELL_BIRTH = 26262, // The Birth Animation
|
||||
SPELL_DIRTMOUND_PASSIVE = 26092
|
||||
};
|
||||
|
||||
class boss_ouro : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_ouro() : CreatureScript("boss_ouro") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_ouroAI(creature);
|
||||
}
|
||||
|
||||
struct boss_ouroAI : public ScriptedAI
|
||||
{
|
||||
boss_ouroAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 Sweep_Timer;
|
||||
uint32 SandBlast_Timer;
|
||||
uint32 Submerge_Timer;
|
||||
uint32 Back_Timer;
|
||||
uint32 ChangeTarget_Timer;
|
||||
uint32 Spawn_Timer;
|
||||
|
||||
bool Enrage;
|
||||
bool Submerged;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Sweep_Timer = urand(5000, 10000);
|
||||
SandBlast_Timer = urand(20000, 35000);
|
||||
Submerge_Timer = urand(90000, 150000);
|
||||
Back_Timer = urand(30000, 45000);
|
||||
ChangeTarget_Timer = urand(5000, 8000);
|
||||
Spawn_Timer = urand(10000, 20000);
|
||||
|
||||
Enrage = false;
|
||||
Submerged = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
DoCastVictim(SPELL_BIRTH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Sweep_Timer
|
||||
if (!Submerged && Sweep_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SWEEP);
|
||||
Sweep_Timer = urand(15000, 30000);
|
||||
} else Sweep_Timer -= diff;
|
||||
|
||||
//SandBlast_Timer
|
||||
if (!Submerged && SandBlast_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SANDBLAST);
|
||||
SandBlast_Timer = urand(20000, 35000);
|
||||
} else SandBlast_Timer -= diff;
|
||||
|
||||
//Submerge_Timer
|
||||
if (!Submerged && Submerge_Timer <= diff)
|
||||
{
|
||||
//Cast
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_SUBMERGE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->setFaction(35);
|
||||
DoCast(me, SPELL_DIRTMOUND_PASSIVE);
|
||||
|
||||
Submerged = true;
|
||||
Back_Timer = urand(30000, 45000);
|
||||
} else Submerge_Timer -= diff;
|
||||
|
||||
//ChangeTarget_Timer
|
||||
if (Submerged && ChangeTarget_Timer <= diff)
|
||||
{
|
||||
Unit* target = NULL;
|
||||
target = SelectTarget(SELECT_TARGET_RANDOM, 0);
|
||||
|
||||
if (target)
|
||||
me->NearTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), me->GetOrientation());
|
||||
|
||||
ChangeTarget_Timer = urand(10000, 20000);
|
||||
} else ChangeTarget_Timer -= diff;
|
||||
|
||||
//Back_Timer
|
||||
if (Submerged && Back_Timer <= diff)
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->setFaction(14);
|
||||
|
||||
DoCastVictim(SPELL_GROUND_RUPTURE);
|
||||
|
||||
Submerged = false;
|
||||
Submerge_Timer = urand(60000, 120000);
|
||||
} else Back_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_ouro()
|
||||
{
|
||||
new boss_ouro();
|
||||
}
|
||||
@@ -1,306 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Boss_Sartura
|
||||
SD%Complete: 95
|
||||
SDComment:
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
enum Sartura
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_DEATH = 2,
|
||||
|
||||
SPELL_WHIRLWIND = 26083,
|
||||
SPELL_ENRAGE = 28747, //Not sure if right ID.
|
||||
SPELL_ENRAGEHARD = 28798,
|
||||
|
||||
//Guard Spell
|
||||
SPELL_WHIRLWINDADD = 26038,
|
||||
SPELL_KNOCKBACK = 26027
|
||||
};
|
||||
|
||||
class boss_sartura : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_sartura() : CreatureScript("boss_sartura") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_sarturaAI(creature);
|
||||
}
|
||||
|
||||
struct boss_sarturaAI : public ScriptedAI
|
||||
{
|
||||
boss_sarturaAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 WhirlWind_Timer;
|
||||
uint32 WhirlWindRandom_Timer;
|
||||
uint32 WhirlWindEnd_Timer;
|
||||
uint32 AggroReset_Timer;
|
||||
uint32 AggroResetEnd_Timer;
|
||||
uint32 EnrageHard_Timer;
|
||||
|
||||
bool Enraged;
|
||||
bool EnragedHard;
|
||||
bool WhirlWind;
|
||||
bool AggroReset;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
WhirlWind_Timer = 30000;
|
||||
WhirlWindRandom_Timer = urand(3000, 7000);
|
||||
WhirlWindEnd_Timer = 15000;
|
||||
AggroReset_Timer = urand(45000, 55000);
|
||||
AggroResetEnd_Timer = 5000;
|
||||
EnrageHard_Timer = 10*60000;
|
||||
|
||||
WhirlWind = false;
|
||||
AggroReset = false;
|
||||
Enraged = false;
|
||||
EnragedHard = false;
|
||||
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (WhirlWind)
|
||||
{
|
||||
if (WhirlWindRandom_Timer <= diff)
|
||||
{
|
||||
//Attack random Gamers
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true))
|
||||
{
|
||||
me->AddThreat(target, 1.0f);
|
||||
me->TauntApply(target);
|
||||
AttackStart(target);
|
||||
}
|
||||
WhirlWindRandom_Timer = urand(3000, 7000);
|
||||
} else WhirlWindRandom_Timer -= diff;
|
||||
|
||||
if (WhirlWindEnd_Timer <= diff)
|
||||
{
|
||||
WhirlWind = false;
|
||||
WhirlWind_Timer = urand(25000, 40000);
|
||||
} else WhirlWindEnd_Timer -= diff;
|
||||
}
|
||||
|
||||
if (!WhirlWind)
|
||||
{
|
||||
if (WhirlWind_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_WHIRLWIND);
|
||||
WhirlWind = true;
|
||||
WhirlWindEnd_Timer = 15000;
|
||||
} else WhirlWind_Timer -= diff;
|
||||
|
||||
if (AggroReset_Timer <= diff)
|
||||
{
|
||||
//Attack random Gamers
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true))
|
||||
{
|
||||
me->AddThreat(target, 1.0f);
|
||||
me->TauntApply(target);
|
||||
AttackStart(target);
|
||||
}
|
||||
AggroReset = true;
|
||||
AggroReset_Timer = urand(2000, 5000);
|
||||
} else AggroReset_Timer -= diff;
|
||||
|
||||
if (AggroReset)
|
||||
{
|
||||
if (AggroResetEnd_Timer <= diff)
|
||||
{
|
||||
AggroReset = false;
|
||||
AggroResetEnd_Timer = 5000;
|
||||
AggroReset_Timer = urand(35000, 45000);
|
||||
} else AggroResetEnd_Timer -= diff;
|
||||
}
|
||||
|
||||
//If she is 20% enrage
|
||||
if (!Enraged)
|
||||
{
|
||||
if (!HealthAbovePct(20) && !me->IsNonMeleeSpellCast(false))
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
Enraged = true;
|
||||
}
|
||||
}
|
||||
|
||||
//After 10 minutes hard enrage
|
||||
if (!EnragedHard)
|
||||
{
|
||||
if (EnrageHard_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGEHARD);
|
||||
EnragedHard = true;
|
||||
} else EnrageHard_Timer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class npc_sartura_royal_guard : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_sartura_royal_guard() : CreatureScript("npc_sartura_royal_guard") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_sartura_royal_guardAI(creature);
|
||||
}
|
||||
|
||||
struct npc_sartura_royal_guardAI : public ScriptedAI
|
||||
{
|
||||
npc_sartura_royal_guardAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 WhirlWind_Timer;
|
||||
uint32 WhirlWindRandom_Timer;
|
||||
uint32 WhirlWindEnd_Timer;
|
||||
uint32 AggroReset_Timer;
|
||||
uint32 AggroResetEnd_Timer;
|
||||
uint32 KnockBack_Timer;
|
||||
|
||||
bool WhirlWind;
|
||||
bool AggroReset;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
WhirlWind_Timer = 30000;
|
||||
WhirlWindRandom_Timer = urand(3000, 7000);
|
||||
WhirlWindEnd_Timer = 15000;
|
||||
AggroReset_Timer = urand(45000, 55000);
|
||||
AggroResetEnd_Timer = 5000;
|
||||
KnockBack_Timer = 10000;
|
||||
|
||||
WhirlWind = false;
|
||||
AggroReset = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (!WhirlWind && WhirlWind_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_WHIRLWINDADD);
|
||||
WhirlWind = true;
|
||||
WhirlWind_Timer = urand(25000, 40000);
|
||||
WhirlWindEnd_Timer = 15000;
|
||||
} else WhirlWind_Timer -= diff;
|
||||
|
||||
if (WhirlWind)
|
||||
{
|
||||
if (WhirlWindRandom_Timer <= diff)
|
||||
{
|
||||
//Attack random Gamers
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true))
|
||||
{
|
||||
me->AddThreat(target, 1.0f);
|
||||
me->TauntApply(target);
|
||||
AttackStart(target);
|
||||
}
|
||||
|
||||
WhirlWindRandom_Timer = urand(3000, 7000);
|
||||
} else WhirlWindRandom_Timer -= diff;
|
||||
|
||||
if (WhirlWindEnd_Timer <= diff)
|
||||
{
|
||||
WhirlWind = false;
|
||||
} else WhirlWindEnd_Timer -= diff;
|
||||
}
|
||||
|
||||
if (!WhirlWind)
|
||||
{
|
||||
if (AggroReset_Timer <= diff)
|
||||
{
|
||||
//Attack random Gamers
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true))
|
||||
{
|
||||
me->AddThreat(target, 1.0f);
|
||||
me->TauntApply(target);
|
||||
AttackStart(target);
|
||||
}
|
||||
|
||||
AggroReset = true;
|
||||
AggroReset_Timer = urand(2000, 5000);
|
||||
} else AggroReset_Timer -= diff;
|
||||
|
||||
if (KnockBack_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_WHIRLWINDADD);
|
||||
KnockBack_Timer = urand(10000, 20000);
|
||||
} else KnockBack_Timer -= diff;
|
||||
}
|
||||
|
||||
if (AggroReset)
|
||||
{
|
||||
if (AggroResetEnd_Timer <= diff)
|
||||
{
|
||||
AggroReset = false;
|
||||
AggroResetEnd_Timer = 5000;
|
||||
AggroReset_Timer = urand(30000, 40000);
|
||||
} else AggroResetEnd_Timer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_sartura()
|
||||
{
|
||||
new boss_sartura();
|
||||
new npc_sartura_royal_guard();
|
||||
}
|
||||
@@ -1,228 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "temple_of_ahnqiraj.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_SPLIT = 2,
|
||||
SAY_DEATH = 3
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_ARCANE_EXPLOSION = 26192,
|
||||
SPELL_EARTH_SHOCK = 26194,
|
||||
SPELL_TRUE_FULFILLMENT = 785,
|
||||
SPELL_INITIALIZE_IMAGE = 3730,
|
||||
SPELL_SUMMON_IMAGES = 747
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_ARCANE_EXPLOSION = 1,
|
||||
EVENT_FULLFILMENT = 2,
|
||||
EVENT_BLINK = 3,
|
||||
EVENT_EARTH_SHOCK = 4
|
||||
};
|
||||
|
||||
uint32 const BlinkSpells[3] = { 4801, 8195, 20449 };
|
||||
|
||||
class boss_skeram : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_skeram() : CreatureScript("boss_skeram") { }
|
||||
|
||||
struct boss_skeramAI : public BossAI
|
||||
{
|
||||
boss_skeramAI(Creature* creature) : BossAI(creature, DATA_SKERAM) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_flag = 0;
|
||||
_hpct = 75.0f;
|
||||
me->SetVisible(true);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
if (me->IsSummon())
|
||||
((TempSummon*)me)->UnSummon();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* creature)
|
||||
{
|
||||
// Shift the boss and images (Get it? *Shift*?)
|
||||
uint8 rand = 0;
|
||||
if (_flag != 0)
|
||||
{
|
||||
while (_flag & (1 << rand))
|
||||
rand = urand(0, 2);
|
||||
DoCast(me, BlinkSpells[rand]);
|
||||
_flag |= (1 << rand);
|
||||
_flag |= (1 << 7);
|
||||
}
|
||||
|
||||
while (_flag & (1 << rand))
|
||||
rand = urand(0, 2);
|
||||
creature->CastSpell(creature, BlinkSpells[rand]);
|
||||
_flag |= (1 << rand);
|
||||
|
||||
if (_flag & (1 << 7))
|
||||
_flag = 0;
|
||||
|
||||
if (Unit* Target = SelectTarget(SELECT_TARGET_RANDOM))
|
||||
creature->AI()->AttackStart(Target);
|
||||
|
||||
float ImageHealthPct;
|
||||
|
||||
if (me->GetHealthPct() < 25.0f)
|
||||
ImageHealthPct = 0.50f;
|
||||
else if (me->GetHealthPct() < 50.0f)
|
||||
ImageHealthPct = 0.20f;
|
||||
else
|
||||
ImageHealthPct = 0.10f;
|
||||
|
||||
creature->SetMaxHealth(me->GetMaxHealth() * ImageHealthPct);
|
||||
creature->SetHealth(creature->GetMaxHealth() * (me->GetHealthPct() / 100.0f));
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (!me->IsSummon())
|
||||
Talk(SAY_DEATH);
|
||||
else
|
||||
me->RemoveCorpse();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
events.Reset();
|
||||
|
||||
events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(6000, 12000));
|
||||
events.ScheduleEvent(EVENT_FULLFILMENT, 15000);
|
||||
events.ScheduleEvent(EVENT_BLINK, urand(30000, 45000));
|
||||
events.ScheduleEvent(EVENT_EARTH_SHOCK, 2000);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_ARCANE_EXPLOSION:
|
||||
DoCastAOE(SPELL_ARCANE_EXPLOSION, true);
|
||||
events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(8000, 18000));
|
||||
break;
|
||||
case EVENT_FULLFILMENT:
|
||||
/// @todo For some weird reason boss does not cast this
|
||||
// Spell actually works, tested in duel
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true), SPELL_TRUE_FULFILLMENT, true);
|
||||
events.ScheduleEvent(EVENT_FULLFILMENT, urand(20000, 30000));
|
||||
break;
|
||||
case EVENT_BLINK:
|
||||
DoCast(me, BlinkSpells[urand(0, 2)]);
|
||||
DoResetThreat();
|
||||
me->SetVisible(true);
|
||||
events.ScheduleEvent(EVENT_BLINK, urand(10000, 30000));
|
||||
break;
|
||||
case EVENT_EARTH_SHOCK:
|
||||
DoCastVictim(SPELL_EARTH_SHOCK);
|
||||
events.ScheduleEvent(EVENT_EARTH_SHOCK, 2000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!me->IsSummon() && me->GetHealthPct() < _hpct)
|
||||
{
|
||||
DoCast(me, SPELL_SUMMON_IMAGES);
|
||||
Talk(SAY_SPLIT);
|
||||
_hpct -= 25.0f;
|
||||
me->SetVisible(false);
|
||||
events.RescheduleEvent(EVENT_BLINK, 2000);
|
||||
}
|
||||
|
||||
if (me->IsWithinMeleeRange(me->GetVictim()))
|
||||
{
|
||||
events.RescheduleEvent(EVENT_EARTH_SHOCK, 2000);
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
float _hpct;
|
||||
uint8 _flag;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_skeramAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_skeram_arcane_explosion : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_skeram_arcane_explosion() : SpellScriptLoader("spell_skeram_arcane_explosion") { }
|
||||
|
||||
class spell_skeram_arcane_explosion_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_skeram_arcane_explosion_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.remove_if(PlayerOrPetCheck());
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_skeram_arcane_explosion_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_skeram_arcane_explosion_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_skeram()
|
||||
{
|
||||
new boss_skeram();
|
||||
new spell_skeram_arcane_explosion();
|
||||
}
|
||||
@@ -1,594 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Boss_Twinemperors
|
||||
SD%Complete: 95
|
||||
SDComment:
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "temple_of_ahnqiraj.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Item.h"
|
||||
#include "Spell.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_HEAL_BROTHER = 7393,
|
||||
SPELL_TWIN_TELEPORT = 800, // CTRA watches for this spell to start its teleport timer
|
||||
SPELL_TWIN_TELEPORT_VISUAL = 26638, // visual
|
||||
SPELL_EXPLODEBUG = 804,
|
||||
SPELL_MUTATE_BUG = 802,
|
||||
SPELL_BERSERK = 26662,
|
||||
SPELL_UPPERCUT = 26007,
|
||||
SPELL_UNBALANCING_STRIKE = 26613,
|
||||
SPELL_SHADOWBOLT = 26006,
|
||||
SPELL_BLIZZARD = 26607,
|
||||
SPELL_ARCANEBURST = 568,
|
||||
};
|
||||
|
||||
enum Sound
|
||||
{
|
||||
SOUND_VL_AGGRO = 8657, //8657 - Aggro - To Late
|
||||
SOUND_VL_KILL = 8658, //8658 - Kill - You will not
|
||||
SOUND_VL_DEATH = 8659, //8659 - Death
|
||||
SOUND_VN_DEATH = 8660, //8660 - Death - Feel
|
||||
SOUND_VN_AGGRO = 8661, //8661 - Aggro - Let none
|
||||
SOUND_VN_KILL = 8662, //8661 - Kill - your fate
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
PULL_RANGE = 50,
|
||||
ABUSE_BUG_RANGE = 20,
|
||||
VEKLOR_DIST = 20, // VL will not come to melee when attacking
|
||||
TELEPORTTIME = 30000
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct boss_twinemperorsAI : public ScriptedAI
|
||||
{
|
||||
boss_twinemperorsAI(Creature* creature): ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 Heal_Timer;
|
||||
uint32 Teleport_Timer;
|
||||
bool AfterTeleport;
|
||||
uint32 AfterTeleportTimer;
|
||||
bool DontYellWhenDead;
|
||||
uint32 Abuse_Bug_Timer, BugsTimer;
|
||||
bool tspellcast;
|
||||
uint32 EnrageTimer;
|
||||
|
||||
virtual bool IAmVeklor() = 0;
|
||||
virtual void Reset() = 0;
|
||||
virtual void CastSpellOnBug(Creature* target) = 0;
|
||||
|
||||
void TwinReset()
|
||||
{
|
||||
Heal_Timer = 0; // first heal immediately when they get close together
|
||||
Teleport_Timer = TELEPORTTIME;
|
||||
AfterTeleport = false;
|
||||
tspellcast = false;
|
||||
AfterTeleportTimer = 0;
|
||||
Abuse_Bug_Timer = urand(10000, 17000);
|
||||
BugsTimer = 2000;
|
||||
me->ClearUnitState(UNIT_STATE_STUNNED);
|
||||
DontYellWhenDead = false;
|
||||
EnrageTimer = 15*60000;
|
||||
}
|
||||
|
||||
Creature* GetOtherBoss()
|
||||
{
|
||||
return ObjectAccessor::GetCreature(*me, instance->GetData64(IAmVeklor() ? DATA_VEKNILASH : DATA_VEKLOR));
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
Unit* pOtherBoss = GetOtherBoss();
|
||||
if (pOtherBoss)
|
||||
{
|
||||
float dPercent = ((float)damage) / ((float)me->GetMaxHealth());
|
||||
int odmg = (int)(dPercent * ((float)pOtherBoss->GetMaxHealth()));
|
||||
int ohealth = pOtherBoss->GetHealth()-odmg;
|
||||
pOtherBoss->SetHealth(ohealth > 0 ? ohealth : 0);
|
||||
if (ohealth <= 0)
|
||||
{
|
||||
pOtherBoss->setDeathState(JUST_DIED);
|
||||
pOtherBoss->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Creature* pOtherBoss = GetOtherBoss();
|
||||
if (pOtherBoss)
|
||||
{
|
||||
pOtherBoss->SetHealth(0);
|
||||
pOtherBoss->setDeathState(JUST_DIED);
|
||||
pOtherBoss->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
||||
CAST_AI(boss_twinemperorsAI, pOtherBoss->AI())->DontYellWhenDead = true;
|
||||
}
|
||||
if (!DontYellWhenDead) // I hope AI is not threaded
|
||||
DoPlaySoundToSet(me, IAmVeklor() ? SOUND_VL_DEATH : SOUND_VN_DEATH);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
DoPlaySoundToSet(me, IAmVeklor() ? SOUND_VL_KILL : SOUND_VN_KILL);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
DoZoneInCombat();
|
||||
Creature* pOtherBoss = GetOtherBoss();
|
||||
if (pOtherBoss)
|
||||
{
|
||||
/// @todo we should activate the other boss location so he can start attackning even if nobody
|
||||
// is near I dont know how to do that
|
||||
ScriptedAI* otherAI = CAST_AI(ScriptedAI, pOtherBoss->AI());
|
||||
if (!pOtherBoss->IsInCombat())
|
||||
{
|
||||
DoPlaySoundToSet(me, IAmVeklor() ? SOUND_VL_AGGRO : SOUND_VN_AGGRO);
|
||||
otherAI->AttackStart(who);
|
||||
otherAI->DoZoneInCombat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, const SpellInfo* entry)
|
||||
{
|
||||
if (caster == me)
|
||||
return;
|
||||
|
||||
Creature* pOtherBoss = GetOtherBoss();
|
||||
if (entry->Id != SPELL_HEAL_BROTHER || !pOtherBoss)
|
||||
return;
|
||||
|
||||
// add health so we keep same percentage for both brothers
|
||||
uint32 mytotal = me->GetMaxHealth(), histotal = pOtherBoss->GetMaxHealth();
|
||||
float mult = ((float)mytotal) / ((float)histotal);
|
||||
if (mult < 1)
|
||||
mult = 1.0f/mult;
|
||||
#define HEAL_BROTHER_AMOUNT 30000.0f
|
||||
uint32 largerAmount = (uint32)((HEAL_BROTHER_AMOUNT * mult) - HEAL_BROTHER_AMOUNT);
|
||||
|
||||
if (mytotal > histotal)
|
||||
{
|
||||
uint32 h = me->GetHealth()+largerAmount;
|
||||
me->SetHealth(std::min(mytotal, h));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 h = pOtherBoss->GetHealth()+largerAmount;
|
||||
pOtherBoss->SetHealth(std::min(histotal, h));
|
||||
}
|
||||
}
|
||||
|
||||
void TryHealBrother(uint32 diff)
|
||||
{
|
||||
if (IAmVeklor()) // this spell heals caster and the other brother so let VN cast it
|
||||
return;
|
||||
|
||||
if (Heal_Timer <= diff)
|
||||
{
|
||||
Unit* pOtherBoss = GetOtherBoss();
|
||||
if (pOtherBoss && pOtherBoss->IsWithinDist(me, 60))
|
||||
{
|
||||
DoCast(pOtherBoss, SPELL_HEAL_BROTHER);
|
||||
Heal_Timer = 1000;
|
||||
}
|
||||
} else Heal_Timer -= diff;
|
||||
}
|
||||
|
||||
void TeleportToMyBrother()
|
||||
{
|
||||
Teleport_Timer = TELEPORTTIME;
|
||||
|
||||
if (IAmVeklor())
|
||||
return; // mechanics handled by veknilash so they teleport exactly at the same time and to correct coordinates
|
||||
|
||||
Creature* pOtherBoss = GetOtherBoss();
|
||||
if (pOtherBoss)
|
||||
{
|
||||
//me->MonsterYell("Teleporting ...", LANG_UNIVERSAL, 0);
|
||||
Position thisPos;
|
||||
thisPos.Relocate(me);
|
||||
Position otherPos;
|
||||
otherPos.Relocate(pOtherBoss);
|
||||
pOtherBoss->SetPosition(thisPos);
|
||||
me->SetPosition(otherPos);
|
||||
|
||||
SetAfterTeleport();
|
||||
CAST_AI(boss_twinemperorsAI, pOtherBoss->AI())->SetAfterTeleport();
|
||||
}
|
||||
}
|
||||
|
||||
void SetAfterTeleport()
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoStopAttack();
|
||||
DoResetThreat();
|
||||
DoCast(me, SPELL_TWIN_TELEPORT_VISUAL);
|
||||
me->AddUnitState(UNIT_STATE_STUNNED);
|
||||
AfterTeleport = true;
|
||||
AfterTeleportTimer = 2000;
|
||||
tspellcast = false;
|
||||
}
|
||||
|
||||
bool TryActivateAfterTTelep(uint32 diff)
|
||||
{
|
||||
if (AfterTeleport)
|
||||
{
|
||||
if (!tspellcast)
|
||||
{
|
||||
me->ClearUnitState(UNIT_STATE_STUNNED);
|
||||
DoCast(me, SPELL_TWIN_TELEPORT);
|
||||
me->AddUnitState(UNIT_STATE_STUNNED);
|
||||
}
|
||||
|
||||
tspellcast = true;
|
||||
|
||||
if (AfterTeleportTimer <= diff)
|
||||
{
|
||||
AfterTeleport = false;
|
||||
me->ClearUnitState(UNIT_STATE_STUNNED);
|
||||
if (Unit* nearu = me->SelectNearestTarget(100))
|
||||
{
|
||||
//DoYell(nearu->GetName(), LANG_UNIVERSAL, 0);
|
||||
AttackStart(nearu);
|
||||
me->AddThreat(nearu, 10000);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AfterTeleportTimer -= diff;
|
||||
// update important timers which would otherwise get skipped
|
||||
if (EnrageTimer > diff)
|
||||
EnrageTimer -= diff;
|
||||
else
|
||||
EnrageTimer = 0;
|
||||
if (Teleport_Timer > diff)
|
||||
Teleport_Timer -= diff;
|
||||
else
|
||||
Teleport_Timer = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (!who || me->GetVictim())
|
||||
return;
|
||||
|
||||
if (me->_CanDetectFeignDeathOf(who) && me->CanCreatureAttack(who))
|
||||
{
|
||||
if (me->IsWithinDistInMap(who, PULL_RANGE) && me->GetDistanceZ(who) <= /*CREATURE_Z_ATTACK_RANGE*/7 /*there are stairs*/)
|
||||
{
|
||||
//if (who->HasStealthAura())
|
||||
// who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
AttackStart(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Creature* RespawnNearbyBugsAndGetOne()
|
||||
{
|
||||
std::list<Creature*> lUnitList;
|
||||
me->GetCreatureListWithEntryInGrid(lUnitList, 15316, 150.0f);
|
||||
me->GetCreatureListWithEntryInGrid(lUnitList, 15317, 150.0f);
|
||||
|
||||
if (lUnitList.empty())
|
||||
return NULL;
|
||||
|
||||
Creature* nearb = NULL;
|
||||
|
||||
for (std::list<Creature*>::const_iterator iter = lUnitList.begin(); iter != lUnitList.end(); ++iter)
|
||||
{
|
||||
Creature* c = *iter;
|
||||
if (c)
|
||||
{
|
||||
if (c->isDead())
|
||||
{
|
||||
c->Respawn();
|
||||
c->setFaction(7);
|
||||
c->RemoveAllAuras();
|
||||
}
|
||||
if (c->IsWithinDistInMap(me, ABUSE_BUG_RANGE))
|
||||
{
|
||||
if (!nearb || (rand()%4) == 0)
|
||||
nearb = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nearb;
|
||||
}
|
||||
|
||||
void HandleBugs(uint32 diff)
|
||||
{
|
||||
if (BugsTimer < diff || Abuse_Bug_Timer <= diff)
|
||||
{
|
||||
Creature* c = RespawnNearbyBugsAndGetOne();
|
||||
if (Abuse_Bug_Timer <= diff)
|
||||
{
|
||||
if (c)
|
||||
{
|
||||
CastSpellOnBug(c);
|
||||
Abuse_Bug_Timer = urand(10000, 17000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Abuse_Bug_Timer = 1000;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Abuse_Bug_Timer -= diff;
|
||||
}
|
||||
BugsTimer = 2000;
|
||||
}
|
||||
else
|
||||
{
|
||||
BugsTimer -= diff;
|
||||
Abuse_Bug_Timer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckEnrage(uint32 diff)
|
||||
{
|
||||
if (EnrageTimer <= diff)
|
||||
{
|
||||
if (!me->IsNonMeleeSpellCast(true))
|
||||
{
|
||||
DoCast(me, SPELL_BERSERK);
|
||||
EnrageTimer = 60*60000;
|
||||
} else EnrageTimer = 0;
|
||||
} else EnrageTimer-=diff;
|
||||
}
|
||||
};
|
||||
|
||||
class boss_veknilash : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_veknilash() : CreatureScript("boss_veknilash") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_veknilashAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_veknilashAI : public boss_twinemperorsAI
|
||||
{
|
||||
bool IAmVeklor() {return false;}
|
||||
boss_veknilashAI(Creature* creature) : boss_twinemperorsAI(creature) { }
|
||||
|
||||
uint32 UpperCut_Timer;
|
||||
uint32 UnbalancingStrike_Timer;
|
||||
uint32 Scarabs_Timer;
|
||||
int Rand;
|
||||
int RandX;
|
||||
int RandY;
|
||||
|
||||
Creature* Summoned;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
TwinReset();
|
||||
UpperCut_Timer = urand(14000, 29000);
|
||||
UnbalancingStrike_Timer = urand(8000, 18000);
|
||||
Scarabs_Timer = urand(7000, 14000);
|
||||
|
||||
//Added. Can be removed if its included in DB.
|
||||
me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true);
|
||||
}
|
||||
|
||||
void CastSpellOnBug(Creature* target)
|
||||
{
|
||||
target->setFaction(14);
|
||||
target->AI()->AttackStart(me->getThreatManager().getHostilTarget());
|
||||
target->AddAura(SPELL_MUTATE_BUG, target);
|
||||
target->SetFullHealth();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (!TryActivateAfterTTelep(diff))
|
||||
return;
|
||||
|
||||
//UnbalancingStrike_Timer
|
||||
if (UnbalancingStrike_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_UNBALANCING_STRIKE);
|
||||
UnbalancingStrike_Timer = 8000+rand()%12000;
|
||||
} else UnbalancingStrike_Timer -= diff;
|
||||
|
||||
if (UpperCut_Timer <= diff)
|
||||
{
|
||||
Unit* randomMelee = SelectTarget(SELECT_TARGET_RANDOM, 0, NOMINAL_MELEE_RANGE, true);
|
||||
if (randomMelee)
|
||||
DoCast(randomMelee, SPELL_UPPERCUT);
|
||||
UpperCut_Timer = 15000+rand()%15000;
|
||||
} else UpperCut_Timer -= diff;
|
||||
|
||||
HandleBugs(diff);
|
||||
|
||||
//Heal brother when 60yrds close
|
||||
TryHealBrother(diff);
|
||||
|
||||
//Teleporting to brother
|
||||
if (Teleport_Timer <= diff)
|
||||
{
|
||||
TeleportToMyBrother();
|
||||
} else Teleport_Timer -= diff;
|
||||
|
||||
CheckEnrage(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class boss_veklor : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_veklor() : CreatureScript("boss_veklor") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_veklorAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_veklorAI : public boss_twinemperorsAI
|
||||
{
|
||||
bool IAmVeklor() {return true;}
|
||||
boss_veklorAI(Creature* creature) : boss_twinemperorsAI(creature) { }
|
||||
|
||||
uint32 ShadowBolt_Timer;
|
||||
uint32 Blizzard_Timer;
|
||||
uint32 ArcaneBurst_Timer;
|
||||
uint32 Scorpions_Timer;
|
||||
int Rand;
|
||||
int RandX;
|
||||
int RandY;
|
||||
|
||||
Creature* Summoned;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
TwinReset();
|
||||
ShadowBolt_Timer = 0;
|
||||
Blizzard_Timer = urand(15000, 20000);
|
||||
ArcaneBurst_Timer = 1000;
|
||||
Scorpions_Timer = urand(7000, 14000);
|
||||
|
||||
//Added. Can be removed if its included in DB.
|
||||
me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true);
|
||||
}
|
||||
|
||||
void CastSpellOnBug(Creature* target)
|
||||
{
|
||||
target->setFaction(14);
|
||||
target->AddAura(SPELL_EXPLODEBUG, target);
|
||||
target->SetFullHealth();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
// reset arcane burst after teleport - we need to do this because
|
||||
// when VL jumps to VN's location there will be a warrior who will get only 2s to run away
|
||||
// which is almost impossible
|
||||
if (AfterTeleport)
|
||||
ArcaneBurst_Timer = 5000;
|
||||
if (!TryActivateAfterTTelep(diff))
|
||||
return;
|
||||
|
||||
//ShadowBolt_Timer
|
||||
if (ShadowBolt_Timer <= diff)
|
||||
{
|
||||
if (!me->IsWithinDist(me->GetVictim(), 45.0f))
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim(), VEKLOR_DIST, 0);
|
||||
else
|
||||
DoCastVictim(SPELL_SHADOWBOLT);
|
||||
ShadowBolt_Timer = 2000;
|
||||
} else ShadowBolt_Timer -= diff;
|
||||
|
||||
//Blizzard_Timer
|
||||
if (Blizzard_Timer <= diff)
|
||||
{
|
||||
Unit* target = NULL;
|
||||
target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45, true);
|
||||
if (target)
|
||||
DoCast(target, SPELL_BLIZZARD);
|
||||
Blizzard_Timer = 15000+rand()%15000;
|
||||
} else Blizzard_Timer -= diff;
|
||||
|
||||
if (ArcaneBurst_Timer <= diff)
|
||||
{
|
||||
Unit* mvic;
|
||||
if ((mvic=SelectTarget(SELECT_TARGET_NEAREST, 0, NOMINAL_MELEE_RANGE, true)) != NULL)
|
||||
{
|
||||
DoCast(mvic, SPELL_ARCANEBURST);
|
||||
ArcaneBurst_Timer = 5000;
|
||||
}
|
||||
} else ArcaneBurst_Timer -= diff;
|
||||
|
||||
HandleBugs(diff);
|
||||
|
||||
//Heal brother when 60yrds close
|
||||
TryHealBrother(diff);
|
||||
|
||||
//Teleporting to brother
|
||||
if (Teleport_Timer <= diff)
|
||||
{
|
||||
TeleportToMyBrother();
|
||||
} else Teleport_Timer -= diff;
|
||||
|
||||
CheckEnrage(diff);
|
||||
|
||||
//VL doesn't melee
|
||||
//DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who)
|
||||
{
|
||||
if (!who)
|
||||
return;
|
||||
|
||||
if (who->isTargetableForAttack())
|
||||
{
|
||||
// VL doesn't melee
|
||||
if (me->Attack(who, false))
|
||||
{
|
||||
me->GetMotionMaster()->MoveChase(who, VEKLOR_DIST, 0);
|
||||
me->AddThreat(who, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_twinemperors()
|
||||
{
|
||||
new boss_veknilash();
|
||||
new boss_veklor();
|
||||
}
|
||||
@@ -1,306 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "SpellInfo.h"
|
||||
#include "temple_of_ahnqiraj.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_POISON_SHOCK = 25993,
|
||||
SPELL_POISONBOLT_VOLLEY = 25991,
|
||||
SPELL_TOXIN = 26575,
|
||||
SPELL_VISCIDUS_SLOWED = 26034,
|
||||
SPELL_VISCIDUS_SLOWED_MORE = 26036,
|
||||
SPELL_VISCIDUS_FREEZE = 25937,
|
||||
SPELL_REJOIN_VISCIDUS = 25896,
|
||||
SPELL_VISCIDUS_EXPLODE = 25938,
|
||||
SPELL_VISCIDUS_SUICIDE = 26003,
|
||||
SPELL_VISCIDUS_SHRINKS = 25893, // Removed from client, in world.spell_dbc
|
||||
|
||||
SPELL_MEMBRANE_VISCIDUS = 25994, // damage reduction spell - removed from DBC
|
||||
SPELL_VISCIDUS_WEAKNESS = 25926, // aura which procs at damage - should trigger the slow spells - removed from DBC
|
||||
SPELL_VISCIDUS_GROWS = 25897, // removed from DBC
|
||||
SPELL_SUMMON_GLOBS = 25885, // summons npc 15667 using spells from 25865 to 25884; All spells have target coords - removed from DBC
|
||||
SPELL_VISCIDUS_TELEPORT = 25904, // removed from DBC
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_POISONBOLT_VOLLEY = 1,
|
||||
EVENT_POISON_SHOCK = 2,
|
||||
EVENT_RESET_PHASE = 3
|
||||
};
|
||||
|
||||
enum Phases
|
||||
{
|
||||
PHASE_FROST = 1,
|
||||
PHASE_MELEE = 2,
|
||||
PHASE_GLOB = 3
|
||||
};
|
||||
|
||||
enum Emotes
|
||||
{
|
||||
EMOTE_SLOW = 0,
|
||||
EMOTE_FREEZE = 1,
|
||||
EMOTE_FROZEN = 2,
|
||||
|
||||
EMOTE_CRACK = 3,
|
||||
EMOTE_SHATTER = 4,
|
||||
EMOTE_EXPLODE = 5
|
||||
};
|
||||
|
||||
enum HitCounter
|
||||
{
|
||||
HITCOUNTER_SLOW = 100,
|
||||
HITCOUNTER_SLOW_MORE = 150,
|
||||
HITCOUNTER_FREEZE = 200,
|
||||
|
||||
HITCOUNTER_CRACK = 50,
|
||||
HITCOUNTER_SHATTER = 100,
|
||||
HITCOUNTER_EXPLODE = 150,
|
||||
};
|
||||
|
||||
enum MovePoints
|
||||
{
|
||||
ROOM_CENTER = 1
|
||||
};
|
||||
|
||||
Position const ViscidusCoord = { -7992.36f, 908.19f, -52.62f, 1.68f }; /// @todo Visci isn't in room middle
|
||||
float const RoomRadius = 40.0f; /// @todo Not sure if its correct
|
||||
|
||||
class boss_viscidus : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_viscidus() : CreatureScript("boss_viscidus") { }
|
||||
|
||||
struct boss_viscidusAI : public BossAI
|
||||
{
|
||||
boss_viscidusAI(Creature* creature) : BossAI(creature, DATA_VISCIDUS) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
_hitcounter = 0;
|
||||
_phase = PHASE_FROST;
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* attacker, uint32& /*damage*/, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (!attacker || _phase != PHASE_MELEE)
|
||||
return;
|
||||
|
||||
++_hitcounter;
|
||||
|
||||
if (attacker->HasUnitState(UNIT_STATE_MELEE_ATTACKING) && _hitcounter >= HITCOUNTER_EXPLODE)
|
||||
{
|
||||
Talk(EMOTE_EXPLODE);
|
||||
events.Reset();
|
||||
_phase = PHASE_GLOB;
|
||||
DoCast(me, SPELL_VISCIDUS_EXPLODE);
|
||||
me->SetVisible(false);
|
||||
me->RemoveAura(SPELL_TOXIN);
|
||||
me->RemoveAura(SPELL_VISCIDUS_FREEZE);
|
||||
|
||||
uint8 NumGlobes = me->GetHealthPct() / 5.0f;
|
||||
for (uint8 i = 0; i < NumGlobes; ++i)
|
||||
{
|
||||
float Angle = i * 2 * M_PI / NumGlobes;
|
||||
float X = ViscidusCoord.GetPositionX() + std::cos(Angle) * RoomRadius;
|
||||
float Y = ViscidusCoord.GetPositionY() + std::sin(Angle) * RoomRadius;
|
||||
float Z = -35.0f;
|
||||
|
||||
if (TempSummon* Glob = me->SummonCreature(NPC_GLOB_OF_VISCIDUS, X, Y, Z))
|
||||
{
|
||||
Glob->UpdateAllowedPositionZ(X, Y, Z);
|
||||
Glob->NearTeleportTo(X, Y, Z, 0.0f);
|
||||
Glob->GetMotionMaster()->MovePoint(ROOM_CENTER, ViscidusCoord);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (_hitcounter == HITCOUNTER_SHATTER)
|
||||
Talk(EMOTE_SHATTER);
|
||||
else if (_hitcounter == HITCOUNTER_CRACK)
|
||||
Talk(EMOTE_CRACK);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spell)
|
||||
{
|
||||
if ((spell->GetSchoolMask() & SPELL_SCHOOL_MASK_FROST) && _phase == PHASE_FROST && me->GetHealthPct() > 5.0f)
|
||||
{
|
||||
++_hitcounter;
|
||||
|
||||
if (_hitcounter >= HITCOUNTER_FREEZE)
|
||||
{
|
||||
_hitcounter = 0;
|
||||
Talk(EMOTE_FROZEN);
|
||||
_phase = PHASE_MELEE;
|
||||
DoCast(me, SPELL_VISCIDUS_FREEZE);
|
||||
me->RemoveAura(SPELL_VISCIDUS_SLOWED_MORE);
|
||||
events.ScheduleEvent(EVENT_RESET_PHASE, 15000);
|
||||
}
|
||||
else if (_hitcounter >= HITCOUNTER_SLOW_MORE)
|
||||
{
|
||||
Talk(EMOTE_FREEZE);
|
||||
me->RemoveAura(SPELL_VISCIDUS_SLOWED);
|
||||
DoCast(me, SPELL_VISCIDUS_SLOWED_MORE);
|
||||
}
|
||||
else if (_hitcounter >= HITCOUNTER_SLOW)
|
||||
{
|
||||
Talk(EMOTE_SLOW);
|
||||
DoCast(me, SPELL_VISCIDUS_SLOWED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
events.Reset();
|
||||
InitSpells();
|
||||
}
|
||||
|
||||
void InitSpells()
|
||||
{
|
||||
DoCast(me, SPELL_TOXIN);
|
||||
events.ScheduleEvent(EVENT_POISONBOLT_VOLLEY, urand(10000, 15000));
|
||||
events.ScheduleEvent(EVENT_POISON_SHOCK, urand(7000, 12000));
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
summons.DespawnAll();
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
DoCast(me, SPELL_VISCIDUS_SUICIDE);
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (_phase == PHASE_GLOB && summons.empty())
|
||||
{
|
||||
DoResetThreat();
|
||||
me->NearTeleportTo(ViscidusCoord.GetPositionX(),
|
||||
ViscidusCoord.GetPositionY(),
|
||||
ViscidusCoord.GetPositionZ(),
|
||||
ViscidusCoord.GetOrientation());
|
||||
|
||||
_hitcounter = 0;
|
||||
_phase = PHASE_FROST;
|
||||
InitSpells();
|
||||
me->SetVisible(true);
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_POISONBOLT_VOLLEY:
|
||||
DoCast(me, SPELL_POISONBOLT_VOLLEY);
|
||||
events.ScheduleEvent(EVENT_POISONBOLT_VOLLEY, urand(10000, 15000));
|
||||
break;
|
||||
case EVENT_POISON_SHOCK:
|
||||
DoCast(me, SPELL_POISON_SHOCK);
|
||||
events.ScheduleEvent(EVENT_POISON_SHOCK, urand(7000, 12000));
|
||||
break;
|
||||
case EVENT_RESET_PHASE:
|
||||
_hitcounter = 0;
|
||||
_phase = PHASE_FROST;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_phase != PHASE_GLOB)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _hitcounter;
|
||||
Phases _phase;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_viscidusAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_glob_of_viscidus : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_glob_of_viscidus() : CreatureScript("boss_glob_of_viscidus") { }
|
||||
|
||||
struct npc_glob_of_viscidusAI : public ScriptedAI
|
||||
{
|
||||
npc_glob_of_viscidusAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
InstanceScript* Instance = me->GetInstanceScript();
|
||||
|
||||
if (Creature* Viscidus = me->GetMap()->GetCreature(Instance->GetData64(DATA_VISCIDUS)))
|
||||
{
|
||||
if (BossAI* ViscidusAI = dynamic_cast<BossAI*>(Viscidus->GetAI()))
|
||||
ViscidusAI->SummonedCreatureDespawn(me);
|
||||
|
||||
if (Viscidus->IsAlive() && Viscidus->GetHealthPct() < 5.0f)
|
||||
{
|
||||
Viscidus->SetVisible(true);
|
||||
Unit::Kill(Viscidus->GetVictim(), Viscidus);
|
||||
}
|
||||
else
|
||||
{
|
||||
Viscidus->SetHealth(Viscidus->GetHealth() - Viscidus->GetMaxHealth() / 20);
|
||||
Viscidus->CastSpell(Viscidus, SPELL_VISCIDUS_SHRINKS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 /*type*/, uint32 id)
|
||||
{
|
||||
if (id == ROOM_CENTER)
|
||||
{
|
||||
DoCast(me, SPELL_REJOIN_VISCIDUS);
|
||||
if (TempSummon* summon = me->ToTempSummon())
|
||||
summon->UnSummon();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_glob_of_viscidusAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_viscidus()
|
||||
{
|
||||
new boss_viscidus();
|
||||
new npc_glob_of_viscidus();
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Instance_Temple_of_Ahnqiraj
|
||||
SD%Complete: 80
|
||||
SDComment:
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "temple_of_ahnqiraj.h"
|
||||
|
||||
class instance_temple_of_ahnqiraj : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_temple_of_ahnqiraj() : InstanceMapScript("instance_temple_of_ahnqiraj", 531) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_temple_of_ahnqiraj_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
struct instance_temple_of_ahnqiraj_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_temple_of_ahnqiraj_InstanceMapScript(Map* map) : InstanceScript(map) { }
|
||||
|
||||
//If Vem is dead...
|
||||
bool IsBossDied[3];
|
||||
|
||||
//Storing Skeram, Vem and Kri.
|
||||
uint64 SkeramGUID;
|
||||
uint64 VemGUID;
|
||||
uint64 KriGUID;
|
||||
uint64 VeklorGUID;
|
||||
uint64 VeknilashGUID;
|
||||
uint64 ViscidusGUID;
|
||||
|
||||
uint32 BugTrioDeathCount;
|
||||
|
||||
uint32 CthunPhase;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
IsBossDied[0] = false;
|
||||
IsBossDied[1] = false;
|
||||
IsBossDied[2] = false;
|
||||
|
||||
SkeramGUID = 0;
|
||||
VemGUID = 0;
|
||||
KriGUID = 0;
|
||||
VeklorGUID = 0;
|
||||
VeknilashGUID = 0;
|
||||
ViscidusGUID = 0;
|
||||
|
||||
BugTrioDeathCount = 0;
|
||||
|
||||
CthunPhase = 0;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_SKERAM:
|
||||
SkeramGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_VEM:
|
||||
VemGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_KRI:
|
||||
KriGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_VEKLOR:
|
||||
VeklorGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_VEKNILASH:
|
||||
VeknilashGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_VISCIDUS:
|
||||
ViscidusGUID = creature->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
//not active in AQ40
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_VEMISDEAD:
|
||||
if (IsBossDied[0])
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case DATA_VEKLORISDEAD:
|
||||
if (IsBossDied[1])
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case DATA_VEKNILASHISDEAD:
|
||||
if (IsBossDied[2])
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case DATA_BUG_TRIO_DEATH:
|
||||
return BugTrioDeathCount;
|
||||
|
||||
case DATA_CTHUN_PHASE:
|
||||
return CthunPhase;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 identifier) const
|
||||
{
|
||||
switch (identifier)
|
||||
{
|
||||
case DATA_SKERAM:
|
||||
return SkeramGUID;
|
||||
case DATA_VEM:
|
||||
return VemGUID;
|
||||
case DATA_KRI:
|
||||
return KriGUID;
|
||||
case DATA_VEKLOR:
|
||||
return VeklorGUID;
|
||||
case DATA_VEKNILASH:
|
||||
return VeknilashGUID;
|
||||
case DATA_VISCIDUS:
|
||||
return ViscidusGUID;
|
||||
}
|
||||
return 0;
|
||||
} // end GetData64
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_VEM_DEATH:
|
||||
IsBossDied[0] = true;
|
||||
break;
|
||||
|
||||
case DATA_BUG_TRIO_DEATH:
|
||||
++BugTrioDeathCount;
|
||||
break;
|
||||
|
||||
case DATA_VEKLOR_DEATH:
|
||||
IsBossDied[1] = true;
|
||||
break;
|
||||
|
||||
case DATA_VEKNILASH_DEATH:
|
||||
IsBossDied[2] = true;
|
||||
break;
|
||||
|
||||
case DATA_CTHUN_PHASE:
|
||||
CthunPhase = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_instance_temple_of_ahnqiraj()
|
||||
{
|
||||
new instance_temple_of_ahnqiraj();
|
||||
}
|
||||
@@ -1,268 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: npc_anubisath_sentinel
|
||||
SD%Complete: 95
|
||||
SDComment: Shadow storm is not properly implemented in core it should only target ppl outside of melee range.
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
#include "Item.h"
|
||||
#include "Player.h"
|
||||
#include "Spell.h"
|
||||
|
||||
#include "Cell.h"
|
||||
#include "CellImpl.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_MENDING_BUFF = 2147,
|
||||
|
||||
SPELL_KNOCK_BUFF = 21737,
|
||||
SPELL_KNOCK = 25778,
|
||||
SPELL_MANAB_BUFF = 812,
|
||||
SPELL_MANAB = 25779,
|
||||
|
||||
SPELL_REFLECTAF_BUFF = 13022,
|
||||
SPELL_REFLECTSFr_BUFF = 19595,
|
||||
SPELL_THORNS_BUFF = 25777,
|
||||
|
||||
SPELL_THUNDER_BUFF = 2834,
|
||||
SPELL_THUNDER = 8732,
|
||||
|
||||
SPELL_MSTRIKE_BUFF = 9347,
|
||||
SPELL_MSTRIKE = 24573,
|
||||
|
||||
SPELL_STORM_BUFF = 2148,
|
||||
SPELL_STORM = 26546
|
||||
};
|
||||
|
||||
class npc_anubisath_sentinel : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_anubisath_sentinel() : CreatureScript("npc_anubisath_sentinel") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new aqsentinelAI(creature);
|
||||
}
|
||||
|
||||
struct aqsentinelAI : public ScriptedAI
|
||||
{
|
||||
uint32 ability;
|
||||
int abselected;
|
||||
|
||||
void selectAbility(int asel)
|
||||
{
|
||||
switch (asel)
|
||||
{
|
||||
case 0: ability = SPELL_MENDING_BUFF;break;
|
||||
case 1: ability = SPELL_KNOCK_BUFF;break;
|
||||
case 2: ability = SPELL_MANAB_BUFF;break;
|
||||
case 3: ability = SPELL_REFLECTAF_BUFF;break;
|
||||
case 4: ability = SPELL_REFLECTSFr_BUFF;break;
|
||||
case 5: ability = SPELL_THORNS_BUFF;break;
|
||||
case 6: ability = SPELL_THUNDER_BUFF;break;
|
||||
case 7: ability = SPELL_MSTRIKE_BUFF;break;
|
||||
case 8: ability = SPELL_STORM_BUFF;break;
|
||||
}
|
||||
}
|
||||
|
||||
aqsentinelAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
ClearBuddyList();
|
||||
abselected = 0; // just initialization of variable
|
||||
}
|
||||
|
||||
uint64 NearbyGUID[3];
|
||||
|
||||
void ClearBuddyList()
|
||||
{
|
||||
NearbyGUID[0] = NearbyGUID[1] = NearbyGUID[2] = 0;
|
||||
}
|
||||
|
||||
void AddBuddyToList(uint64 CreatureGUID)
|
||||
{
|
||||
if (CreatureGUID == me->GetGUID())
|
||||
return;
|
||||
|
||||
for (int i=0; i<3; ++i)
|
||||
{
|
||||
if (NearbyGUID[i] == CreatureGUID)
|
||||
return;
|
||||
if (!NearbyGUID[i])
|
||||
{
|
||||
NearbyGUID[i] = CreatureGUID;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GiveBuddyMyList(Creature* c)
|
||||
{
|
||||
aqsentinelAI* cai = CAST_AI(aqsentinelAI, (c)->AI());
|
||||
for (int i=0; i<3; ++i)
|
||||
if (NearbyGUID[i] && NearbyGUID[i] != c->GetGUID())
|
||||
cai->AddBuddyToList(NearbyGUID[i]);
|
||||
cai->AddBuddyToList(me->GetGUID());
|
||||
}
|
||||
|
||||
void SendMyListToBuddies()
|
||||
{
|
||||
for (int i=0; i<3; ++i)
|
||||
if (Creature* pNearby = ObjectAccessor::GetCreature(*me, NearbyGUID[i]))
|
||||
GiveBuddyMyList(pNearby);
|
||||
}
|
||||
|
||||
void CallBuddiesToAttack(Unit* who)
|
||||
{
|
||||
for (int i=0; i<3; ++i)
|
||||
{
|
||||
Creature* c = ObjectAccessor::GetCreature(*me, NearbyGUID[i]);
|
||||
if (c)
|
||||
{
|
||||
if (!c->IsInCombat())
|
||||
{
|
||||
c->SetNoCallAssistance(true);
|
||||
if (c->AI())
|
||||
c->AI()->AttackStart(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddSentinelsNear(Unit* /*nears*/)
|
||||
{
|
||||
std::list<Creature*> assistList;
|
||||
me->GetCreatureListWithEntryInGrid(assistList, 15264, 70.0f);
|
||||
|
||||
if (assistList.empty())
|
||||
return;
|
||||
|
||||
for (std::list<Creature*>::const_iterator iter = assistList.begin(); iter != assistList.end(); ++iter)
|
||||
AddBuddyToList((*iter)->GetGUID());
|
||||
}
|
||||
|
||||
int pickAbilityRandom(bool *chosenAbilities)
|
||||
{
|
||||
for (int t = 0; t < 2; ++t)
|
||||
{
|
||||
for (int i = !t ? (rand()%9) : 0; i < 9; ++i)
|
||||
{
|
||||
if (!chosenAbilities[i])
|
||||
{
|
||||
chosenAbilities[i] = true;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0; // should never happen
|
||||
}
|
||||
|
||||
void GetOtherSentinels(Unit* who)
|
||||
{
|
||||
bool *chosenAbilities = new bool[9];
|
||||
memset(chosenAbilities, 0, 9*sizeof(bool));
|
||||
selectAbility(pickAbilityRandom(chosenAbilities));
|
||||
|
||||
ClearBuddyList();
|
||||
AddSentinelsNear(me);
|
||||
int bli;
|
||||
for (bli = 0; bli < 3; ++bli)
|
||||
{
|
||||
if (!NearbyGUID[bli])
|
||||
break;
|
||||
|
||||
Creature* pNearby = ObjectAccessor::GetCreature(*me, NearbyGUID[bli]);
|
||||
if (!pNearby)
|
||||
break;
|
||||
|
||||
AddSentinelsNear(pNearby);
|
||||
CAST_AI(aqsentinelAI, pNearby->AI())->gatherOthersWhenAggro = false;
|
||||
CAST_AI(aqsentinelAI, pNearby->AI())->selectAbility(pickAbilityRandom(chosenAbilities));
|
||||
}
|
||||
/*if (bli < 3)
|
||||
DoYell("I dont have enough buddies.", LANG_NEUTRAL, 0);*/
|
||||
SendMyListToBuddies();
|
||||
CallBuddiesToAttack(who);
|
||||
|
||||
delete[] chosenAbilities;
|
||||
}
|
||||
|
||||
bool gatherOthersWhenAggro;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (!me->isDead())
|
||||
{
|
||||
for (int i=0; i<3; ++i)
|
||||
{
|
||||
if (!NearbyGUID[i])
|
||||
continue;
|
||||
if (Creature* pNearby = ObjectAccessor::GetCreature(*me, NearbyGUID[i]))
|
||||
{
|
||||
if (pNearby->isDead())
|
||||
pNearby->Respawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
ClearBuddyList();
|
||||
gatherOthersWhenAggro = true;
|
||||
}
|
||||
|
||||
void GainSentinelAbility(uint32 id)
|
||||
{
|
||||
me->AddAura(id, me);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
if (gatherOthersWhenAggro)
|
||||
GetOtherSentinels(who);
|
||||
|
||||
GainSentinelAbility(ability);
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
for (int ni=0; ni<3; ++ni)
|
||||
{
|
||||
Creature* sent = ObjectAccessor::GetCreature(*me, NearbyGUID[ni]);
|
||||
if (!sent)
|
||||
continue;
|
||||
if (sent->isDead())
|
||||
continue;
|
||||
sent->ModifyHealth(int32(sent->CountPctFromMaxHealth(50)));
|
||||
CAST_AI(aqsentinelAI, sent->AI())->GainSentinelAbility(ability);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_npc_anubisath_sentinel()
|
||||
{
|
||||
new npc_anubisath_sentinel();
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef DEF_TEMPLE_OF_AHNQIRAJ_H
|
||||
#define DEF_TEMPLE_OF_AHNQIRAJ_H
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
DATA_SKERAM = 1,
|
||||
DATA_KRI = 2,
|
||||
DATA_VEM = 3,
|
||||
DATA_VEMISDEAD = 4,
|
||||
DATA_VEM_DEATH = 5,
|
||||
DATA_VEKLOR = 6,
|
||||
DATA_VEKLORISDEAD = 7,
|
||||
DATA_VEKLOR_DEATH = 8,
|
||||
DATA_VEKNILASH = 9,
|
||||
DATA_VEKNILASHISDEAD = 10,
|
||||
DATA_VEKNILASH_DEATH = 11,
|
||||
DATA_BUG_TRIO_DEATH = 14,
|
||||
DATA_CTHUN_PHASE = 20,
|
||||
DATA_VISCIDUS = 21
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
BOSS_EYE_OF_CTHUN = 15589,
|
||||
NPC_CTHUN_PORTAL = 15896,
|
||||
NPC_CLAW_TENTACLE = 15725,
|
||||
NPC_EYE_TENTACLE = 15726,
|
||||
NPC_SMALL_PORTAL = 15904,
|
||||
NPC_BODY_OF_CTHUN = 15809,
|
||||
NPC_GIANT_CLAW_TENTACLE = 15728,
|
||||
NPC_GIANT_EYE_TENTACLE = 15334,
|
||||
NPC_FLESH_TENTACLE = 15802,
|
||||
NPC_GIANT_PORTAL = 15910,
|
||||
|
||||
NPC_VISCIDUS = 15299,
|
||||
NPC_GLOB_OF_VISCIDUS = 15667,
|
||||
|
||||
NPC_SKERAM = 15263,
|
||||
NPC_VEM = 15544,
|
||||
NPC_KRI = 15511,
|
||||
NPC_VEKLOR = 15276,
|
||||
NPC_VEKNILASH = 15275
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "wailing_caverns.h"
|
||||
|
||||
class instance_wailing_caverns : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_wailing_caverns() : InstanceMapScript("instance_wailing_caverns", 43) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_wailing_caverns_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
struct instance_wailing_caverns_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_wailing_caverns_InstanceMapScript(Map* map) : InstanceScript(map) { }
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
memset(&_encounters, 0, sizeof(_encounters));
|
||||
|
||||
DiscipleOfNaralexGUID = 0;
|
||||
SerpentisGUID = 0;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
if (creature->GetEntry() == NPC_DISCIPLE_OF_NARALEX)
|
||||
DiscipleOfNaralexGUID = creature->GetGUID();
|
||||
else if (creature->GetEntry() == NPC_LORD_SERPENTIS)
|
||||
SerpentisGUID = creature->GetGUID();
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_LORD_COBRAHN:
|
||||
case TYPE_LORD_PYTHAS:
|
||||
case TYPE_LADY_ANACONDRA:
|
||||
case TYPE_LORD_SERPENTIS:
|
||||
case TYPE_MUTANUS:
|
||||
_encounters[type] = data;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data == DONE)
|
||||
SaveToDB();
|
||||
|
||||
if (type == TYPE_LORD_COBRAHN && _encounters[TYPE_LORD_SERPENTIS] != DONE)
|
||||
{
|
||||
instance->LoadGrid(-120.163f, -24.624f);
|
||||
if (Creature* serpentis = instance->GetCreature(SerpentisGUID))
|
||||
serpentis->AI()->Talk(SAY_SERPENTIS);
|
||||
}
|
||||
|
||||
if (type != TYPE_MUTANUS && _encounters[TYPE_LORD_COBRAHN] == DONE && _encounters[TYPE_LORD_PYTHAS] == DONE &&
|
||||
_encounters[TYPE_LADY_ANACONDRA] == DONE && _encounters[TYPE_LORD_SERPENTIS] == DONE)
|
||||
{
|
||||
instance->LoadGrid(-134.97f, 125.402f);
|
||||
if (Creature* disciple = instance->GetCreature(DiscipleOfNaralexGUID))
|
||||
disciple->AI()->Talk(SAY_DISCIPLE);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_LORD_COBRAHN:
|
||||
case TYPE_LORD_PYTHAS:
|
||||
case TYPE_LADY_ANACONDRA:
|
||||
case TYPE_LORD_SERPENTIS:
|
||||
return _encounters[type];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "W C " << _encounters[0] << ' ' << _encounters[1] << ' ' << _encounters[2] << ' ' << _encounters[3] << ' ' << _encounters[4];
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
return;
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2;
|
||||
if (dataHead1 == 'W' && dataHead2 == 'C')
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
|
||||
{
|
||||
loadStream >> _encounters[i];
|
||||
if (_encounters[i] == IN_PROGRESS)
|
||||
_encounters[i] = NOT_STARTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _encounters[MAX_ENCOUNTERS];
|
||||
uint64 DiscipleOfNaralexGUID;
|
||||
uint64 SerpentisGUID;
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_instance_wailing_caverns()
|
||||
{
|
||||
new instance_wailing_caverns();
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef DEF_WAILING_CAVERNS_H
|
||||
#define DEF_WAILING_CAVERNS_H
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
TYPE_LORD_COBRAHN = 0,
|
||||
TYPE_LORD_PYTHAS = 1,
|
||||
TYPE_LADY_ANACONDRA = 2,
|
||||
TYPE_LORD_SERPENTIS = 3,
|
||||
TYPE_MUTANUS = 4,
|
||||
MAX_ENCOUNTERS = 5,
|
||||
|
||||
NPC_DISCIPLE_OF_NARALEX = 3678,
|
||||
NPC_LORD_SERPENTIS = 3673,
|
||||
|
||||
SAY_DISCIPLE = 0,
|
||||
SAY_SERPENTIS = 0,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "zulfarrak.h"
|
||||
#include "Player.h"
|
||||
#include "TemporarySummon.h"
|
||||
|
||||
class instance_zulfarrak : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_zulfarrak() : InstanceMapScript("instance_zulfarrak", 209) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_zulfarrak_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
struct instance_zulfarrak_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_zulfarrak_InstanceMapScript(Map* map) : InstanceScript(map) { }
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_pyramidEventProgress = NOT_STARTED;
|
||||
_gahzrillaSummoned = NOT_STARTED;
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* gameobject)
|
||||
{
|
||||
if (gameobject->GetEntry() == GO_END_DOOR && _pyramidEventProgress == DONE)
|
||||
gameobject->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const
|
||||
{
|
||||
if (type == TYPE_PYRAMID_EVENT)
|
||||
return _pyramidEventProgress;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_PYRAMID_EVENT:
|
||||
_pyramidEventProgress = data;
|
||||
break;
|
||||
case TYPE_GAHZRILLA:
|
||||
_gahzrillaSummoned = data;
|
||||
break;
|
||||
}
|
||||
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "Z F " << _pyramidEventProgress << ' ' << _gahzrillaSummoned;
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* str)
|
||||
{
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
std::istringstream loadStream(str);
|
||||
loadStream >> dataHead1 >> dataHead2;
|
||||
|
||||
if (dataHead1 == 'Z' && dataHead2 == 'F')
|
||||
{
|
||||
loadStream >> _pyramidEventProgress;
|
||||
loadStream >> _gahzrillaSummoned;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _pyramidEventProgress;
|
||||
uint32 _gahzrillaSummoned;
|
||||
};
|
||||
};
|
||||
|
||||
class spell_zulfarrak_summon_zulfarrak_zombies : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_zulfarrak_summon_zulfarrak_zombies() : SpellScriptLoader("spell_zulfarrak_summon_zulfarrak_zombies") { }
|
||||
|
||||
class spell_zulfarrak_summon_zulfarrak_zombies_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_zulfarrak_summon_zulfarrak_zombies_SpellScript);
|
||||
|
||||
void HandleSummon(SpellEffIndex effIndex)
|
||||
{
|
||||
if (effIndex == EFFECT_0)
|
||||
{
|
||||
if (roll_chance_i(30))
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (roll_chance_i(40))
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHit += SpellEffectFn(spell_zulfarrak_summon_zulfarrak_zombies_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON);
|
||||
OnEffectHit += SpellEffectFn(spell_zulfarrak_summon_zulfarrak_zombies_SpellScript::HandleSummon, EFFECT_1, SPELL_EFFECT_SUMMON);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_zulfarrak_summon_zulfarrak_zombies_SpellScript;
|
||||
}
|
||||
};
|
||||
|
||||
class spell_zulfarrak_unlocking : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_zulfarrak_unlocking() : SpellScriptLoader("spell_zulfarrak_unlocking") { }
|
||||
|
||||
class spell_zulfarrak_unlocking_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_zulfarrak_unlocking_SpellScript);
|
||||
|
||||
void HandleOpenLock(SpellEffIndex effIndex)
|
||||
{
|
||||
GameObject* cage = GetHitGObj();
|
||||
std::list<WorldObject*> cagesList;
|
||||
Trinity::AllWorldObjectsInRange objects(GetCaster(), 15.0f);
|
||||
Trinity::WorldObjectListSearcher<Trinity::AllWorldObjectsInRange> searcher(GetCaster(), cagesList, objects);
|
||||
GetCaster()->VisitNearbyObject(15.0f, searcher);
|
||||
for (std::list<WorldObject*>::const_iterator itr = cagesList.begin(); itr != cagesList.end(); ++itr)
|
||||
{
|
||||
if (GameObject* go = (*itr)->ToGameObject())
|
||||
if (go->GetDisplayId() == cage->GetDisplayId())
|
||||
go->UseDoorOrButton(0, false, GetCaster());
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_zulfarrak_unlocking_SpellScript::HandleOpenLock, EFFECT_0, SPELL_EFFECT_OPEN_LOCK);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_zulfarrak_unlocking_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_zulfarrak()
|
||||
{
|
||||
new instance_zulfarrak();
|
||||
new spell_zulfarrak_summon_zulfarrak_zombies();
|
||||
new spell_zulfarrak_unlocking();
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef DEF_ZULFARRACK_H
|
||||
#define DEF_ZULFARRACK_H
|
||||
|
||||
enum ZulFarrakData
|
||||
{
|
||||
TYPE_PYRAMID_EVENT = 0,
|
||||
TYPE_GAHZRILLA = 1,
|
||||
|
||||
GO_END_DOOR = 146084
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Boss_Azuregos
|
||||
SD%Complete: 90
|
||||
SDComment: Teleport not included, spell reflect not effecting dots (Core problem)
|
||||
SDCategory: Azshara
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
enum Say
|
||||
{
|
||||
SAY_TELEPORT = 0
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_MARKOFFROST = 23182,
|
||||
SPELL_MANASTORM = 21097,
|
||||
SPELL_CHILL = 21098,
|
||||
SPELL_FROSTBREATH = 21099,
|
||||
SPELL_REFLECT = 22067,
|
||||
SPELL_CLEAVE = 8255, //Perhaps not right ID
|
||||
SPELL_ENRAGE = 23537
|
||||
};
|
||||
|
||||
class boss_azuregos : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_azuregos() : CreatureScript("boss_azuregos") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_azuregosAI(creature);
|
||||
}
|
||||
|
||||
struct boss_azuregosAI : public ScriptedAI
|
||||
{
|
||||
boss_azuregosAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 MarkOfFrostTimer;
|
||||
uint32 ManaStormTimer;
|
||||
uint32 ChillTimer;
|
||||
uint32 BreathTimer;
|
||||
uint32 TeleportTimer;
|
||||
uint32 ReflectTimer;
|
||||
uint32 CleaveTimer;
|
||||
uint32 EnrageTimer;
|
||||
bool Enraged;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
MarkOfFrostTimer = 35000;
|
||||
ManaStormTimer = urand(5000, 17000);
|
||||
ChillTimer = urand(10000, 30000);
|
||||
BreathTimer = urand(2000, 8000);
|
||||
TeleportTimer = 30000;
|
||||
ReflectTimer = urand(15000, 30000);
|
||||
CleaveTimer = 7000;
|
||||
EnrageTimer = 0;
|
||||
Enraged = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (TeleportTimer <= diff)
|
||||
{
|
||||
Talk(SAY_TELEPORT);
|
||||
ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
|
||||
ThreatContainer::StorageType::const_iterator i = threatlist.begin();
|
||||
for (i = threatlist.begin(); i != threatlist.end(); ++i)
|
||||
{
|
||||
Unit* unit = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid());
|
||||
if (unit && (unit->GetTypeId() == TYPEID_PLAYER))
|
||||
{
|
||||
DoTeleportPlayer(unit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+3, unit->GetOrientation());
|
||||
}
|
||||
}
|
||||
|
||||
DoResetThreat();
|
||||
TeleportTimer = 30000;
|
||||
} else TeleportTimer -= diff;
|
||||
|
||||
// //MarkOfFrostTimer
|
||||
// if (MarkOfFrostTimer <= diff)
|
||||
// {
|
||||
// DoCastVictim(SPELL_MARKOFFROST);
|
||||
// MarkOfFrostTimer = 25000;
|
||||
// } else MarkOfFrostTimer -= diff;
|
||||
|
||||
//ChillTimer
|
||||
if (ChillTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_CHILL);
|
||||
ChillTimer = urand(13000, 25000);
|
||||
} else ChillTimer -= diff;
|
||||
|
||||
//BreathTimer
|
||||
if (BreathTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_FROSTBREATH);
|
||||
BreathTimer = urand(10000, 15000);
|
||||
} else BreathTimer -= diff;
|
||||
|
||||
//ManaStormTimer
|
||||
if (ManaStormTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_MANASTORM);
|
||||
ManaStormTimer = urand(7500, 12500);
|
||||
} else ManaStormTimer -= diff;
|
||||
|
||||
//ReflectTimer
|
||||
if (ReflectTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_REFLECT);
|
||||
ReflectTimer = urand(20000, 35000);
|
||||
} else ReflectTimer -= diff;
|
||||
|
||||
//CleaveTimer
|
||||
if (CleaveTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
CleaveTimer = 7000;
|
||||
} else CleaveTimer -= diff;
|
||||
|
||||
//EnrageTimer
|
||||
if (HealthBelowPct(26) && !Enraged)
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
Enraged = true;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_boss_azuregos()
|
||||
{
|
||||
new boss_azuregos();
|
||||
}
|
||||
@@ -1,344 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Ashenvale
|
||||
SD%Complete: 70
|
||||
SDComment: Quest support: 6544, 6482
|
||||
SDCategory: Ashenvale Forest
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_ruul_snowhoof
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "Player.h"
|
||||
|
||||
/*####
|
||||
# npc_ruul_snowhoof
|
||||
####*/
|
||||
|
||||
enum RuulSnowhoof
|
||||
{
|
||||
NPC_THISTLEFUR_URSA = 3921,
|
||||
NPC_THISTLEFUR_TOTEMIC = 3922,
|
||||
NPC_THISTLEFUR_PATHFINDER = 3926,
|
||||
QUEST_FREEDOM_TO_RUUL = 6482,
|
||||
FACTION_QUEST = 113,
|
||||
GO_CAGE = 178147
|
||||
};
|
||||
|
||||
Position const RuulSnowhoofSummonsCoord[6] =
|
||||
{
|
||||
{ 3449.218018f, -587.825073f, 174.978867f, 4.714445f },
|
||||
{ 3446.384521f, -587.830872f, 175.186279f, 4.714445f },
|
||||
{ 3444.218994f, -587.835327f, 175.380600f, 4.714445f },
|
||||
{ 3508.344482f, -492.024261f, 186.929031f, 4.145029f },
|
||||
{ 3506.265625f, -490.531006f, 186.740128f, 4.239277f },
|
||||
{ 3503.682373f, -489.393799f, 186.629684f, 4.349232f }
|
||||
};
|
||||
|
||||
class npc_ruul_snowhoof : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ruul_snowhoof() : CreatureScript("npc_ruul_snowhoof") { }
|
||||
|
||||
struct npc_ruul_snowhoofAI : public npc_escortAI
|
||||
{
|
||||
npc_ruul_snowhoofAI(Creature* creature) : npc_escortAI(creature) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 20))
|
||||
Cage->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void JustSummoned(Creature* summoned)
|
||||
{
|
||||
summoned->AI()->AttackStart(me);
|
||||
}
|
||||
|
||||
void sQuestAccept(Player* player, Quest const* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_FREEDOM_TO_RUUL)
|
||||
{
|
||||
me->setFaction(FACTION_QUEST);
|
||||
npc_escortAI::Start(true, false, player->GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
Player* player = GetPlayerForEscort();
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
switch (waypointId)
|
||||
{
|
||||
case 0:
|
||||
me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 20))
|
||||
Cage->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case 13:
|
||||
me->SummonCreature(NPC_THISTLEFUR_TOTEMIC, RuulSnowhoofSummonsCoord[0], TEMPSUMMON_DEAD_DESPAWN, 60000);
|
||||
me->SummonCreature(NPC_THISTLEFUR_URSA, RuulSnowhoofSummonsCoord[1], TEMPSUMMON_DEAD_DESPAWN, 60000);
|
||||
me->SummonCreature(NPC_THISTLEFUR_PATHFINDER, RuulSnowhoofSummonsCoord[2], TEMPSUMMON_DEAD_DESPAWN, 60000);
|
||||
break;
|
||||
case 19:
|
||||
me->SummonCreature(NPC_THISTLEFUR_TOTEMIC, RuulSnowhoofSummonsCoord[3], TEMPSUMMON_DEAD_DESPAWN, 60000);
|
||||
me->SummonCreature(NPC_THISTLEFUR_URSA, RuulSnowhoofSummonsCoord[4], TEMPSUMMON_DEAD_DESPAWN, 60000);
|
||||
me->SummonCreature(NPC_THISTLEFUR_PATHFINDER, RuulSnowhoofSummonsCoord[5], TEMPSUMMON_DEAD_DESPAWN, 60000);
|
||||
break;
|
||||
case 21:
|
||||
player->GroupEventHappens(QUEST_FREEDOM_TO_RUUL, me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_ruul_snowhoofAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
enum Muglash
|
||||
{
|
||||
SAY_MUG_START1 = 0,
|
||||
SAY_MUG_START2 = 1,
|
||||
SAY_MUG_BRAZIER = 2,
|
||||
SAY_MUG_BRAZIER_WAIT = 3,
|
||||
SAY_MUG_ON_GUARD = 4,
|
||||
SAY_MUG_REST = 5,
|
||||
SAY_MUG_DONE = 6,
|
||||
SAY_MUG_GRATITUDE = 7,
|
||||
SAY_MUG_PATROL = 8,
|
||||
SAY_MUG_RETURN = 9,
|
||||
|
||||
QUEST_VORSHA = 6641,
|
||||
|
||||
GO_NAGA_BRAZIER = 178247,
|
||||
|
||||
NPC_WRATH_RIDER = 3713,
|
||||
NPC_WRATH_SORCERESS = 3717,
|
||||
NPC_WRATH_RAZORTAIL = 3712,
|
||||
|
||||
NPC_WRATH_PRIESTESS = 3944,
|
||||
NPC_WRATH_MYRMIDON = 3711,
|
||||
NPC_WRATH_SEAWITCH = 3715,
|
||||
|
||||
NPC_VORSHA = 12940,
|
||||
NPC_MUGLASH = 12717
|
||||
};
|
||||
|
||||
Position const FirstNagaCoord[3] =
|
||||
{
|
||||
{ 3603.504150f, 1122.631104f, 1.635f, 0.0f }, // rider
|
||||
{ 3589.293945f, 1148.664063f, 5.565f, 0.0f }, // sorceress
|
||||
{ 3609.925537f, 1168.759521f, -1.168f, 0.0f } // razortail
|
||||
};
|
||||
|
||||
Position const SecondNagaCoord[3] =
|
||||
{
|
||||
{ 3609.925537f, 1168.759521f, -1.168f, 0.0f }, // witch
|
||||
{ 3645.652100f, 1139.425415f, 1.322f, 0.0f }, // priest
|
||||
{ 3583.602051f, 1128.405762f, 2.347f, 0.0f } // myrmidon
|
||||
};
|
||||
|
||||
Position const VorshaCoord = {3633.056885f, 1172.924072f, -5.388f, 0.0f};
|
||||
|
||||
class npc_muglash : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_muglash() : CreatureScript("npc_muglash") { }
|
||||
|
||||
struct npc_muglashAI : public npc_escortAI
|
||||
{
|
||||
npc_muglashAI(Creature* creature) : npc_escortAI(creature) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
eventTimer = 10000;
|
||||
waveId = 0;
|
||||
_isBrazierExtinguished = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
if (HasEscortState(STATE_ESCORT_PAUSED))
|
||||
{
|
||||
if (urand(0, 1))
|
||||
Talk(SAY_MUG_ON_GUARD, player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
player->FailQuest(QUEST_VORSHA);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned)
|
||||
{
|
||||
summoned->AI()->AttackStart(me);
|
||||
}
|
||||
|
||||
void sQuestAccept(Player* player, Quest const* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_VORSHA)
|
||||
{
|
||||
Talk(SAY_MUG_START1);
|
||||
me->setFaction(FACTION_QUEST);
|
||||
npc_escortAI::Start(true, false, player->GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 0:
|
||||
Talk(SAY_MUG_START2, player);
|
||||
break;
|
||||
case 24:
|
||||
Talk(SAY_MUG_BRAZIER, player);
|
||||
|
||||
if (GameObject* go = GetClosestGameObjectWithEntry(me, GO_NAGA_BRAZIER, INTERACTION_DISTANCE*2))
|
||||
{
|
||||
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
SetEscortPaused(true);
|
||||
}
|
||||
break;
|
||||
case 25:
|
||||
Talk(SAY_MUG_GRATITUDE);
|
||||
player->GroupEventHappens(QUEST_VORSHA, me);
|
||||
break;
|
||||
case 26:
|
||||
Talk(SAY_MUG_PATROL);
|
||||
break;
|
||||
case 27:
|
||||
Talk(SAY_MUG_RETURN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoWaveSummon()
|
||||
{
|
||||
switch (waveId)
|
||||
{
|
||||
case 1:
|
||||
me->SummonCreature(NPC_WRATH_RIDER, FirstNagaCoord[0], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
|
||||
me->SummonCreature(NPC_WRATH_SORCERESS, FirstNagaCoord[1], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
|
||||
me->SummonCreature(NPC_WRATH_RAZORTAIL, FirstNagaCoord[2], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
|
||||
break;
|
||||
case 2:
|
||||
me->SummonCreature(NPC_WRATH_PRIESTESS, SecondNagaCoord[0], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
|
||||
me->SummonCreature(NPC_WRATH_MYRMIDON, SecondNagaCoord[1], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
|
||||
me->SummonCreature(NPC_WRATH_SEAWITCH, SecondNagaCoord[2], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
|
||||
break;
|
||||
case 3:
|
||||
me->SummonCreature(NPC_VORSHA, VorshaCoord, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
|
||||
break;
|
||||
case 4:
|
||||
SetEscortPaused(false);
|
||||
Talk(SAY_MUG_DONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
|
||||
if (!me->GetVictim())
|
||||
{
|
||||
if (HasEscortState(STATE_ESCORT_PAUSED) && _isBrazierExtinguished)
|
||||
{
|
||||
if (eventTimer < diff)
|
||||
{
|
||||
++waveId;
|
||||
DoWaveSummon();
|
||||
eventTimer = 10000;
|
||||
}
|
||||
else
|
||||
eventTimer -= diff;
|
||||
}
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 eventTimer;
|
||||
uint8 waveId;
|
||||
public:
|
||||
bool _isBrazierExtinguished;
|
||||
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_muglashAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class go_naga_brazier : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_naga_brazier() : GameObjectScript("go_naga_brazier") { }
|
||||
|
||||
bool OnGossipHello(Player* /*player*/, GameObject* go)
|
||||
{
|
||||
if (Creature* creature = GetClosestCreatureWithEntry(go, NPC_MUGLASH, INTERACTION_DISTANCE*2))
|
||||
{
|
||||
if (npc_muglash::npc_muglashAI* pEscortAI = CAST_AI(npc_muglash::npc_muglashAI, creature->AI()))
|
||||
{
|
||||
creature->AI()->Talk(SAY_MUG_BRAZIER_WAIT);
|
||||
|
||||
pEscortAI->_isBrazierExtinguished = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_ashenvale()
|
||||
{
|
||||
new npc_ruul_snowhoof();
|
||||
new npc_muglash();
|
||||
new go_naga_brazier();
|
||||
}
|
||||
@@ -1,534 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Azshara
|
||||
SD%Complete: 90
|
||||
SDComment: Quest support: 2744, 3141, 9364, 10994
|
||||
SDCategory: Azshara
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_spitelashes
|
||||
npc_loramus_thalipedes
|
||||
npc_rizzle_sprysprocket
|
||||
npc_depth_charge
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "Player.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
/*######
|
||||
## npc_spitelashes
|
||||
######*/
|
||||
|
||||
enum Spitelashes
|
||||
{
|
||||
SPELL_POLYMORPH_RANK1 = 118,
|
||||
SPELL_POLYMORPH_RANK2 = 12824,
|
||||
SPELL_POLYMORPH_RANK3 = 12825,
|
||||
SPELL_POLYMORPH_RANK4 = 12826,
|
||||
SPELL_POLYMORPH = 29124,
|
||||
SPELL_POLYMORPH_BACKFIRE = 28406,
|
||||
SPELL_REMOVE_POLYMORPH = 6924
|
||||
};
|
||||
|
||||
class npc_spitelashes : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_spitelashes() : CreatureScript("npc_spitelashes") { }
|
||||
|
||||
struct npc_spitelashesAI : public ScriptedAI
|
||||
{
|
||||
npc_spitelashesAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 morphtimer;
|
||||
bool spellhit;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
morphtimer = 0;
|
||||
spellhit = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void SpellHit(Unit* unit, const SpellInfo* spell)
|
||||
{
|
||||
if (spellhit)
|
||||
return;
|
||||
|
||||
switch (spell->Id)
|
||||
{
|
||||
case SPELL_POLYMORPH_RANK1:
|
||||
case SPELL_POLYMORPH_RANK2:
|
||||
case SPELL_POLYMORPH_RANK3:
|
||||
case SPELL_POLYMORPH_RANK4:
|
||||
if (Player* player = unit->ToPlayer())
|
||||
if (player->GetQuestStatus(9364) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
spellhit = true;
|
||||
DoCast(me, SPELL_POLYMORPH);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
// we mustn't remove the Creature in the same round in which we cast the summon spell, otherwise there will be no summons
|
||||
if (spellhit && morphtimer >= 5000)
|
||||
{
|
||||
me->DespawnOrUnsummon();
|
||||
return;
|
||||
}
|
||||
// walk 5 seconds before summoning
|
||||
if (spellhit && morphtimer<5000)
|
||||
{
|
||||
morphtimer+=diff;
|
||||
if (morphtimer >= 5000)
|
||||
{
|
||||
DoCast(me, SPELL_POLYMORPH_BACKFIRE); // summon copies
|
||||
DoCast(me, SPELL_REMOVE_POLYMORPH); // visual explosion
|
||||
}
|
||||
}
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
/// @todo add abilities for the different creatures
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_spitelashesAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_loramus_thalipedes
|
||||
######*/
|
||||
|
||||
#define GOSSIP_HELLO_LT1 "Can you help me?"
|
||||
#define GOSSIP_HELLO_LT2 "Tell me your story"
|
||||
#define GOSSIP_SELECT_LT1 "Please continue"
|
||||
#define GOSSIP_SELECT_LT2 "I do not understand"
|
||||
#define GOSSIP_SELECT_LT3 "Indeed"
|
||||
#define GOSSIP_SELECT_LT4 "I will do this with or your help, Loramus"
|
||||
#define GOSSIP_SELECT_LT5 "Yes"
|
||||
|
||||
class npc_loramus_thalipedes : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_loramus_thalipedes() : CreatureScript("npc_loramus_thalipedes") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
switch (action)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF+1:
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
player->AreaExploredOrEventHappens(2744);
|
||||
break;
|
||||
|
||||
case GOSSIP_ACTION_INFO_DEF+2:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 21);
|
||||
player->SEND_GOSSIP_MENU(1813, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+21:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 22);
|
||||
player->SEND_GOSSIP_MENU(1814, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+22:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 23);
|
||||
player->SEND_GOSSIP_MENU(1815, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+23:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 24);
|
||||
player->SEND_GOSSIP_MENU(1816, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+24:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 25);
|
||||
player->SEND_GOSSIP_MENU(1817, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+25:
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
player->AreaExploredOrEventHappens(3141);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (creature->IsQuestGiver())
|
||||
player->PrepareQuestMenu(creature->GetGUID());
|
||||
|
||||
if (player->GetQuestStatus(2744) == QUEST_STATUS_INCOMPLETE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_LT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
|
||||
if (player->GetQuestStatus(3141) == QUEST_STATUS_INCOMPLETE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_LT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
|
||||
|
||||
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/*####
|
||||
# npc_rizzle_sprysprocket
|
||||
####*/
|
||||
|
||||
enum RizzleSprysprocketData
|
||||
{
|
||||
QUEST_CHASING_THE_MOONSTONE = 10994,
|
||||
|
||||
NPC_DEPTH_CHARGE = 23025,
|
||||
|
||||
SPELL_RIZZLE_BLACKJACK = 39865,
|
||||
SPELL_RIZZLE_ESCAPE = 39871,
|
||||
SPELL_RIZZLE_FROST_GRENADE = 40525,
|
||||
SPELL_DEPTH_CHARGE_TRAP = 38576,
|
||||
SPELL_PERIODIC_DEPTH_CHARGE = 39912,
|
||||
SPELL_GIVE_SOUTHFURY_MOONSTONE = 39886,
|
||||
|
||||
SAY_RIZZLE_START = 0,
|
||||
SAY_RIZZLE_GRENADE = 1,
|
||||
SAY_RIZZLE_FINAL = 2,
|
||||
MSG_ESCAPE_NOTICE = 3
|
||||
};
|
||||
|
||||
#define GOSSIP_GET_MOONSTONE "Hand over the Southfury moonstone and I'll let you go."
|
||||
|
||||
Position const WPs[58] =
|
||||
{
|
||||
{3691.97f, -3962.41f, 35.9118f, 3.67f},
|
||||
{3675.02f, -3960.49f, 35.9118f, 3.67f},
|
||||
{3653.19f, -3958.33f, 33.9118f, 3.59f},
|
||||
{3621.12f, -3958.51f, 29.9118f, 3.48f},
|
||||
{3604.86f, -3963, 29.9118f, 3.48f},
|
||||
{3569.94f, -3970.25f, 29.9118f, 3.44f},
|
||||
{3541.03f, -3975.64f, 29.9118f, 3.41f},
|
||||
{3510.84f, -3978.71f, 29.9118f, 3.41f},
|
||||
{3472.7f, -3997.07f, 29.9118f, 3.35f},
|
||||
{3439.15f, -4014.55f, 29.9118f, 3.29f},
|
||||
{3412.8f, -4025.87f, 29.9118f, 3.25f},
|
||||
{3384.95f, -4038.04f, 29.9118f, 3.24f},
|
||||
{3346.77f, -4052.93f, 29.9118f, 3.22f},
|
||||
{3299.56f, -4071.59f, 29.9118f, 3.20f},
|
||||
{3261.22f, -4080.38f, 30.9118f, 3.19f},
|
||||
{3220.68f, -4083.09f, 31.9118f, 3.18f},
|
||||
{3187.11f, -4070.45f, 33.9118f, 3.16f},
|
||||
{3162.78f, -4062.75f, 33.9118f, 3.15f},
|
||||
{3136.09f, -4050.32f, 33.9118f, 3.07f},
|
||||
{3119.47f, -4044.51f, 36.0363f, 3.07f},
|
||||
{3098.95f, -4019.8f, 33.9118f, 3.07f},
|
||||
{3073.07f, -4011.42f, 33.9118f, 3.07f},
|
||||
{3051.71f, -3993.37f, 33.9118f, 3.02f},
|
||||
{3027.52f, -3978.6f, 33.9118f, 3.00f},
|
||||
{3003.78f, -3960.14f, 33.9118f, 2.98f},
|
||||
{2977.99f, -3941.98f, 31.9118f, 2.96f},
|
||||
{2964.57f, -3932.07f, 30.9118f, 2.96f},
|
||||
{2947.9f, -3921.31f, 29.9118f, 2.96f},
|
||||
{2924.91f, -3910.8f, 29.9118f, 2.94f},
|
||||
{2903.04f, -3896.42f, 29.9118f, 2.93f},
|
||||
{2884.75f, -3874.03f, 29.9118f, 2.90f},
|
||||
{2868.19f, -3851.48f, 29.9118f, 2.82f},
|
||||
{2854.62f, -3819.72f, 29.9118f, 2.80f},
|
||||
{2825.53f, -3790.4f, 29.9118f, 2.744f},
|
||||
{2804.31f, -3773.05f, 29.9118f, 2.71f},
|
||||
{2769.78f, -3763.57f, 29.9118f, 2.70f},
|
||||
{2727.23f, -3745.92f, 30.9118f, 2.69f},
|
||||
{2680.12f, -3737.49f, 30.9118f, 2.67f},
|
||||
{2647.62f, -3739.94f, 30.9118f, 2.66f},
|
||||
{2616.6f, -3745.75f, 30.9118f, 2.64f},
|
||||
{2589.38f, -3731.97f, 30.9118f, 2.61f},
|
||||
{2562.94f, -3722.35f, 31.9118f, 2.56f},
|
||||
{2521.05f, -3716.6f, 31.9118f, 2.55f},
|
||||
{2485.26f, -3706.67f, 31.9118f, 2.51f},
|
||||
{2458.93f, -3696.67f, 31.9118f, 2.51f},
|
||||
{2432, -3692.03f, 31.9118f, 2.46f},
|
||||
{2399.59f, -3681.97f, 31.9118f, 2.45f},
|
||||
{2357.75f, -3666.6f, 31.9118f, 2.44f},
|
||||
{2311.99f, -3656.88f, 31.9118f, 2.94f},
|
||||
{2263.41f, -3649.55f, 31.9118f, 3.02f},
|
||||
{2209.05f, -3641.76f, 31.9118f, 2.99f},
|
||||
{2164.83f, -3637.64f, 31.9118f, 3.15f},
|
||||
{2122.42f, -3639, 31.9118f, 3.21f},
|
||||
{2075.73f, -3643.59f, 31.9118f, 3.22f},
|
||||
{2033.59f, -3649.52f, 31.9118f, 3.42f},
|
||||
{1985.22f, -3662.99f, 31.9118f, 3.42f},
|
||||
{1927.09f, -3679.56f, 33.9118f, 3.42f},
|
||||
{1873.57f, -3695.32f, 33.9118f, 3.44f}
|
||||
};
|
||||
|
||||
class npc_rizzle_sprysprocket : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_rizzle_sprysprocket() : CreatureScript("npc_rizzle_sprysprocket") { }
|
||||
|
||||
struct npc_rizzle_sprysprocketAI : public ScriptedAI
|
||||
{
|
||||
npc_rizzle_sprysprocketAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
SpellEscapeTimer = 1300;
|
||||
TeleportTimer = 3500;
|
||||
CheckTimer = 10000;
|
||||
GrenadeTimer = 30000;
|
||||
MustDieTimer = 3000;
|
||||
CurrWP = 0;
|
||||
|
||||
PlayerGUID = 0;
|
||||
|
||||
MustDie = false;
|
||||
Escape = false;
|
||||
ContinueWP = false;
|
||||
Reached = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void AttackStart(Unit* who)
|
||||
{
|
||||
if (!who || PlayerGUID)
|
||||
return;
|
||||
|
||||
Player* player = who->ToPlayer();
|
||||
|
||||
if (player && player->GetQuestStatus(QUEST_CHASING_THE_MOONSTONE) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
PlayerGUID = who->GetGUID();
|
||||
Talk(SAY_RIZZLE_START);
|
||||
DoCast(who, SPELL_RIZZLE_BLACKJACK, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void sGossipSelect(Player* player, uint32 /*sender*/, uint32 /*action*/)
|
||||
{
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
me->CastSpell(player, SPELL_GIVE_SOUTHFURY_MOONSTONE, true);
|
||||
MustDieTimer = 3000;
|
||||
MustDie = true;
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (id == 57)
|
||||
{
|
||||
me->DespawnOrUnsummon();
|
||||
return;
|
||||
}
|
||||
|
||||
++CurrWP;
|
||||
ContinueWP = true;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (MustDie)
|
||||
{
|
||||
if (MustDieTimer <= diff)
|
||||
{
|
||||
me->DespawnOrUnsummon();
|
||||
return;
|
||||
} else MustDieTimer -= diff;
|
||||
}
|
||||
|
||||
if (!Escape)
|
||||
{
|
||||
if (!PlayerGUID)
|
||||
return;
|
||||
|
||||
if (SpellEscapeTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_RIZZLE_ESCAPE, false);
|
||||
SpellEscapeTimer = 10000;
|
||||
} else SpellEscapeTimer -= diff;
|
||||
|
||||
if (TeleportTimer <= diff)
|
||||
{
|
||||
// temp solution - unit can't be teleported by core using spelleffect 5, only players
|
||||
me->NearTeleportTo(3706.39f, -3969.15f, 35.9118f, me->GetOrientation());
|
||||
|
||||
//begin swimming and summon depth charges
|
||||
Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID);
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
Talk(MSG_ESCAPE_NOTICE, player);
|
||||
DoCast(me, SPELL_PERIODIC_DEPTH_CHARGE);
|
||||
me->SetHover(true);
|
||||
me->SetSwim(true);
|
||||
me->SetSpeed(MOVE_RUN, 0.85f, true);
|
||||
me->GetMotionMaster()->MovementExpired();
|
||||
me->GetMotionMaster()->MovePoint(CurrWP, WPs[CurrWP]);
|
||||
Escape = true;
|
||||
} else TeleportTimer -= diff;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (ContinueWP)
|
||||
{
|
||||
me->GetMotionMaster()->MovePoint(CurrWP, WPs[CurrWP]);
|
||||
ContinueWP = false;
|
||||
}
|
||||
|
||||
if (GrenadeTimer <= diff)
|
||||
{
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID))
|
||||
{
|
||||
Talk(SAY_RIZZLE_GRENADE, player);
|
||||
DoCast(player, SPELL_RIZZLE_FROST_GRENADE, true);
|
||||
}
|
||||
GrenadeTimer = 30000;
|
||||
} else GrenadeTimer -= diff;
|
||||
|
||||
if (CheckTimer <= diff)
|
||||
{
|
||||
Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID);
|
||||
if (!player)
|
||||
{
|
||||
me->DespawnOrUnsummon();
|
||||
return;
|
||||
}
|
||||
|
||||
if (me->IsWithinDist(player, 10) && me->GetPositionX() > player->GetPositionX() && !Reached)
|
||||
{
|
||||
Talk(SAY_RIZZLE_FINAL);
|
||||
me->SetUInt32Value(UNIT_NPC_FLAGS, 1);
|
||||
me->setFaction(35);
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->RemoveAurasDueToSpell(SPELL_PERIODIC_DEPTH_CHARGE);
|
||||
Reached = true;
|
||||
}
|
||||
|
||||
CheckTimer = 1000;
|
||||
} else CheckTimer -= diff;
|
||||
}
|
||||
|
||||
private:
|
||||
uint64 PlayerGUID;
|
||||
uint32 SpellEscapeTimer;
|
||||
uint32 TeleportTimer;
|
||||
uint32 CheckTimer;
|
||||
uint32 GrenadeTimer;
|
||||
uint32 MustDieTimer;
|
||||
uint32 CurrWP;
|
||||
bool MustDie;
|
||||
bool Escape;
|
||||
bool ContinueWP;
|
||||
bool Reached;
|
||||
};
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (player->GetQuestStatus(QUEST_CHASING_THE_MOONSTONE) != QUEST_STATUS_INCOMPLETE)
|
||||
return true;
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_GET_MOONSTONE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
player->SEND_GOSSIP_MENU(10811, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_rizzle_sprysprocketAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
/*####
|
||||
# npc_depth_charge
|
||||
####*/
|
||||
class npc_depth_charge : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_depth_charge() : CreatureScript("npc_depth_charge") { }
|
||||
|
||||
struct npc_depth_chargeAI : public ScriptedAI
|
||||
{
|
||||
npc_depth_chargeAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
bool WeMustDie;
|
||||
uint32 WeMustDieTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->SetHover(true);
|
||||
me->SetSwim(true);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
WeMustDie = false;
|
||||
WeMustDieTimer = 1000;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void AttackStart(Unit* /*who*/) { }
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (!who)
|
||||
return;
|
||||
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 5))
|
||||
{
|
||||
DoCast(who, SPELL_DEPTH_CHARGE_TRAP);
|
||||
WeMustDie = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (WeMustDie)
|
||||
{
|
||||
if (WeMustDieTimer <= diff)
|
||||
me->DespawnOrUnsummon();
|
||||
else
|
||||
WeMustDieTimer -= diff;
|
||||
}
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_depth_chargeAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_azshara()
|
||||
{
|
||||
new npc_spitelashes();
|
||||
new npc_loramus_thalipedes();
|
||||
new npc_rizzle_sprysprocket();
|
||||
new npc_depth_charge();
|
||||
}
|
||||
@@ -1,748 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Azuremyst_Isle
|
||||
SD%Complete: 75
|
||||
SDComment: Quest support: 9283, 9537, 9582, 9554, 9531, ? (special flight path, proper model for mount missing). Injured Draenei cosmetic only, 9582.
|
||||
SDCategory: Azuremyst Isle
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_draenei_survivor
|
||||
npc_engineer_spark_overgrind
|
||||
npc_injured_draenei
|
||||
npc_magwin
|
||||
npc_geezle
|
||||
go_ravager_cage
|
||||
npc_death_ravager
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "Cell.h"
|
||||
#include "CellImpl.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "GridNotifiers.h"
|
||||
|
||||
/*######
|
||||
## npc_draenei_survivor
|
||||
######*/
|
||||
|
||||
enum draeneiSurvivor
|
||||
{
|
||||
SAY_HEAL = 0,
|
||||
SAY_HELP = 1,
|
||||
SPELL_IRRIDATION = 35046,
|
||||
SPELL_STUNNED = 28630
|
||||
};
|
||||
|
||||
class npc_draenei_survivor : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_draenei_survivor() : CreatureScript("npc_draenei_survivor") { }
|
||||
|
||||
struct npc_draenei_survivorAI : public ScriptedAI
|
||||
{
|
||||
npc_draenei_survivorAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint64 pCaster;
|
||||
|
||||
uint32 SayThanksTimer;
|
||||
uint32 RunAwayTimer;
|
||||
uint32 SayHelpTimer;
|
||||
|
||||
bool CanSayHelp;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
pCaster = 0;
|
||||
|
||||
SayThanksTimer = 0;
|
||||
RunAwayTimer = 0;
|
||||
SayHelpTimer = 10000;
|
||||
|
||||
CanSayHelp = true;
|
||||
|
||||
DoCast(me, SPELL_IRRIDATION, true);
|
||||
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
|
||||
me->SetHealth(me->CountPctFromMaxHealth(10));
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (CanSayHelp && who->GetTypeId() == TYPEID_PLAYER && me->IsFriendlyTo(who) && me->IsWithinDistInMap(who, 25.0f))
|
||||
{
|
||||
//Random switch between 4 texts
|
||||
Talk(SAY_HELP, who);
|
||||
|
||||
SayHelpTimer = 20000;
|
||||
CanSayHelp = false;
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHit(Unit* Caster, const SpellInfo* Spell)
|
||||
{
|
||||
if (Spell->SpellFamilyFlags[2] & 0x080000000)
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
|
||||
DoCast(me, SPELL_STUNNED, true);
|
||||
|
||||
pCaster = Caster->GetGUID();
|
||||
|
||||
SayThanksTimer = 5000;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (SayThanksTimer)
|
||||
{
|
||||
if (SayThanksTimer <= diff)
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_IRRIDATION);
|
||||
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*me, pCaster))
|
||||
{
|
||||
Talk(SAY_HEAL, player);
|
||||
|
||||
player->TalkedToCreature(me->GetEntry(), me->GetGUID());
|
||||
}
|
||||
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->GetMotionMaster()->MovePoint(0, -4115.053711f, -13754.831055f, 73.508949f);
|
||||
|
||||
RunAwayTimer = 10000;
|
||||
SayThanksTimer = 0;
|
||||
} else SayThanksTimer -= diff;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (RunAwayTimer)
|
||||
{
|
||||
if (RunAwayTimer <= diff)
|
||||
me->DespawnOrUnsummon();
|
||||
else
|
||||
RunAwayTimer -= diff;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (SayHelpTimer <= diff)
|
||||
{
|
||||
CanSayHelp = true;
|
||||
SayHelpTimer = 20000;
|
||||
} else SayHelpTimer -= diff;
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_draenei_survivorAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_engineer_spark_overgrind
|
||||
######*/
|
||||
|
||||
enum Overgrind
|
||||
{
|
||||
SAY_TEXT = 0,
|
||||
SAY_EMOTE = 1,
|
||||
ATTACK_YELL = 2,
|
||||
|
||||
AREA_COVE = 3579,
|
||||
AREA_ISLE = 3639,
|
||||
QUEST_GNOMERCY = 9537,
|
||||
FACTION_HOSTILE = 14,
|
||||
SPELL_DYNAMITE = 7978
|
||||
};
|
||||
|
||||
class npc_engineer_spark_overgrind : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_engineer_spark_overgrind() : CreatureScript("npc_engineer_spark_overgrind") { }
|
||||
|
||||
struct npc_engineer_spark_overgrindAI : public ScriptedAI
|
||||
{
|
||||
npc_engineer_spark_overgrindAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
NormFaction = creature->getFaction();
|
||||
NpcFlags = creature->GetUInt32Value(UNIT_NPC_FLAGS);
|
||||
|
||||
if (creature->GetAreaId() == AREA_COVE || creature->GetAreaId() == AREA_ISLE)
|
||||
IsTreeEvent = true;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
DynamiteTimer = 8000;
|
||||
EmoteTimer = urand(120000, 150000);
|
||||
|
||||
me->setFaction(NormFaction);
|
||||
me->SetUInt32Value(UNIT_NPC_FLAGS, NpcFlags);
|
||||
|
||||
IsTreeEvent = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
Talk(ATTACK_YELL, who);
|
||||
}
|
||||
|
||||
void sGossipSelect(Player* player, uint32 /*sender*/, uint32 /*action*/)
|
||||
{
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
me->setFaction(FACTION_HOSTILE);
|
||||
me->Attack(player, true);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!me->IsInCombat() && !IsTreeEvent)
|
||||
{
|
||||
if (EmoteTimer <= diff)
|
||||
{
|
||||
Talk(SAY_TEXT);
|
||||
Talk(SAY_EMOTE);
|
||||
EmoteTimer = urand(120000, 150000);
|
||||
} else EmoteTimer -= diff;
|
||||
}
|
||||
else if (IsTreeEvent)
|
||||
return;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (DynamiteTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_DYNAMITE);
|
||||
DynamiteTimer = 8000;
|
||||
} else DynamiteTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 NormFaction;
|
||||
uint32 NpcFlags;
|
||||
uint32 DynamiteTimer;
|
||||
uint32 EmoteTimer;
|
||||
bool IsTreeEvent;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_engineer_spark_overgrindAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_injured_draenei
|
||||
######*/
|
||||
|
||||
class npc_injured_draenei : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_injured_draenei() : CreatureScript("npc_injured_draenei") { }
|
||||
|
||||
struct npc_injured_draeneiAI : public ScriptedAI
|
||||
{
|
||||
npc_injured_draeneiAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
|
||||
me->SetHealth(me->CountPctFromMaxHealth(15));
|
||||
switch (urand(0, 1))
|
||||
{
|
||||
case 0:
|
||||
me->SetStandState(UNIT_STAND_STATE_SIT);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) { }
|
||||
|
||||
void UpdateAI(uint32 /*diff*/) { }
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_injured_draeneiAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_magwin
|
||||
######*/
|
||||
|
||||
enum Magwin
|
||||
{
|
||||
SAY_START = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_PROGRESS = 2,
|
||||
SAY_END1 = 3,
|
||||
SAY_END2 = 4,
|
||||
EMOTE_HUG = 5,
|
||||
QUEST_A_CRY_FOR_SAY_HELP = 9528,
|
||||
FACTION_QUEST = 113
|
||||
};
|
||||
|
||||
class npc_magwin : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_magwin() : CreatureScript("npc_magwin") { }
|
||||
|
||||
struct npc_magwinAI : public npc_escortAI
|
||||
{
|
||||
npc_magwinAI(Creature* creature) : npc_escortAI(creature) { }
|
||||
|
||||
void Reset() { }
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
Talk(SAY_AGGRO, who);
|
||||
}
|
||||
|
||||
void sQuestAccept(Player* player, Quest const* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_A_CRY_FOR_SAY_HELP)
|
||||
{
|
||||
me->setFaction(FACTION_QUEST);
|
||||
npc_escortAI::Start(true, false, player->GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 0:
|
||||
Talk(SAY_START, player);
|
||||
break;
|
||||
case 17:
|
||||
Talk(SAY_PROGRESS, player);
|
||||
break;
|
||||
case 28:
|
||||
Talk(SAY_END1, player);
|
||||
break;
|
||||
case 29:
|
||||
Talk(EMOTE_HUG, player);
|
||||
Talk(SAY_END2, player);
|
||||
player->GroupEventHappens(QUEST_A_CRY_FOR_SAY_HELP, me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_magwinAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_geezle
|
||||
######*/
|
||||
|
||||
enum Geezle
|
||||
{
|
||||
QUEST_TREES_COMPANY = 9531,
|
||||
|
||||
SPELL_TREE_DISGUISE = 30298,
|
||||
|
||||
GEEZLE_SAY_1 = 0,
|
||||
SPARK_SAY_2 = 3,
|
||||
SPARK_SAY_3 = 4,
|
||||
GEEZLE_SAY_4 = 1,
|
||||
SPARK_SAY_5 = 5,
|
||||
SPARK_SAY_6 = 6,
|
||||
GEEZLE_SAY_7 = 2,
|
||||
|
||||
EMOTE_SPARK = 7,
|
||||
|
||||
NPC_SPARK = 17243,
|
||||
GO_NAGA_FLAG = 181694
|
||||
};
|
||||
|
||||
Position const SparkPos = {-5029.91f, -11291.79f, 8.096f, 0.0f};
|
||||
|
||||
class npc_geezle : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_geezle() : CreatureScript("npc_geezle") { }
|
||||
|
||||
struct npc_geezleAI : public ScriptedAI
|
||||
{
|
||||
npc_geezleAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint64 SparkGUID;
|
||||
|
||||
uint8 Step;
|
||||
uint32 SayTimer;
|
||||
|
||||
bool EventStarted;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
SparkGUID = 0;
|
||||
Step = 0;
|
||||
StartEvent();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void StartEvent()
|
||||
{
|
||||
Step = 0;
|
||||
EventStarted = true;
|
||||
if (Creature* Spark = me->SummonCreature(NPC_SPARK, SparkPos, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 150000))
|
||||
{
|
||||
SparkGUID = Spark->GetGUID();
|
||||
Spark->setActive(true);
|
||||
Spark->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
}
|
||||
SayTimer = 8000;
|
||||
}
|
||||
|
||||
uint32 NextStep(uint8 Step)
|
||||
{
|
||||
Creature* Spark = ObjectAccessor::GetCreature(*me, SparkGUID);
|
||||
if (!Spark)
|
||||
{
|
||||
me->DespawnOrUnsummon(1);
|
||||
return 5000;
|
||||
}
|
||||
|
||||
switch (Step)
|
||||
{
|
||||
case 0:
|
||||
Spark->GetMotionMaster()->MovePoint(0, -5080.70f, -11253.61f, 0.56f);
|
||||
me->GetMotionMaster()->MovePoint(0, -5092.26f, -11252, 0.71f);
|
||||
return 9000;
|
||||
case 1:
|
||||
DespawnNagaFlag(true);
|
||||
Spark->AI()->Talk(EMOTE_SPARK);
|
||||
return 1000;
|
||||
case 2:
|
||||
Talk(GEEZLE_SAY_1, Spark);
|
||||
Spark->SetInFront(me);
|
||||
me->SetInFront(Spark);
|
||||
return 5000;
|
||||
case 3:
|
||||
Spark->AI()->Talk(SPARK_SAY_2);
|
||||
return 7000;
|
||||
case 4:
|
||||
Spark->AI()->Talk(SPARK_SAY_3);
|
||||
return 8000;
|
||||
case 5:
|
||||
Talk(GEEZLE_SAY_4, Spark);
|
||||
return 8000;
|
||||
case 6:
|
||||
Spark->AI()->Talk(SPARK_SAY_5);
|
||||
return 9000;
|
||||
case 7:
|
||||
Spark->AI()->Talk(SPARK_SAY_6);
|
||||
return 8000;
|
||||
case 8:
|
||||
Talk(GEEZLE_SAY_7, Spark);
|
||||
return 2000;
|
||||
case 9:
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
Spark->GetMotionMaster()->MovePoint(0, SparkPos);
|
||||
CompleteQuest();
|
||||
return 9000;
|
||||
case 10:
|
||||
Spark->DespawnOrUnsummon(1);
|
||||
DespawnNagaFlag(false);
|
||||
me->DespawnOrUnsummon(1);
|
||||
return 5000;
|
||||
default: return 99999999;
|
||||
}
|
||||
}
|
||||
|
||||
// will complete Tree's company quest for all nearby players that are disguised as trees
|
||||
void CompleteQuest()
|
||||
{
|
||||
float radius = 50.0f;
|
||||
std::list<Player*> players;
|
||||
Trinity::AnyPlayerInObjectRangeCheck checker(me, radius);
|
||||
Trinity::PlayerListSearcher<Trinity::AnyPlayerInObjectRangeCheck> searcher(me, players, checker);
|
||||
me->VisitNearbyWorldObject(radius, searcher);
|
||||
|
||||
for (std::list<Player*>::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
if ((*itr)->GetQuestStatus(QUEST_TREES_COMPANY) == QUEST_STATUS_INCOMPLETE && (*itr)->HasAura(SPELL_TREE_DISGUISE))
|
||||
(*itr)->KilledMonsterCredit(NPC_SPARK, 0);
|
||||
}
|
||||
|
||||
void DespawnNagaFlag(bool despawn)
|
||||
{
|
||||
std::list<GameObject*> FlagList;
|
||||
me->GetGameObjectListWithEntryInGrid(FlagList, GO_NAGA_FLAG, 100.0f);
|
||||
|
||||
if (!FlagList.empty())
|
||||
{
|
||||
for (std::list<GameObject*>::const_iterator itr = FlagList.begin(); itr != FlagList.end(); ++itr)
|
||||
{
|
||||
if (despawn)
|
||||
(*itr)->SetLootState(GO_JUST_DEACTIVATED);
|
||||
else
|
||||
(*itr)->Respawn();
|
||||
}
|
||||
}
|
||||
//else
|
||||
// TC_LOG_ERROR("scripts", "SD2 ERROR: FlagList is empty!");
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (SayTimer <= diff)
|
||||
{
|
||||
if (EventStarted)
|
||||
SayTimer = NextStep(Step++);
|
||||
}
|
||||
else
|
||||
SayTimer -= diff;
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_geezleAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
enum RavegerCage
|
||||
{
|
||||
NPC_DEATH_RAVAGER = 17556,
|
||||
|
||||
SPELL_REND = 13443,
|
||||
SPELL_ENRAGING_BITE = 30736,
|
||||
|
||||
QUEST_STRENGTH_ONE = 9582
|
||||
};
|
||||
|
||||
class go_ravager_cage : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_ravager_cage() : GameObjectScript("go_ravager_cage") { }
|
||||
|
||||
bool OnGossipHello(Player* player, GameObject* go)
|
||||
{
|
||||
go->UseDoorOrButton();
|
||||
if (player->GetQuestStatus(QUEST_STRENGTH_ONE) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
if (Creature* ravager = go->FindNearestCreature(NPC_DEATH_RAVAGER, 5.0f, true))
|
||||
{
|
||||
ravager->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
ravager->SetReactState(REACT_AGGRESSIVE);
|
||||
ravager->AI()->AttackStart(player);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class npc_death_ravager : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_death_ravager() : CreatureScript("npc_death_ravager") { }
|
||||
|
||||
struct npc_death_ravagerAI : public ScriptedAI
|
||||
{
|
||||
npc_death_ravagerAI(Creature* creature) : ScriptedAI(creature){ }
|
||||
|
||||
uint32 RendTimer;
|
||||
uint32 EnragingBiteTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
RendTimer = 30000;
|
||||
EnragingBiteTimer = 20000;
|
||||
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (RendTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_REND);
|
||||
RendTimer = 30000;
|
||||
}
|
||||
else RendTimer -= diff;
|
||||
|
||||
if (EnragingBiteTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_ENRAGING_BITE);
|
||||
EnragingBiteTimer = 15000;
|
||||
}
|
||||
else EnragingBiteTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_death_ravagerAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
/*########
|
||||
## Quest: The Prophecy of Akida
|
||||
########*/
|
||||
|
||||
enum BristlelimbCage
|
||||
{
|
||||
QUEST_THE_PROPHECY_OF_AKIDA = 9544,
|
||||
NPC_STILLPINE_CAPITIVE = 17375,
|
||||
GO_BRISTELIMB_CAGE = 181714,
|
||||
|
||||
CAPITIVE_SAY = 0,
|
||||
|
||||
POINT_INIT = 1,
|
||||
EVENT_DESPAWN = 1,
|
||||
};
|
||||
|
||||
class npc_stillpine_capitive : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_stillpine_capitive() : CreatureScript("npc_stillpine_capitive") { }
|
||||
|
||||
struct npc_stillpine_capitiveAI : public ScriptedAI
|
||||
{
|
||||
npc_stillpine_capitiveAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (GameObject* cage = me->FindNearestGameObject(GO_BRISTELIMB_CAGE, 5.0f))
|
||||
{
|
||||
cage->SetLootState(GO_JUST_DEACTIVATED);
|
||||
cage->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
_events.Reset();
|
||||
_playerGUID = 0;
|
||||
_movementComplete = false;
|
||||
}
|
||||
|
||||
void StartMoving(Player* owner)
|
||||
{
|
||||
if (owner)
|
||||
{
|
||||
Talk(CAPITIVE_SAY, owner);
|
||||
_playerGUID = owner->GetGUID();
|
||||
}
|
||||
Position pos;
|
||||
me->GetNearPosition(pos, 3.0f, 0.0f);
|
||||
me->GetMotionMaster()->MovePoint(POINT_INIT, pos);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE || id != POINT_INIT)
|
||||
return;
|
||||
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID))
|
||||
player->KilledMonsterCredit(me->GetEntry(), me->GetGUID());
|
||||
|
||||
_movementComplete = true;
|
||||
_events.ScheduleEvent(EVENT_DESPAWN, 3500);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!_movementComplete)
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
if (_events.ExecuteEvent() == EVENT_DESPAWN)
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
private:
|
||||
uint64 _playerGUID;
|
||||
EventMap _events;
|
||||
bool _movementComplete;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_stillpine_capitiveAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class go_bristlelimb_cage : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_bristlelimb_cage() : GameObjectScript("go_bristlelimb_cage") { }
|
||||
|
||||
bool OnGossipHello(Player* player, GameObject* go)
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
if (player->GetQuestStatus(QUEST_THE_PROPHECY_OF_AKIDA) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
if (Creature* capitive = go->FindNearestCreature(NPC_STILLPINE_CAPITIVE, 5.0f, true))
|
||||
{
|
||||
go->ResetDoorOrButton();
|
||||
CAST_AI(npc_stillpine_capitive::npc_stillpine_capitiveAI, capitive->AI())->StartMoving(player);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_azuremyst_isle()
|
||||
{
|
||||
new npc_draenei_survivor();
|
||||
new npc_engineer_spark_overgrind();
|
||||
new npc_injured_draenei();
|
||||
new npc_magwin();
|
||||
new npc_geezle();
|
||||
new npc_death_ravager();
|
||||
new go_ravager_cage();
|
||||
new npc_stillpine_capitive();
|
||||
new go_bristlelimb_cage();
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Bloodmyst_Isle
|
||||
SD%Complete: 80
|
||||
SDComment: Quest support: 9670
|
||||
SDCategory: Bloodmyst Isle
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_webbed_creature
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "Player.h"
|
||||
|
||||
/*######
|
||||
## npc_webbed_creature
|
||||
######*/
|
||||
|
||||
//possible creatures to be spawned
|
||||
uint32 const possibleSpawns[32] = {17322, 17661, 17496, 17522, 17340, 17352, 17333, 17524, 17654, 17348, 17339, 17345, 17359, 17353, 17336, 17550, 17330, 17701, 17321, 17680, 17325, 17320, 17683, 17342, 17715, 17334, 17341, 17338, 17337, 17346, 17344, 17327};
|
||||
|
||||
enum WebbedCreature
|
||||
{
|
||||
NPC_EXPEDITION_RESEARCHER = 17681
|
||||
};
|
||||
|
||||
class npc_webbed_creature : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_webbed_creature() : CreatureScript("npc_webbed_creature") { }
|
||||
|
||||
struct npc_webbed_creatureAI : public ScriptedAI
|
||||
{
|
||||
npc_webbed_creatureAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void Reset() { }
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
uint32 spawnCreatureID = 0;
|
||||
|
||||
switch (urand(0, 2))
|
||||
{
|
||||
case 0:
|
||||
if (Player* player = killer->ToPlayer())
|
||||
player->KilledMonsterCredit(NPC_EXPEDITION_RESEARCHER, 0);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
spawnCreatureID = possibleSpawns[urand(0, 30)];
|
||||
break;
|
||||
}
|
||||
|
||||
if (spawnCreatureID)
|
||||
me->SummonCreature(spawnCreatureID, 0.0f, 0.0f, 0.0f, me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_webbed_creatureAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_bloodmyst_isle()
|
||||
{
|
||||
new npc_webbed_creature();
|
||||
}
|
||||
@@ -1,523 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Darkshore
|
||||
SD%Complete: 100
|
||||
SDComment: Quest support: 731, 2078, 5321
|
||||
SDCategory: Darkshore
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_kerlonian
|
||||
npc_prospector_remtravel
|
||||
npc_threshwackonator
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "ScriptedFollowerAI.h"
|
||||
#include "Player.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
// Ours
|
||||
enum murkdeep
|
||||
{
|
||||
NPC_GREYMIST_HUNTER = 2206,
|
||||
NPC_GREYMIST_WARRIOR = 2205,
|
||||
NPC_GREYMIST_COASTRUNNER = 2202,
|
||||
|
||||
SPELL_SUNDER_ARMOR = 11971,
|
||||
SPELL_NET = 6533,
|
||||
|
||||
EVENT_SPELL_SUNDER_ARMOR = 2,
|
||||
EVENT_SPELL_NET = 3,
|
||||
};
|
||||
|
||||
class npc_murkdeep : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_murkdeep() : CreatureScript("npc_murkdeep") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_murkdeepAI(creature);
|
||||
}
|
||||
|
||||
struct npc_murkdeepAI : public ScriptedAI
|
||||
{
|
||||
npc_murkdeepAI(Creature* c) : ScriptedAI(c) {}
|
||||
|
||||
uint8 phase;
|
||||
uint32 spawnTimer;
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
spawnTimer = 0;
|
||||
phase = 0;
|
||||
me->SetVisible(false);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit*)
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_SPELL_SUNDER_ARMOR, 5000);
|
||||
events.ScheduleEvent(EVENT_SPELL_NET, 10000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
spawnTimer += diff;
|
||||
if (spawnTimer >= 5000)
|
||||
{
|
||||
spawnTimer = 0;
|
||||
switch (phase)
|
||||
{
|
||||
case 0:
|
||||
if (!me->FindNearestCreature(NPC_GREYMIST_WARRIOR, 80.0f, true) && !me->FindNearestCreature(NPC_GREYMIST_HUNTER, 80.0f, true))
|
||||
{
|
||||
Player *player = me->SelectNearestPlayer(100.0f);
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
phase++;
|
||||
for (int i = 0; i < 3; ++i)
|
||||
if (Creature* cr = me->SummonCreature(NPC_GREYMIST_COASTRUNNER, me->GetPositionX()+irand(-5, 5), me->GetPositionY()+irand(-5, 5), me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
|
||||
cr->AI()->AttackStart(player);
|
||||
}
|
||||
return;
|
||||
case 1:
|
||||
if (!me->FindNearestCreature(NPC_GREYMIST_COASTRUNNER, 80.0f))
|
||||
{
|
||||
Player *player = me->SelectNearestPlayer(100.0f);
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
phase++;
|
||||
for (int i = 0; i < 2; ++i)
|
||||
if (Creature* cr = me->SummonCreature(NPC_GREYMIST_WARRIOR, me->GetPositionX()+irand(-5, 5), me->GetPositionY()+irand(-5, 5), me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
|
||||
cr->AI()->AttackStart(player);
|
||||
}
|
||||
return;
|
||||
case 2:
|
||||
if (!me->FindNearestCreature(NPC_GREYMIST_WARRIOR, 80.0f))
|
||||
{
|
||||
Player *player = me->SelectNearestPlayer(100.0f);
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
phase++;
|
||||
if (Creature* cr = me->SummonCreature(NPC_GREYMIST_HUNTER, me->GetPositionX()+irand(-5, 5), me->GetPositionY()+irand(-5, 5), me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
|
||||
cr->AI()->AttackStart(player);
|
||||
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetVisible(true);
|
||||
AttackStart(player);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!me->IsVisible())
|
||||
return;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_SUNDER_ARMOR:
|
||||
me->CastSpell(me->GetVictim(), SPELL_SUNDER_ARMOR, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_SUNDER_ARMOR, 15000);
|
||||
break;
|
||||
case EVENT_SPELL_NET:
|
||||
me->CastSpell(me->GetVictim(), SPELL_NET, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_NET, 25000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Theirs
|
||||
/*####
|
||||
# npc_kerlonian
|
||||
####*/
|
||||
|
||||
enum Kerlonian
|
||||
{
|
||||
SAY_KER_START = 0,
|
||||
EMOTE_KER_SLEEP = 1,
|
||||
SAY_KER_SLEEP = 2,
|
||||
SAY_KER_ALERT_1 = 3,
|
||||
SAY_KER_END = 4,
|
||||
EMOTE_KER_AWAKEN = 5,
|
||||
|
||||
SPELL_SLEEP_VISUAL = 25148,
|
||||
SPELL_AWAKEN = 17536,
|
||||
QUEST_SLEEPER_AWAKENED = 5321,
|
||||
NPC_LILADRIS = 11219, //attackers entries unknown
|
||||
FACTION_KER_ESCORTEE = 113
|
||||
};
|
||||
|
||||
/// @todo make concept similar as "ringo" -escort. Find a way to run the scripted attacks, _if_ player are choosing road.
|
||||
class npc_kerlonian : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_kerlonian() : CreatureScript("npc_kerlonian") { }
|
||||
|
||||
struct npc_kerlonianAI : public FollowerAI
|
||||
{
|
||||
npc_kerlonianAI(Creature* creature) : FollowerAI(creature) { }
|
||||
|
||||
uint32 FallAsleepTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
FallAsleepTimer = urand(10000, 45000);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
|
||||
{
|
||||
FollowerAI::MoveInLineOfSight(who);
|
||||
|
||||
if (!me->GetVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_LILADRIS)
|
||||
{
|
||||
if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE*5))
|
||||
{
|
||||
if (Player* player = GetLeaderForFollower())
|
||||
{
|
||||
if (player->GetQuestStatus(QUEST_SLEEPER_AWAKENED) == QUEST_STATUS_INCOMPLETE)
|
||||
player->GroupEventHappens(QUEST_SLEEPER_AWAKENED, me);
|
||||
|
||||
Talk(SAY_KER_END);
|
||||
}
|
||||
|
||||
SetFollowComplete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell)
|
||||
{
|
||||
if (HasFollowState(STATE_FOLLOW_INPROGRESS | STATE_FOLLOW_PAUSED) && pSpell->Id == SPELL_AWAKEN)
|
||||
ClearSleeping();
|
||||
}
|
||||
|
||||
void SetSleeping()
|
||||
{
|
||||
SetFollowPaused(true);
|
||||
|
||||
Talk(EMOTE_KER_SLEEP);
|
||||
|
||||
Talk(SAY_KER_SLEEP);
|
||||
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
DoCast(me, SPELL_SLEEP_VISUAL, false);
|
||||
}
|
||||
|
||||
void ClearSleeping()
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_SLEEP_VISUAL);
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
|
||||
Talk(EMOTE_KER_AWAKEN);
|
||||
|
||||
SetFollowPaused(false);
|
||||
}
|
||||
|
||||
void UpdateFollowerAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
if (!HasFollowState(STATE_FOLLOW_INPROGRESS))
|
||||
return;
|
||||
|
||||
if (!HasFollowState(STATE_FOLLOW_PAUSED))
|
||||
{
|
||||
if (FallAsleepTimer <= diff)
|
||||
{
|
||||
SetSleeping();
|
||||
FallAsleepTimer = urand(25000, 90000);
|
||||
}
|
||||
else
|
||||
FallAsleepTimer -= diff;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_SLEEPER_AWAKENED)
|
||||
{
|
||||
if (npc_kerlonianAI* pKerlonianAI = CAST_AI(npc_kerlonian::npc_kerlonianAI, creature->AI()))
|
||||
{
|
||||
creature->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
creature->AI()->Talk(SAY_KER_START, player);
|
||||
pKerlonianAI->StartFollow(player, FACTION_KER_ESCORTEE, quest);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_kerlonianAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
/*####
|
||||
# npc_prospector_remtravel
|
||||
####*/
|
||||
|
||||
enum Remtravel
|
||||
{
|
||||
SAY_REM_START = 0,
|
||||
SAY_REM_AGGRO = 1,
|
||||
SAY_REM_RAMP1_1 = 2,
|
||||
SAY_REM_RAMP1_2 = 3,
|
||||
SAY_REM_BOOK = 4,
|
||||
SAY_REM_TENT1_1 = 5,
|
||||
SAY_REM_TENT1_2 = 6,
|
||||
SAY_REM_MOSS = 7,
|
||||
EMOTE_REM_MOSS = 8,
|
||||
SAY_REM_MOSS_PROGRESS = 9,
|
||||
SAY_REM_PROGRESS = 10,
|
||||
SAY_REM_REMEMBER = 11,
|
||||
EMOTE_REM_END = 12,
|
||||
|
||||
FACTION_ESCORTEE = 10,
|
||||
QUEST_ABSENT_MINDED_PT2 = 731,
|
||||
NPC_GRAVEL_SCOUT = 2158,
|
||||
NPC_GRAVEL_BONE = 2159,
|
||||
NPC_GRAVEL_GEO = 2160
|
||||
};
|
||||
|
||||
class npc_prospector_remtravel : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_prospector_remtravel() : CreatureScript("npc_prospector_remtravel") { }
|
||||
|
||||
struct npc_prospector_remtravelAI : public npc_escortAI
|
||||
{
|
||||
npc_prospector_remtravelAI(Creature* creature) : npc_escortAI(creature) { }
|
||||
|
||||
void Reset() { }
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
if (urand(0, 1))
|
||||
Talk(SAY_REM_AGGRO, who);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* /*pSummoned*/)
|
||||
{
|
||||
//unsure if it should be any
|
||||
//pSummoned->AI()->AttackStart(me);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 0:
|
||||
Talk(SAY_REM_START, player);
|
||||
break;
|
||||
case 5:
|
||||
Talk(SAY_REM_RAMP1_1, player);
|
||||
break;
|
||||
case 6:
|
||||
DoSpawnCreature(NPC_GRAVEL_SCOUT, -10.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||
DoSpawnCreature(NPC_GRAVEL_BONE, -10.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||
break;
|
||||
case 9:
|
||||
Talk(SAY_REM_RAMP1_2, player);
|
||||
break;
|
||||
case 14:
|
||||
//depend quest rewarded?
|
||||
Talk(SAY_REM_BOOK, player);
|
||||
break;
|
||||
case 15:
|
||||
Talk(SAY_REM_TENT1_1, player);
|
||||
break;
|
||||
case 16:
|
||||
DoSpawnCreature(NPC_GRAVEL_SCOUT, -10.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||
DoSpawnCreature(NPC_GRAVEL_BONE, -10.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||
break;
|
||||
case 17:
|
||||
Talk(SAY_REM_TENT1_2, player);
|
||||
break;
|
||||
case 26:
|
||||
Talk(SAY_REM_MOSS, player);
|
||||
break;
|
||||
case 27:
|
||||
Talk(EMOTE_REM_MOSS, player);
|
||||
break;
|
||||
case 28:
|
||||
Talk(SAY_REM_MOSS_PROGRESS, player);
|
||||
break;
|
||||
case 29:
|
||||
DoSpawnCreature(NPC_GRAVEL_SCOUT, -15.0f, 3.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||
DoSpawnCreature(NPC_GRAVEL_BONE, -15.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||
DoSpawnCreature(NPC_GRAVEL_GEO, -15.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||
break;
|
||||
case 31:
|
||||
Talk(SAY_REM_PROGRESS, player);
|
||||
break;
|
||||
case 41:
|
||||
Talk(SAY_REM_REMEMBER, player);
|
||||
break;
|
||||
case 42:
|
||||
Talk(EMOTE_REM_END, player);
|
||||
player->GroupEventHappens(QUEST_ABSENT_MINDED_PT2, me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_ABSENT_MINDED_PT2)
|
||||
{
|
||||
if (npc_escortAI* pEscortAI = CAST_AI(npc_prospector_remtravel::npc_prospector_remtravelAI, creature->AI()))
|
||||
pEscortAI->Start(false, false, player->GetGUID());
|
||||
|
||||
creature->setFaction(FACTION_ESCORTEE);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_prospector_remtravelAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
/*####
|
||||
# npc_threshwackonator
|
||||
####*/
|
||||
|
||||
enum Threshwackonator
|
||||
{
|
||||
EMOTE_START = 0,
|
||||
SAY_AT_CLOSE = 1,
|
||||
QUEST_GYROMAST_REV = 2078,
|
||||
NPC_GELKAK = 6667,
|
||||
FACTION_HOSTILE = 14
|
||||
};
|
||||
|
||||
#define GOSSIP_ITEM_INSERT_KEY "[PH] Insert key"
|
||||
|
||||
class npc_threshwackonator : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_threshwackonator() : CreatureScript("npc_threshwackonator") { }
|
||||
|
||||
struct npc_threshwackonatorAI : public FollowerAI
|
||||
{
|
||||
npc_threshwackonatorAI(Creature* creature) : FollowerAI(creature) { }
|
||||
|
||||
void Reset() { }
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
|
||||
{
|
||||
FollowerAI::MoveInLineOfSight(who);
|
||||
|
||||
if (!me->GetVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_GELKAK)
|
||||
{
|
||||
if (me->IsWithinDistInMap(who, 10.0f))
|
||||
{
|
||||
Talk(SAY_AT_CLOSE, who);
|
||||
DoAtEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoAtEnd()
|
||||
{
|
||||
me->setFaction(FACTION_HOSTILE);
|
||||
|
||||
if (Player* pHolder = GetLeaderForFollower())
|
||||
AttackStart(pHolder);
|
||||
|
||||
SetFollowComplete(true);
|
||||
}
|
||||
};
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
if (action == GOSSIP_ACTION_INFO_DEF+1)
|
||||
{
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
|
||||
if (npc_threshwackonatorAI* pThreshAI = CAST_AI(npc_threshwackonator::npc_threshwackonatorAI, creature->AI()))
|
||||
{
|
||||
creature->AI()->Talk(EMOTE_START);
|
||||
pThreshAI->StartFollow(player);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (player->GetQuestStatus(QUEST_GYROMAST_REV) == QUEST_STATUS_INCOMPLETE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_INSERT_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
|
||||
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_threshwackonatorAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_darkshore()
|
||||
{
|
||||
// Ours
|
||||
new npc_murkdeep();
|
||||
|
||||
// Theirs
|
||||
new npc_kerlonian();
|
||||
new npc_prospector_remtravel();
|
||||
new npc_threshwackonator();
|
||||
}
|
||||
@@ -1,628 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Desolace
|
||||
SD%Complete: 100
|
||||
SDComment: Quest support: 5561
|
||||
SDCategory: Desolace
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_aged_dying_ancient_kodo
|
||||
npc_dalinda_malem
|
||||
go_demon_portal
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "Player.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
// Ours
|
||||
enum Caravan
|
||||
{
|
||||
QUEST_BODYGUARD_FOR_HIRE = 5821,
|
||||
QUEST_GIZELTON_CARAVAN = 5943,
|
||||
|
||||
EVENT_RESUME_PATH = 1,
|
||||
EVENT_WAIT_FOR_ASSIST = 2,
|
||||
EVENT_RESTART_ESCORT = 3,
|
||||
|
||||
NPC_CORK_GIZELTON = 11625,
|
||||
NPC_RIGGER_GIZELTON = 11626,
|
||||
NPC_CARAVAN_KODO = 11564,
|
||||
NPC_VENDOR_TRON = 12245,
|
||||
NPC_SUPER_SELLER = 12246,
|
||||
|
||||
SAY_CARAVAN_LEAVE = 0,
|
||||
SAY_CARAVAN_HIRE = 1,
|
||||
|
||||
MAX_CARAVAN_SUMMONS = 3,
|
||||
|
||||
TIME_SHOP_STOP = 10*MINUTE*IN_MILLISECONDS,
|
||||
TIME_HIRE_STOP = 4*MINUTE*IN_MILLISECONDS,
|
||||
|
||||
// Ambush
|
||||
NPC_KOLKAR_WAYLAYER = 12976,
|
||||
NPC_KOLKAR_AMBUSHER = 12977,
|
||||
NPC_LESSER_INFERNAL = 4676,
|
||||
NPC_DOOMWARDER = 4677,
|
||||
NPC_NETHER = 4684,
|
||||
|
||||
};
|
||||
|
||||
class npc_cork_gizelton : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_cork_gizelton() : CreatureScript("npc_cork_gizelton") { }
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_BODYGUARD_FOR_HIRE)
|
||||
creature->AI()->SetGUID(player->GetGUID(), player->getFaction());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_cork_gizeltonAI(creature);
|
||||
}
|
||||
|
||||
struct npc_cork_gizeltonAI : public npc_escortAI
|
||||
{
|
||||
npc_cork_gizeltonAI(Creature* creature) : npc_escortAI(creature)
|
||||
{
|
||||
memset(&summons, 0, sizeof(summons));
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
uint64 summons[MAX_CARAVAN_SUMMONS];
|
||||
bool headNorth;
|
||||
|
||||
uint64 _playerGUID;
|
||||
uint32 _faction;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_playerGUID = 0;
|
||||
_faction = 35;
|
||||
headNorth = true;
|
||||
me->setActive(true);
|
||||
events.ScheduleEvent(EVENT_RESTART_ESCORT, 0);
|
||||
}
|
||||
|
||||
void JustRespawned()
|
||||
{
|
||||
npc_escortAI::JustRespawned();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
npc_escortAI::InitializeAI();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
RemoveSummons();
|
||||
npc_escortAI::JustDied(killer);
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
SummonsFollow();
|
||||
ImmuneFlagSet(false, 35);
|
||||
npc_escortAI::EnterEvadeMode();
|
||||
}
|
||||
|
||||
void CheckPlayer()
|
||||
{
|
||||
if (_playerGUID)
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID))
|
||||
if (me->IsWithinDist(player, 60.0f))
|
||||
return;
|
||||
|
||||
_playerGUID = 0;
|
||||
_faction = 35;
|
||||
ImmuneFlagSet(false, _faction);
|
||||
}
|
||||
|
||||
void SetGUID(uint64 playerGUID, int32 faction)
|
||||
{
|
||||
_playerGUID = playerGUID;
|
||||
_faction = faction;
|
||||
SetEscortPaused(false);
|
||||
if (Creature* active = !headNorth ? me : ObjectAccessor::GetCreature(*me, summons[0]))
|
||||
active->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
events.CancelEvent(EVENT_WAIT_FOR_ASSIST);
|
||||
}
|
||||
|
||||
void SetData(uint32 field, uint32 data)
|
||||
{
|
||||
if (field == 1 && data == 1)
|
||||
if (Player* player = me->SelectNearestPlayer(50.0f))
|
||||
SetGUID(player->GetGUID(), player->getFaction());
|
||||
}
|
||||
|
||||
bool CheckCaravan()
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_CARAVAN_SUMMONS; ++i)
|
||||
{
|
||||
if (summons[i] == 0)
|
||||
{
|
||||
SummonHelpers();
|
||||
return false;
|
||||
}
|
||||
|
||||
Creature* summon = ObjectAccessor::GetCreature(*me, summons[i]);
|
||||
if (!summon || me->GetDistance2d(summon) > 25.0f)
|
||||
{
|
||||
SummonHelpers();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemoveSummons()
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_CARAVAN_SUMMONS; ++i)
|
||||
{
|
||||
if (Creature* summon = ObjectAccessor::GetCreature(*me, summons[i]))
|
||||
summon->DespawnOrUnsummon();
|
||||
|
||||
summons[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SummonHelpers()
|
||||
{
|
||||
RemoveSummons();
|
||||
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
|
||||
Creature* cr = NULL;
|
||||
if (cr = me->SummonCreature(NPC_RIGGER_GIZELTON, *me))
|
||||
{
|
||||
cr->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
summons[0] = cr->GetGUID();
|
||||
}
|
||||
if (cr = me->SummonCreature(NPC_CARAVAN_KODO, *me))
|
||||
summons[1] = cr->GetGUID();
|
||||
if (cr = me->SummonCreature(NPC_CARAVAN_KODO, *me))
|
||||
summons[2] = cr->GetGUID();
|
||||
|
||||
SummonsFollow();
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* creature, Unit*)
|
||||
{
|
||||
if (creature->GetGUID() == summons[0])
|
||||
summons[0] = 0;
|
||||
else if (creature->GetGUID() == summons[1])
|
||||
summons[1] = 0;
|
||||
else if (creature->GetGUID() == summons[2])
|
||||
summons[2] = 0;
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* creature)
|
||||
{
|
||||
if (creature->GetGUID() == summons[0])
|
||||
summons[0] = 0;
|
||||
else if (creature->GetGUID() == summons[1])
|
||||
summons[1] = 0;
|
||||
else if (creature->GetGUID() == summons[2])
|
||||
summons[2] = 0;
|
||||
}
|
||||
|
||||
void SummonsFollow()
|
||||
{
|
||||
float dist = 1.0f;
|
||||
for (uint8 i = 0; i < MAX_CARAVAN_SUMMONS; ++i)
|
||||
if (Creature* summon = ObjectAccessor::GetCreature(*me, summons[i]))
|
||||
{
|
||||
summon->GetMotionMaster()->Clear(false);
|
||||
summon->StopMoving();
|
||||
summon->GetMotionMaster()->MoveFollow(me, dist, M_PI, MOTION_SLOT_ACTIVE);
|
||||
dist += (i == 1 ? 9.5f : 3.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void RelocateSummons()
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_CARAVAN_SUMMONS; ++i)
|
||||
if (Creature* summon = ObjectAccessor::GetCreature(*me, summons[i]))
|
||||
summon->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
|
||||
}
|
||||
|
||||
void ImmuneFlagSet(bool remove, uint32 faction)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_CARAVAN_SUMMONS; ++i)
|
||||
if (Creature* summon = ObjectAccessor::GetCreature(*me, summons[i]))
|
||||
{
|
||||
summon->setFaction(faction);
|
||||
if (remove)
|
||||
summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
else
|
||||
summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
}
|
||||
if (remove)
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
else
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->setFaction(faction);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
RelocateSummons();
|
||||
switch (waypointId)
|
||||
{
|
||||
// Finished north path
|
||||
case 52:
|
||||
me->SummonCreature(NPC_VENDOR_TRON, -694.61f, 1460.7f, 90.794f, 2.4f, TEMPSUMMON_TIMED_DESPAWN, TIME_SHOP_STOP+15*IN_MILLISECONDS);
|
||||
SetEscortPaused(true);
|
||||
events.ScheduleEvent(EVENT_RESUME_PATH, TIME_SHOP_STOP);
|
||||
CheckCaravan();
|
||||
break;
|
||||
// Finished south path
|
||||
case 193:
|
||||
me->SummonCreature(NPC_SUPER_SELLER, -1905.5f, 2463.3f, 61.52f, 5.87f, TEMPSUMMON_TIMED_DESPAWN, TIME_SHOP_STOP+15*IN_MILLISECONDS);
|
||||
SetEscortPaused(true);
|
||||
events.ScheduleEvent(EVENT_RESUME_PATH, TIME_SHOP_STOP);
|
||||
CheckCaravan();
|
||||
break;
|
||||
// North -> South - hire
|
||||
case 77:
|
||||
SetEscortPaused(true);
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
Talk(SAY_CARAVAN_HIRE);
|
||||
events.ScheduleEvent(EVENT_WAIT_FOR_ASSIST, TIME_HIRE_STOP);
|
||||
break;
|
||||
// Sout -> North - hire
|
||||
case 208:
|
||||
SetEscortPaused(true);
|
||||
if (Creature* rigger = ObjectAccessor::GetCreature(*me, summons[0]))
|
||||
{
|
||||
rigger->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
rigger->AI()->Talk(SAY_CARAVAN_HIRE);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_WAIT_FOR_ASSIST, TIME_HIRE_STOP);
|
||||
break;
|
||||
// North -> South - complete
|
||||
case 103:
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID))
|
||||
{
|
||||
if (CheckCaravan())
|
||||
player->GroupEventHappens(QUEST_BODYGUARD_FOR_HIRE, player);
|
||||
else
|
||||
player->FailQuest(QUEST_BODYGUARD_FOR_HIRE);
|
||||
}
|
||||
_playerGUID = 0;
|
||||
CheckPlayer();
|
||||
break;
|
||||
// South -> North - complete
|
||||
case 235:
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID))
|
||||
{
|
||||
if (CheckCaravan())
|
||||
player->GroupEventHappens(QUEST_GIZELTON_CARAVAN, player);
|
||||
else
|
||||
player->FailQuest(QUEST_GIZELTON_CARAVAN);
|
||||
}
|
||||
_playerGUID = 0;
|
||||
CheckPlayer();
|
||||
break;
|
||||
// North -> South - spawn attackers
|
||||
case 83:
|
||||
case 93:
|
||||
case 100:
|
||||
{
|
||||
if (!_playerGUID)
|
||||
return;
|
||||
ImmuneFlagSet(true, _faction);
|
||||
Creature* cr = NULL;
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
{
|
||||
float o = (i*M_PI/2)+(M_PI/4);
|
||||
float x = me->GetPositionX()+cos(o)*15.0f;
|
||||
float y = me->GetPositionY()+sin(o)*15.0f;
|
||||
if (cr = me->SummonCreature((i%2 == 0 ? NPC_KOLKAR_WAYLAYER : NPC_KOLKAR_AMBUSHER),
|
||||
x, y, me->GetMap()->GetHeight(x, y, MAX_HEIGHT), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
|
||||
cr->AI()->AttackStart(me);
|
||||
}
|
||||
if (cr)
|
||||
{
|
||||
AttackStart(cr);
|
||||
me->CallForHelp(50.0f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// South -> North - spawn attackers
|
||||
case 221:
|
||||
case 228:
|
||||
case 233:
|
||||
{
|
||||
if (!_playerGUID)
|
||||
return;
|
||||
ImmuneFlagSet(true, _faction);
|
||||
Creature* cr = NULL;
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
{
|
||||
float o = i*2*M_PI/3;
|
||||
float x = me->GetPositionX()+cos(o)*10.0f;
|
||||
float y = me->GetPositionY()+sin(o)*10.0f;
|
||||
uint32 entry = NPC_LESSER_INFERNAL;
|
||||
if (i)
|
||||
entry = i == 1 ? NPC_DOOMWARDER : NPC_NETHER;
|
||||
|
||||
if (cr = me->SummonCreature(entry, x, y, me->GetMap()->GetHeight(x, y, MAX_HEIGHT), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
|
||||
cr->AI()->AttackStart(me);
|
||||
}
|
||||
if (cr)
|
||||
{
|
||||
AttackStart(cr);
|
||||
me->CallForHelp(50.0f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 282:
|
||||
events.ScheduleEvent(EVENT_RESTART_ESCORT, 1000);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateEscortAI(uint32 diff)
|
||||
{
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_RESUME_PATH:
|
||||
SetEscortPaused(false);
|
||||
if (Creature* talker = headNorth ? me : ObjectAccessor::GetCreature(*me, summons[0]))
|
||||
talker->AI()->Talk(SAY_CARAVAN_LEAVE);
|
||||
|
||||
headNorth = !headNorth;
|
||||
break;
|
||||
case EVENT_WAIT_FOR_ASSIST:
|
||||
SetEscortPaused(false);
|
||||
if (Creature* active = !headNorth ? me : ObjectAccessor::GetCreature(*me, summons[0]))
|
||||
active->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
break;
|
||||
case EVENT_RESTART_ESCORT:
|
||||
CheckCaravan();
|
||||
SetDespawnAtEnd(false);
|
||||
Start(true, true, 0, 0, false, false, true);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Theirs
|
||||
enum DyingKodo
|
||||
{
|
||||
SAY_SMEED_HOME = 0,
|
||||
|
||||
QUEST_KODO = 5561,
|
||||
|
||||
NPC_SMEED = 11596,
|
||||
NPC_AGED_KODO = 4700,
|
||||
NPC_DYING_KODO = 4701,
|
||||
NPC_ANCIENT_KODO = 4702,
|
||||
NPC_TAMED_KODO = 11627,
|
||||
|
||||
SPELL_KODO_KOMBO_ITEM = 18153,
|
||||
SPELL_KODO_KOMBO_PLAYER_BUFF = 18172,
|
||||
SPELL_KODO_KOMBO_DESPAWN_BUFF = 18377,
|
||||
SPELL_KODO_KOMBO_GOSSIP = 18362
|
||||
|
||||
};
|
||||
|
||||
class npc_aged_dying_ancient_kodo : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_aged_dying_ancient_kodo() : CreatureScript("npc_aged_dying_ancient_kodo") { }
|
||||
|
||||
struct npc_aged_dying_ancient_kodoAI : public ScriptedAI
|
||||
{
|
||||
npc_aged_dying_ancient_kodoAI(Creature* creature) : ScriptedAI(creature) {}
|
||||
|
||||
void JustRespawned()
|
||||
{
|
||||
me->UpdateEntry(RAND(NPC_AGED_KODO, NPC_DYING_KODO, NPC_ANCIENT_KODO), NULL, false);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (who->GetEntry() == NPC_SMEED && me->IsWithinDistInMap(who, 10.0f) && !me->HasAura(SPELL_KODO_KOMBO_GOSSIP))
|
||||
{
|
||||
me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
|
||||
me->GetMotionMaster()->Clear();
|
||||
|
||||
DoCast(me, SPELL_KODO_KOMBO_GOSSIP, true);
|
||||
if (Creature* smeed = who->ToCreature())
|
||||
smeed->AI()->Talk(SAY_SMEED_HOME);
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, SpellInfo const* spell)
|
||||
{
|
||||
if (spell->Id == SPELL_KODO_KOMBO_ITEM)
|
||||
{
|
||||
if (!(caster->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF) || me->HasAura(SPELL_KODO_KOMBO_DESPAWN_BUFF))
|
||||
&& (me->GetEntry() == NPC_AGED_KODO || me->GetEntry() == NPC_DYING_KODO || me->GetEntry() == NPC_ANCIENT_KODO))
|
||||
{
|
||||
me->UpdateEntry(NPC_TAMED_KODO, NULL, false);
|
||||
EnterEvadeMode();
|
||||
me->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, me->GetFollowAngle());
|
||||
|
||||
caster->CastSpell(caster, SPELL_KODO_KOMBO_PLAYER_BUFF, true);
|
||||
DoCast(me, SPELL_KODO_KOMBO_DESPAWN_BUFF, true);
|
||||
}
|
||||
}
|
||||
else if (spell->Id == SPELL_KODO_KOMBO_GOSSIP)
|
||||
{
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
me->DespawnOrUnsummon(60000);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (player->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF) && creature->HasAura(SPELL_KODO_KOMBO_DESPAWN_BUFF))
|
||||
{
|
||||
player->TalkedToCreature(creature->GetEntry(), 0);
|
||||
player->RemoveAurasDueToSpell(SPELL_KODO_KOMBO_PLAYER_BUFF);
|
||||
}
|
||||
|
||||
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_aged_dying_ancient_kodoAI(creature);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_dalinda_malem. Quest 1440
|
||||
######*/
|
||||
|
||||
enum Dalinda
|
||||
{
|
||||
QUEST_RETURN_TO_VAHLARRIEL = 1440
|
||||
};
|
||||
|
||||
class npc_dalinda : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_dalinda() : CreatureScript("npc_dalinda") { }
|
||||
|
||||
struct npc_dalindaAI : public npc_escortAI
|
||||
{
|
||||
npc_dalindaAI(Creature* creature) : npc_escortAI(creature) { }
|
||||
|
||||
void Reset() { }
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
player->FailQuest(QUEST_RETURN_TO_VAHLARRIEL);
|
||||
return;
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
Player* player = GetPlayerForEscort();
|
||||
|
||||
switch (waypointId)
|
||||
{
|
||||
case 1:
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
break;
|
||||
case 15:
|
||||
if (player)
|
||||
player->GroupEventHappens(QUEST_RETURN_TO_VAHLARRIEL, me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_RETURN_TO_VAHLARRIEL)
|
||||
{
|
||||
if (npc_escortAI* escortAI = CAST_AI(npc_dalinda::npc_dalindaAI, creature->AI()))
|
||||
{
|
||||
escortAI->Start(true, false, player->GetGUID());
|
||||
creature->setFaction(113);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_dalindaAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## go_demon_portal
|
||||
######*/
|
||||
|
||||
enum DemonPortal
|
||||
{
|
||||
NPC_DEMON_GUARDIAN = 11937,
|
||||
QUEST_PORTAL_OF_THE_LEGION = 5581
|
||||
};
|
||||
|
||||
class go_demon_portal : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_demon_portal() : GameObjectScript("go_demon_portal") { }
|
||||
|
||||
bool OnGossipHello(Player* player, GameObject* go)
|
||||
{
|
||||
if (player->GetQuestStatus(QUEST_PORTAL_OF_THE_LEGION) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_DEMON_GUARDIAN, 5.0f, true))
|
||||
{
|
||||
if (Creature* guardian = player->SummonCreature(NPC_DEMON_GUARDIAN, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0))
|
||||
guardian->AI()->AttackStart(player);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_desolace()
|
||||
{
|
||||
// Ours
|
||||
new npc_cork_gizelton();
|
||||
|
||||
// Theirs
|
||||
new npc_aged_dying_ancient_kodo();
|
||||
new npc_dalinda();
|
||||
new go_demon_portal();
|
||||
}
|
||||
@@ -1,595 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "Vehicle.h"
|
||||
#include "SpellScript.h"
|
||||
#include "Player.h"
|
||||
|
||||
/*######
|
||||
##Quest 5441: Lazy Peons
|
||||
##npc_lazy_peon
|
||||
######*/
|
||||
|
||||
enum LazyPeonYells
|
||||
{
|
||||
SAY_SPELL_HIT = 0
|
||||
};
|
||||
|
||||
enum LazyPeon
|
||||
{
|
||||
QUEST_LAZY_PEONS = 5441,
|
||||
GO_LUMBERPILE = 175784,
|
||||
SPELL_BUFF_SLEEP = 17743,
|
||||
SPELL_AWAKEN_PEON = 19938
|
||||
};
|
||||
|
||||
class npc_lazy_peon : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_lazy_peon() : CreatureScript("npc_lazy_peon") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_lazy_peonAI(creature);
|
||||
}
|
||||
|
||||
struct npc_lazy_peonAI : public ScriptedAI
|
||||
{
|
||||
npc_lazy_peonAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint64 PlayerGUID;
|
||||
|
||||
uint32 RebuffTimer;
|
||||
bool work;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
PlayerGUID = 0;
|
||||
RebuffTimer = 0;
|
||||
work = false;
|
||||
}
|
||||
|
||||
void MovementInform(uint32 /*type*/, uint32 id)
|
||||
{
|
||||
if (id == 1)
|
||||
work = true;
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, const SpellInfo* spell)
|
||||
{
|
||||
if (spell->Id != SPELL_AWAKEN_PEON)
|
||||
return;
|
||||
|
||||
Player* player = caster->ToPlayer();
|
||||
if (player && player->GetQuestStatus(QUEST_LAZY_PEONS) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
player->KilledMonsterCredit(me->GetEntry(), me->GetGUID());
|
||||
Talk(SAY_SPELL_HIT, caster);
|
||||
me->RemoveAllAuras();
|
||||
if (GameObject* Lumberpile = me->FindNearestGameObject(GO_LUMBERPILE, 20))
|
||||
me->GetMotionMaster()->MovePoint(1, Lumberpile->GetPositionX()-1, Lumberpile->GetPositionY(), Lumberpile->GetPositionZ());
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (work == true)
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_WORK_CHOPWOOD);
|
||||
if (RebuffTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_BUFF_SLEEP);
|
||||
RebuffTimer = 300000; //Rebuff agian in 5 minutes
|
||||
}
|
||||
else
|
||||
RebuffTimer -= diff;
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
// Tiger Matriarch Credit
|
||||
SAY_MATRIARCH_AGGRO = 0,
|
||||
|
||||
// Troll Volunteer
|
||||
SAY_VOLUNTEER_START = 0,
|
||||
SAY_VOLUNTEER_END = 1,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// Tiger Matriarch Credit
|
||||
SPELL_SUMMON_MATRIARCH = 75187,
|
||||
SPELL_NO_SUMMON_AURA = 75213,
|
||||
SPELL_DETECT_INVIS = 75180,
|
||||
SPELL_SUMMON_ZENTABRA_TRIGGER = 75212,
|
||||
|
||||
// Tiger Matriarch
|
||||
SPELL_POUNCE = 61184,
|
||||
SPELL_FURIOUS_BITE = 75164,
|
||||
SPELL_SUMMON_ZENTABRA = 75181,
|
||||
SPELL_SPIRIT_OF_THE_TIGER_RIDER = 75166,
|
||||
SPELL_EJECT_PASSENGERS = 50630,
|
||||
|
||||
// Troll Volunteer
|
||||
SPELL_VOLUNTEER_AURA = 75076,
|
||||
SPELL_PETACT_AURA = 74071,
|
||||
SPELL_QUEST_CREDIT = 75106,
|
||||
SPELL_MOUNTING_CHECK = 75420,
|
||||
SPELL_TURNIN = 73953,
|
||||
SPELL_AOE_TURNIN = 75107,
|
||||
|
||||
// Vol'jin War Drums
|
||||
SPELL_MOTIVATE_1 = 75088,
|
||||
SPELL_MOTIVATE_2 = 75086,
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
// Tiger Matriarch Credit
|
||||
NPC_TIGER_VEHICLE = 40305,
|
||||
|
||||
// Troll Volunteer
|
||||
NPC_URUZIN = 40253,
|
||||
NPC_VOLUNTEER_1 = 40264,
|
||||
NPC_VOLUNTEER_2 = 40260,
|
||||
|
||||
// Vol'jin War Drums
|
||||
NPC_CITIZEN_1 = 40256,
|
||||
NPC_CITIZEN_2 = 40257,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
// Tiger Matriarch Credit
|
||||
EVENT_CHECK_SUMMON_AURA = 1,
|
||||
|
||||
// Tiger Matriarch
|
||||
EVENT_POUNCE = 2,
|
||||
EVENT_NOSUMMON = 3,
|
||||
};
|
||||
|
||||
enum Points
|
||||
{
|
||||
POINT_URUZIN = 4026400,
|
||||
};
|
||||
|
||||
class npc_tiger_matriarch_credit : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_tiger_matriarch_credit() : CreatureScript("npc_tiger_matriarch_credit") { }
|
||||
|
||||
struct npc_tiger_matriarch_creditAI : public ScriptedAI
|
||||
{
|
||||
npc_tiger_matriarch_creditAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
SetCombatMovement(false);
|
||||
events.ScheduleEvent(EVENT_CHECK_SUMMON_AURA, 2000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
if (events.ExecuteEvent() == EVENT_CHECK_SUMMON_AURA)
|
||||
{
|
||||
std::list<Creature*> tigers;
|
||||
GetCreatureListWithEntryInGrid(tigers, me, NPC_TIGER_VEHICLE, 15.0f);
|
||||
if (!tigers.empty())
|
||||
{
|
||||
for (std::list<Creature*>::iterator itr = tigers.begin(); itr != tigers.end(); ++itr)
|
||||
{
|
||||
if (!(*itr)->IsSummon())
|
||||
continue;
|
||||
|
||||
if (Unit* summoner = (*itr)->ToTempSummon()->GetSummoner())
|
||||
if (!summoner->HasAura(SPELL_NO_SUMMON_AURA) && !summoner->HasAura(SPELL_SUMMON_ZENTABRA_TRIGGER)
|
||||
&& !summoner->IsInCombat())
|
||||
{
|
||||
me->AddAura(SPELL_NO_SUMMON_AURA, summoner);
|
||||
me->AddAura(SPELL_DETECT_INVIS, summoner);
|
||||
summoner->CastSpell(summoner, SPELL_SUMMON_MATRIARCH, true);
|
||||
Talk(SAY_MATRIARCH_AGGRO, summoner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_CHECK_SUMMON_AURA, 5000);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_tiger_matriarch_creditAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_tiger_matriarch : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_tiger_matriarch() : CreatureScript("npc_tiger_matriarch") { }
|
||||
|
||||
struct npc_tiger_matriarchAI : public ScriptedAI
|
||||
{
|
||||
npc_tiger_matriarchAI(Creature* creature) : ScriptedAI(creature),
|
||||
_tigerGuid(0)
|
||||
{
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*target*/)
|
||||
{
|
||||
_events.Reset();
|
||||
_events.ScheduleEvent(EVENT_POUNCE, 100);
|
||||
_events.ScheduleEvent(EVENT_NOSUMMON, 50000);
|
||||
}
|
||||
|
||||
void IsSummonedBy(Unit* summoner)
|
||||
{
|
||||
if (summoner->GetTypeId() != TYPEID_PLAYER || !summoner->GetVehicle())
|
||||
return;
|
||||
|
||||
_tigerGuid = summoner->GetVehicle()->GetBase()->GetGUID();
|
||||
if (Unit* tiger = ObjectAccessor::GetUnit(*me, _tigerGuid))
|
||||
{
|
||||
me->AddThreat(tiger, 500000.0f);
|
||||
DoCast(me, SPELL_FURIOUS_BITE);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() != TYPEID_UNIT || !victim->IsSummon())
|
||||
return;
|
||||
|
||||
if (Unit* vehSummoner = victim->ToTempSummon()->GetSummoner())
|
||||
{
|
||||
vehSummoner->RemoveAurasDueToSpell(SPELL_NO_SUMMON_AURA);
|
||||
vehSummoner->RemoveAurasDueToSpell(SPELL_DETECT_INVIS);
|
||||
vehSummoner->RemoveAurasDueToSpell(SPELL_SPIRIT_OF_THE_TIGER_RIDER);
|
||||
vehSummoner->RemoveAurasDueToSpell(SPELL_SUMMON_ZENTABRA_TRIGGER);
|
||||
}
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (!attacker || !attacker->IsSummon())
|
||||
return;
|
||||
|
||||
if (HealthBelowPct(20))
|
||||
{
|
||||
damage = 0;
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
if (Unit* vehSummoner = attacker->ToTempSummon()->GetSummoner())
|
||||
{
|
||||
vehSummoner->AddAura(SPELL_SUMMON_ZENTABRA_TRIGGER, vehSummoner);
|
||||
vehSummoner->CastSpell(vehSummoner, SPELL_SUMMON_ZENTABRA, true);
|
||||
attacker->CastSpell(attacker, SPELL_EJECT_PASSENGERS, true);
|
||||
vehSummoner->RemoveAurasDueToSpell(SPELL_NO_SUMMON_AURA);
|
||||
vehSummoner->RemoveAurasDueToSpell(SPELL_DETECT_INVIS);
|
||||
vehSummoner->RemoveAurasDueToSpell(SPELL_SPIRIT_OF_THE_TIGER_RIDER);
|
||||
vehSummoner->RemoveAurasDueToSpell(SPELL_SUMMON_ZENTABRA_TRIGGER);
|
||||
}
|
||||
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (!_tigerGuid)
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_POUNCE:
|
||||
DoCastVictim(SPELL_POUNCE);
|
||||
_events.ScheduleEvent(EVENT_POUNCE, 30000);
|
||||
break;
|
||||
case EVENT_NOSUMMON: // Reapply SPELL_NO_SUMMON_AURA
|
||||
if (Unit* tiger = ObjectAccessor::GetUnit(*me, _tigerGuid))
|
||||
{
|
||||
if (tiger->IsSummon())
|
||||
if (Unit* vehSummoner = tiger->ToTempSummon()->GetSummoner())
|
||||
me->AddAura(SPELL_NO_SUMMON_AURA, vehSummoner);
|
||||
}
|
||||
_events.ScheduleEvent(EVENT_NOSUMMON, 50000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
uint64 _tigerGuid;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_tiger_matriarchAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// These models was found in sniff.
|
||||
/// @todo generalize these models with race from dbc
|
||||
uint32 const trollmodel[] =
|
||||
{11665, 11734, 11750, 12037, 12038, 12042, 12049, 12849, 13529, 14759, 15570, 15701,
|
||||
15702, 1882, 1897, 1976, 2025, 27286, 2734, 2735, 4084, 4085, 4087, 4089, 4231, 4357,
|
||||
4358, 4360, 4361, 4362, 4363, 4370, 4532, 4537, 4540, 4610, 6839, 7037, 9767, 9768};
|
||||
|
||||
class npc_troll_volunteer : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_troll_volunteer() : CreatureScript("npc_troll_volunteer") { }
|
||||
|
||||
struct npc_troll_volunteerAI : public ScriptedAI
|
||||
{
|
||||
npc_troll_volunteerAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
}
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
if (me->isDead() || !me->GetOwner())
|
||||
return;
|
||||
|
||||
Reset();
|
||||
|
||||
switch (urand(0, 3))
|
||||
{
|
||||
case 0:
|
||||
_mountModel = 6471;
|
||||
break;
|
||||
case 1:
|
||||
_mountModel = 6473;
|
||||
break;
|
||||
case 2:
|
||||
_mountModel = 6469;
|
||||
break;
|
||||
default:
|
||||
_mountModel = 6472;
|
||||
break;
|
||||
}
|
||||
me->SetDisplayId(trollmodel[urand(0, 39)]);
|
||||
if (Player* player = me->GetOwner()->ToPlayer())
|
||||
me->GetMotionMaster()->MoveFollow(player, 5.0f, float(rand_norm() + 1.0f) * M_PI / 3.0f * 4.0f);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_complete = false;
|
||||
me->AddAura(SPELL_VOLUNTEER_AURA, me);
|
||||
me->AddAura(SPELL_MOUNTING_CHECK, me);
|
||||
DoCast(me, SPELL_PETACT_AURA);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
Talk(SAY_VOLUNTEER_START);
|
||||
}
|
||||
|
||||
// This is needed for mount check aura to know what mountmodel the npc got stored
|
||||
uint32 GetMountId()
|
||||
{
|
||||
return _mountModel;
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE)
|
||||
return;
|
||||
if (id == POINT_URUZIN)
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, SpellInfo const* spell)
|
||||
{
|
||||
if (spell->Id == SPELL_AOE_TURNIN && caster->GetEntry() == NPC_URUZIN && !_complete)
|
||||
{
|
||||
_complete = true; // Preventing from giving credit twice
|
||||
DoCast(me, SPELL_TURNIN);
|
||||
DoCast(me, SPELL_QUEST_CREDIT);
|
||||
me->RemoveAurasDueToSpell(SPELL_MOUNTING_CHECK);
|
||||
me->Dismount();
|
||||
Talk(SAY_VOLUNTEER_END);
|
||||
me->GetMotionMaster()->MovePoint(POINT_URUZIN, caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _mountModel;
|
||||
bool _complete;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_troll_volunteerAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
typedef npc_troll_volunteer::npc_troll_volunteerAI VolunteerAI;
|
||||
|
||||
class spell_mount_check : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_mount_check() : SpellScriptLoader("spell_mount_check") { }
|
||||
|
||||
class spell_mount_check_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_mount_check_AuraScript)
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/)
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_MOUNTING_CHECK))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
Unit* owner = target->GetOwner();
|
||||
|
||||
if (!owner)
|
||||
return;
|
||||
|
||||
if (owner->IsMounted() && !target->IsMounted())
|
||||
{
|
||||
if (VolunteerAI* volunteerAI = CAST_AI(VolunteerAI, target->GetAI()))
|
||||
target->Mount(volunteerAI->GetMountId());
|
||||
}
|
||||
else if (!owner->IsMounted() && target->IsMounted())
|
||||
target->Dismount();
|
||||
|
||||
target->SetSpeed(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN));
|
||||
target->SetSpeed(MOVE_WALK, owner->GetSpeedRate(MOVE_WALK));
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_mount_check_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_mount_check_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_voljin_war_drums : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_voljin_war_drums() : SpellScriptLoader("spell_voljin_war_drums") { }
|
||||
|
||||
class spell_voljin_war_drums_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_voljin_war_drums_SpellScript)
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/)
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_MOTIVATE_1))
|
||||
return false;
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_MOTIVATE_2))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
if (Unit* target = GetHitUnit())
|
||||
{
|
||||
uint32 motivate = 0;
|
||||
if (target->GetEntry() == NPC_CITIZEN_1)
|
||||
motivate = SPELL_MOTIVATE_1;
|
||||
else if (target->GetEntry() == NPC_CITIZEN_2)
|
||||
motivate = SPELL_MOTIVATE_2;
|
||||
if (motivate)
|
||||
caster->CastSpell(target, motivate, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_voljin_war_drums_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_voljin_war_drums_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
enum VoodooSpells
|
||||
{
|
||||
SPELL_BREW = 16712, // Special Brew
|
||||
SPELL_GHOSTLY = 16713, // Ghostly
|
||||
SPELL_HEX1 = 16707, // Hex
|
||||
SPELL_HEX2 = 16708, // Hex
|
||||
SPELL_HEX3 = 16709, // Hex
|
||||
SPELL_GROW = 16711, // Grow
|
||||
SPELL_LAUNCH = 16716, // Launch (Whee!)
|
||||
};
|
||||
|
||||
// 17009
|
||||
class spell_voodoo : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_voodoo() : SpellScriptLoader("spell_voodoo") { }
|
||||
|
||||
class spell_voodoo_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_voodoo_SpellScript)
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/)
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_BREW) || !sSpellMgr->GetSpellInfo(SPELL_GHOSTLY) ||
|
||||
!sSpellMgr->GetSpellInfo(SPELL_HEX1) || !sSpellMgr->GetSpellInfo(SPELL_HEX2) ||
|
||||
!sSpellMgr->GetSpellInfo(SPELL_HEX3) || !sSpellMgr->GetSpellInfo(SPELL_GROW) ||
|
||||
!sSpellMgr->GetSpellInfo(SPELL_LAUNCH))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
uint32 spellid = RAND(SPELL_BREW, SPELL_GHOSTLY, RAND(SPELL_HEX1, SPELL_HEX2, SPELL_HEX3), SPELL_GROW, SPELL_LAUNCH);
|
||||
if (Unit* target = GetHitUnit())
|
||||
GetCaster()->CastSpell(target, spellid, false);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_voodoo_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_voodoo_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_durotar()
|
||||
{
|
||||
new npc_lazy_peon();
|
||||
new npc_tiger_matriarch_credit();
|
||||
new npc_tiger_matriarch();
|
||||
new npc_troll_volunteer();
|
||||
new spell_mount_check();
|
||||
new spell_voljin_war_drums();
|
||||
new spell_voodoo();
|
||||
}
|
||||
@@ -1,427 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Dustwallow_Marsh
|
||||
SD%Complete: 95
|
||||
SDComment: Quest support: 11180, 558, 11126, 11142, 11174, Vendor Nat Pagle
|
||||
SDCategory: Dustwallow Marsh
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_lady_jaina_proudmoore
|
||||
npc_nat_pagle
|
||||
npc_private_hendel
|
||||
npc_cassa_crimsonwing - handled by npc_taxi
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "SpellScript.h"
|
||||
#include "Player.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
/*######
|
||||
## npc_lady_jaina_proudmoore
|
||||
######*/
|
||||
|
||||
enum LadyJaina
|
||||
{
|
||||
QUEST_JAINAS_AUTOGRAPH = 558,
|
||||
SPELL_JAINAS_AUTOGRAPH = 23122
|
||||
};
|
||||
|
||||
#define GOSSIP_ITEM_JAINA "I know this is rather silly but i have a young ward who is a bit shy and would like your autograph."
|
||||
|
||||
class npc_lady_jaina_proudmoore : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_lady_jaina_proudmoore() : CreatureScript("npc_lady_jaina_proudmoore") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
if (action == GOSSIP_SENDER_INFO)
|
||||
{
|
||||
player->SEND_GOSSIP_MENU(7012, creature->GetGUID());
|
||||
player->CastSpell(player, SPELL_JAINAS_AUTOGRAPH, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (creature->IsQuestGiver())
|
||||
player->PrepareQuestMenu(creature->GetGUID());
|
||||
|
||||
if (player->GetQuestStatus(QUEST_JAINAS_AUTOGRAPH) == QUEST_STATUS_INCOMPLETE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_JAINA, GOSSIP_SENDER_MAIN, GOSSIP_SENDER_INFO);
|
||||
|
||||
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_nat_pagle
|
||||
######*/
|
||||
|
||||
enum NatPagle
|
||||
{
|
||||
QUEST_NATS_MEASURING_TAPE = 8227
|
||||
};
|
||||
|
||||
class npc_nat_pagle : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_nat_pagle() : CreatureScript("npc_nat_pagle") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
if (action == GOSSIP_ACTION_TRADE)
|
||||
player->GetSession()->SendListInventory(creature->GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (creature->IsQuestGiver())
|
||||
player->PrepareQuestMenu(creature->GetGUID());
|
||||
|
||||
if (creature->IsVendor() && player->GetQuestRewardStatus(QUEST_NATS_MEASURING_TAPE))
|
||||
{
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
|
||||
player->SEND_GOSSIP_MENU(7640, creature->GetGUID());
|
||||
}
|
||||
else
|
||||
player->SEND_GOSSIP_MENU(7638, creature->GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_private_hendel
|
||||
######*/
|
||||
|
||||
enum Hendel
|
||||
{
|
||||
SAY_PROGRESS_1_TER = 0,
|
||||
SAY_PROGRESS_2_HEN = 1,
|
||||
SAY_PROGRESS_3_TER = 2,
|
||||
SAY_PROGRESS_4_TER = 3,
|
||||
EMOTE_SURRENDER = 4,
|
||||
|
||||
QUEST_MISSING_DIPLO_PT16 = 1324,
|
||||
FACTION_HOSTILE = 168, //guessed, may be different
|
||||
|
||||
NPC_SENTRY = 5184, //helps hendel
|
||||
NPC_JAINA = 4968, //appears once hendel gives up
|
||||
NPC_TERVOSH = 4967
|
||||
};
|
||||
|
||||
/// @todo develop this further, end event not created
|
||||
class npc_private_hendel : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_private_hendel() : CreatureScript("npc_private_hendel") { }
|
||||
|
||||
bool OnQuestAccept(Player* /*player*/, Creature* creature, const Quest* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_MISSING_DIPLO_PT16)
|
||||
creature->setFaction(FACTION_HOSTILE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_private_hendelAI(creature);
|
||||
}
|
||||
|
||||
struct npc_private_hendelAI : public ScriptedAI
|
||||
{
|
||||
npc_private_hendelAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->RestoreFaction();
|
||||
}
|
||||
|
||||
void AttackedBy(Unit* pAttacker)
|
||||
{
|
||||
if (me->GetVictim())
|
||||
return;
|
||||
|
||||
if (me->IsFriendlyTo(pAttacker))
|
||||
return;
|
||||
|
||||
AttackStart(pAttacker);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* pDoneBy, uint32 &Damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (Damage >= me->GetHealth() || me->HealthBelowPctDamaged(20, Damage))
|
||||
{
|
||||
Damage = 0;
|
||||
|
||||
if (pDoneBy)
|
||||
if (Player* player = pDoneBy->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
player->GroupEventHappens(QUEST_MISSING_DIPLO_PT16, me);
|
||||
|
||||
Talk(EMOTE_SURRENDER);
|
||||
EnterEvadeMode();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_zelfrax
|
||||
######*/
|
||||
|
||||
Position const MovePosition = {-2967.030f, -3872.1799f, 35.620f, 0.0f};
|
||||
|
||||
enum Zelfrax
|
||||
{
|
||||
SAY_ZELFRAX1 = 0,
|
||||
SAY_ZELFRAX2 = 1
|
||||
};
|
||||
|
||||
class npc_zelfrax : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_zelfrax() : CreatureScript("npc_zelfrax") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_zelfraxAI(creature);
|
||||
}
|
||||
|
||||
struct npc_zelfraxAI : public ScriptedAI
|
||||
{
|
||||
npc_zelfraxAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
MoveToDock();
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who)
|
||||
{
|
||||
if (!who)
|
||||
return;
|
||||
|
||||
if (me->Attack(who, true))
|
||||
{
|
||||
me->SetInCombatWith(who);
|
||||
who->SetInCombatWith(me);
|
||||
|
||||
if (IsCombatMovementAllowed())
|
||||
me->GetMotionMaster()->MoveChase(who);
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 Type, uint32 /*Id*/)
|
||||
{
|
||||
if (Type != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
|
||||
SetCombatMovement(true);
|
||||
|
||||
if (me->IsInCombat())
|
||||
if (Unit* unit = me->GetVictim())
|
||||
me->GetMotionMaster()->MoveChase(unit);
|
||||
}
|
||||
|
||||
void MoveToDock()
|
||||
{
|
||||
SetCombatMovement(false);
|
||||
me->GetMotionMaster()->MovePoint(0, MovePosition);
|
||||
Talk(SAY_ZELFRAX1);
|
||||
Talk(SAY_ZELFRAX2);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 /*Diff*/)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
enum SpellScripts
|
||||
{
|
||||
SPELL_OOZE_ZAP = 42489,
|
||||
SPELL_OOZE_ZAP_CHANNEL_END = 42485,
|
||||
SPELL_OOZE_CHANNEL_CREDIT = 42486,
|
||||
SPELL_ENERGIZED = 42492,
|
||||
};
|
||||
|
||||
class spell_ooze_zap : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ooze_zap() : SpellScriptLoader("spell_ooze_zap") { }
|
||||
|
||||
class spell_ooze_zap_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_ooze_zap_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/)
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_OOZE_ZAP))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
SpellCastResult CheckRequirement()
|
||||
{
|
||||
if (!GetCaster()->HasAura(GetSpellInfo()->Effects[EFFECT_1].CalcValue()))
|
||||
return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; // This is actually correct
|
||||
|
||||
if (!GetExplTargetUnit())
|
||||
return SPELL_FAILED_BAD_TARGETS;
|
||||
|
||||
return SPELL_CAST_OK;
|
||||
}
|
||||
|
||||
void HandleDummy(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
if (GetHitUnit())
|
||||
GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_ooze_zap_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
OnCheckCast += SpellCheckCastFn(spell_ooze_zap_SpellScript::CheckRequirement);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_ooze_zap_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_ooze_zap_channel_end : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ooze_zap_channel_end() : SpellScriptLoader("spell_ooze_zap_channel_end") { }
|
||||
|
||||
class spell_ooze_zap_channel_end_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_ooze_zap_channel_end_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/)
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_OOZE_ZAP_CHANNEL_END))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleDummy(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
if (Player* player = GetCaster()->ToPlayer())
|
||||
player->CastSpell(player, SPELL_OOZE_CHANNEL_CREDIT, true);
|
||||
Unit::Kill(GetHitUnit(), GetHitUnit());
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_ooze_zap_channel_end_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_ooze_zap_channel_end_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_energize_aoe : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_energize_aoe() : SpellScriptLoader("spell_energize_aoe") { }
|
||||
|
||||
class spell_energize_aoe_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_energize_aoe_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/)
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_ENERGIZED))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();)
|
||||
{
|
||||
if ((*itr)->GetTypeId() == TYPEID_PLAYER && (*itr)->ToPlayer()->GetQuestStatus(GetSpellInfo()->Effects[EFFECT_1].CalcValue()) == QUEST_STATUS_INCOMPLETE)
|
||||
++itr;
|
||||
else
|
||||
targets.erase(itr++);
|
||||
}
|
||||
targets.push_back(GetCaster());
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
GetCaster()->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_energize_aoe_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_energize_aoe_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_dustwallow_marsh()
|
||||
{
|
||||
new npc_lady_jaina_proudmoore();
|
||||
new npc_nat_pagle();
|
||||
new npc_private_hendel();
|
||||
new npc_zelfrax();
|
||||
new spell_ooze_zap();
|
||||
new spell_ooze_zap_channel_end();
|
||||
new spell_energize_aoe();
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Felwood
|
||||
SD%Complete: 95
|
||||
SDComment: Quest support: 4101, 4102
|
||||
SDCategory: Felwood
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npcs_riverbreeze_and_silversky
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "Player.h"
|
||||
|
||||
/*######
|
||||
## npcs_riverbreeze_and_silversky
|
||||
######*/
|
||||
|
||||
#define GOSSIP_ITEM_BEACON "Please make me a Cenarion Beacon"
|
||||
|
||||
enum RiverbreezeAndSilversky
|
||||
{
|
||||
SPELL_CENARION_BEACON = 15120,
|
||||
|
||||
NPC_ARATHANDRIS_SILVERSKY = 9528,
|
||||
NPC_MAYBESS_RIVERBREEZE = 9529,
|
||||
|
||||
QUEST_CLEASING_FELWOOD_A = 4101,
|
||||
QUEST_CLEASING_FELWOOD_H = 4102
|
||||
};
|
||||
|
||||
class npcs_riverbreeze_and_silversky : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npcs_riverbreeze_and_silversky() : CreatureScript("npcs_riverbreeze_and_silversky") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
if (action == GOSSIP_ACTION_INFO_DEF+1)
|
||||
{
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
creature->CastSpell(player, SPELL_CENARION_BEACON, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (creature->IsQuestGiver())
|
||||
player->PrepareQuestMenu(creature->GetGUID());
|
||||
|
||||
uint32 creatureId = creature->GetEntry();
|
||||
|
||||
if (creatureId == NPC_ARATHANDRIS_SILVERSKY)
|
||||
{
|
||||
if (player->GetQuestRewardStatus(QUEST_CLEASING_FELWOOD_A))
|
||||
{
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEACON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
player->SEND_GOSSIP_MENU(2848, creature->GetGUID());
|
||||
} else if (player->GetTeamId() == TEAM_HORDE)
|
||||
player->SEND_GOSSIP_MENU(2845, creature->GetGUID());
|
||||
else
|
||||
player->SEND_GOSSIP_MENU(2844, creature->GetGUID());
|
||||
}
|
||||
|
||||
if (creatureId == NPC_MAYBESS_RIVERBREEZE)
|
||||
{
|
||||
if (player->GetQuestRewardStatus(QUEST_CLEASING_FELWOOD_H))
|
||||
{
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEACON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
player->SEND_GOSSIP_MENU(2849, creature->GetGUID());
|
||||
} else if (player->GetTeamId() == TEAM_ALLIANCE)
|
||||
player->SEND_GOSSIP_MENU(2843, creature->GetGUID());
|
||||
else
|
||||
player->SEND_GOSSIP_MENU(2842, creature->GetGUID());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## at_ancient_leaf
|
||||
######*/
|
||||
|
||||
enum AncientMisc
|
||||
{
|
||||
QUEST_ANCIENT_LEAF = 7632,
|
||||
NPC_VARTRUS = 14524,
|
||||
NPC_STOMA = 14525,
|
||||
NPC_HASTAT = 14526,
|
||||
CREATURE_GROUP_ANCIENTS = 1
|
||||
};
|
||||
|
||||
class at_ancient_leaf : public AreaTriggerScript
|
||||
{
|
||||
public:
|
||||
at_ancient_leaf() : AreaTriggerScript("at_ancient_leaf") { }
|
||||
|
||||
bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/)
|
||||
{
|
||||
if (player->IsGameMaster() || !player->IsAlive())
|
||||
return false;
|
||||
|
||||
// Handle Call Ancients event start - The area trigger summons 3 ancients
|
||||
if ((player->GetQuestStatus(QUEST_ANCIENT_LEAF) == QUEST_STATUS_COMPLETE) || (player->GetQuestStatus(QUEST_ANCIENT_LEAF) == QUEST_STATUS_REWARDED))
|
||||
{
|
||||
// If ancients are already spawned, skip the rest
|
||||
if (GetClosestCreatureWithEntry(player, NPC_VARTRUS, 50.0f) || GetClosestCreatureWithEntry(player, NPC_STOMA, 50.0f) || GetClosestCreatureWithEntry(player, NPC_HASTAT, 50.0f))
|
||||
return true;
|
||||
|
||||
player->GetMap()->SummonCreatureGroup(CREATURE_GROUP_ANCIENTS);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_felwood()
|
||||
{
|
||||
new npcs_riverbreeze_and_silversky();
|
||||
new at_ancient_leaf();
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Feralas
|
||||
SD%Complete: 100
|
||||
SDComment: Quest support: 3520, 2767, Special vendor Gregan Brewspewer
|
||||
SDCategory: Feralas
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "SpellScript.h"
|
||||
#include "Player.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
/*######
|
||||
## npc_gregan_brewspewer
|
||||
######*/
|
||||
|
||||
#define GOSSIP_HELLO "Buy somethin', will ya?"
|
||||
|
||||
class npc_gregan_brewspewer : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_gregan_brewspewer() : CreatureScript("npc_gregan_brewspewer") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
if (action == GOSSIP_ACTION_INFO_DEF+1)
|
||||
{
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
|
||||
player->SEND_GOSSIP_MENU(2434, creature->GetGUID());
|
||||
}
|
||||
if (action == GOSSIP_ACTION_TRADE)
|
||||
player->GetSession()->SendListInventory(creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (creature->IsQuestGiver())
|
||||
player->PrepareQuestMenu(creature->GetGUID());
|
||||
|
||||
if (creature->IsVendor() && player->GetQuestStatus(3909) == QUEST_STATUS_INCOMPLETE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
|
||||
player->SEND_GOSSIP_MENU(2433, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_oox22fe
|
||||
######*/
|
||||
|
||||
enum OOX
|
||||
{
|
||||
SAY_OOX_START = 0,
|
||||
SAY_OOX_AGGRO = 1,
|
||||
SAY_OOX_AMBUSH = 2,
|
||||
SAY_OOX_END = 3,
|
||||
|
||||
NPC_YETI = 7848,
|
||||
NPC_GORILLA = 5260,
|
||||
NPC_WOODPAW_REAVER = 5255,
|
||||
NPC_WOODPAW_BRUTE = 5253,
|
||||
NPC_WOODPAW_ALPHA = 5258,
|
||||
NPC_WOODPAW_MYSTIC = 5254,
|
||||
|
||||
QUEST_RESCUE_OOX22FE = 2767,
|
||||
FACTION_ESCORTEE_A = 774,
|
||||
FACTION_ESCORTEE_H = 775
|
||||
};
|
||||
|
||||
class npc_oox22fe : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_oox22fe() : CreatureScript("npc_oox22fe") { }
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_RESCUE_OOX22FE)
|
||||
{
|
||||
creature->AI()->Talk(SAY_OOX_START);
|
||||
//change that the npc is not lying dead on the ground
|
||||
creature->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
|
||||
if (player->GetTeamId() == TEAM_ALLIANCE)
|
||||
creature->setFaction(FACTION_ESCORTEE_A);
|
||||
|
||||
if (player->GetTeamId() == TEAM_HORDE)
|
||||
creature->setFaction(FACTION_ESCORTEE_H);
|
||||
|
||||
if (npc_escortAI* pEscortAI = CAST_AI(npc_oox22fe::npc_oox22feAI, creature->AI()))
|
||||
pEscortAI->Start(true, false, player->GetGUID());
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_oox22feAI(creature);
|
||||
}
|
||||
|
||||
struct npc_oox22feAI : public npc_escortAI
|
||||
{
|
||||
npc_oox22feAI(Creature* creature) : npc_escortAI(creature) { }
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
// First Ambush(3 Yetis)
|
||||
case 11:
|
||||
Talk(SAY_OOX_AMBUSH);
|
||||
me->SummonCreature(NPC_YETI, -4841.01f, 1593.91f, 73.42f, 3.98f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
|
||||
me->SummonCreature(NPC_YETI, -4837.61f, 1568.58f, 78.21f, 3.13f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
|
||||
me->SummonCreature(NPC_YETI, -4841.89f, 1569.95f, 76.53f, 0.68f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
|
||||
break;
|
||||
//Second Ambush(3 Gorillas)
|
||||
case 21:
|
||||
Talk(SAY_OOX_AMBUSH);
|
||||
me->SummonCreature(NPC_GORILLA, -4595.81f, 2005.99f, 53.08f, 3.74f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
|
||||
me->SummonCreature(NPC_GORILLA, -4597.53f, 2008.31f, 52.70f, 3.78f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
|
||||
me->SummonCreature(NPC_GORILLA, -4599.37f, 2010.59f, 52.77f, 3.84f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
|
||||
break;
|
||||
//Third Ambush(4 Gnolls)
|
||||
case 30:
|
||||
Talk(SAY_OOX_AMBUSH);
|
||||
me->SummonCreature(NPC_WOODPAW_REAVER, -4425.14f, 2075.87f, 47.77f, 3.77f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
|
||||
me->SummonCreature(NPC_WOODPAW_BRUTE, -4426.68f, 2077.98f, 47.57f, 3.77f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
|
||||
me->SummonCreature(NPC_WOODPAW_MYSTIC, -4428.33f, 2080.24f, 47.43f, 3.87f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
|
||||
me->SummonCreature(NPC_WOODPAW_ALPHA, -4430.04f, 2075.54f, 46.83f, 3.81f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
|
||||
break;
|
||||
case 37:
|
||||
Talk(SAY_OOX_END);
|
||||
// Award quest credit
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
player->GroupEventHappens(QUEST_RESCUE_OOX22FE, me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (!HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
me->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
//For an small probability the npc says something when he get aggro
|
||||
if (urand(0, 9) > 7)
|
||||
Talk(SAY_OOX_AGGRO);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned)
|
||||
{
|
||||
summoned->AI()->AttackStart(me);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
enum GordunniTrap
|
||||
{
|
||||
GO_GORDUNNI_DIRT_MOUND = 144064,
|
||||
};
|
||||
|
||||
class spell_gordunni_trap : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_gordunni_trap() : SpellScriptLoader("spell_gordunni_trap") { }
|
||||
|
||||
class spell_gordunni_trap_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_gordunni_trap_SpellScript);
|
||||
|
||||
void HandleDummy()
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (GameObject* chest = caster->SummonGameObject(GO_GORDUNNI_DIRT_MOUND, caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0))
|
||||
{
|
||||
chest->SetSpellId(GetSpellInfo()->Id);
|
||||
caster->RemoveGameObject(chest, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnCast += SpellCastFn(spell_gordunni_trap_SpellScript::HandleDummy);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_gordunni_trap_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## AddSC
|
||||
######*/
|
||||
|
||||
void AddSC_feralas()
|
||||
{
|
||||
new npc_gregan_brewspewer();
|
||||
new npc_oox22fe();
|
||||
new spell_gordunni_trap();
|
||||
}
|
||||
@@ -1,714 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Moonglade
|
||||
SD%Complete: 100
|
||||
SDComment: Quest support: 30, 272, 5929, 5930, 10965. Special Flight Paths for Druid class.
|
||||
SDCategory: Moonglade
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_bunthen_plainswind
|
||||
npc_great_bear_spirit
|
||||
npc_silva_filnaveth
|
||||
npc_clintar_spirit
|
||||
npc_clintar_dreamwalker
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "Player.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "Cell.h"
|
||||
#include "CellImpl.h"
|
||||
|
||||
/*######
|
||||
## npc_bunthen_plainswind
|
||||
######*/
|
||||
|
||||
enum Bunthen
|
||||
{
|
||||
QUEST_SEA_LION_HORDE = 30,
|
||||
QUEST_SEA_LION_ALLY = 272,
|
||||
TAXI_PATH_ID_ALLY = 315,
|
||||
TAXI_PATH_ID_HORDE = 316
|
||||
};
|
||||
|
||||
#define GOSSIP_ITEM_THUNDER "I'd like to fly to Thunder Bluff."
|
||||
#define GOSSIP_ITEM_AQ_END "Do you know where I can find Half Pendant of Aquatic Endurance?"
|
||||
|
||||
class npc_bunthen_plainswind : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_bunthen_plainswind() : CreatureScript("npc_bunthen_plainswind") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
switch (action)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF + 1:
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
if (player->getClass() == CLASS_DRUID && player->GetTeamId() == TEAM_HORDE)
|
||||
player->ActivateTaxiPathTo(TAXI_PATH_ID_HORDE);
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 2:
|
||||
player->SEND_GOSSIP_MENU(5373, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 3:
|
||||
player->SEND_GOSSIP_MENU(5376, creature->GetGUID());
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (player->getClass() != CLASS_DRUID)
|
||||
player->SEND_GOSSIP_MENU(4916, creature->GetGUID());
|
||||
else if (player->GetTeamId() != TEAM_HORDE)
|
||||
{
|
||||
if (player->GetQuestStatus(QUEST_SEA_LION_ALLY) == QUEST_STATUS_INCOMPLETE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_END, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
|
||||
player->SEND_GOSSIP_MENU(4917, creature->GetGUID());
|
||||
}
|
||||
else if (player->getClass() == CLASS_DRUID && player->GetTeamId() == TEAM_HORDE)
|
||||
{
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_THUNDER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
|
||||
if (player->GetQuestStatus(QUEST_SEA_LION_HORDE) == QUEST_STATUS_INCOMPLETE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_END, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
|
||||
player->SEND_GOSSIP_MENU(4918, creature->GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_great_bear_spirit
|
||||
######*/
|
||||
|
||||
#define GOSSIP_BEAR1 "What do you represent, spirit?"
|
||||
#define GOSSIP_BEAR2 "I seek to understand the importance of strength of the body."
|
||||
#define GOSSIP_BEAR3 "I seek to understand the importance of strength of the heart."
|
||||
#define GOSSIP_BEAR4 "I have heard your words, Great Bear Spirit, and I understand. I now seek your blessings to fully learn the way of the Claw."
|
||||
|
||||
class npc_great_bear_spirit : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_great_bear_spirit() : CreatureScript("npc_great_bear_spirit") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
switch (action)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
player->SEND_GOSSIP_MENU(4721, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 1:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
player->SEND_GOSSIP_MENU(4733, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 2:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
player->SEND_GOSSIP_MENU(4734, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 3:
|
||||
player->SEND_GOSSIP_MENU(4735, creature->GetGUID());
|
||||
if (player->GetQuestStatus(5929) == QUEST_STATUS_INCOMPLETE)
|
||||
player->AreaExploredOrEventHappens(5929);
|
||||
if (player->GetQuestStatus(5930) == QUEST_STATUS_INCOMPLETE)
|
||||
player->AreaExploredOrEventHappens(5930);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
//ally or horde quest
|
||||
if (player->GetQuestStatus(5929) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(5930) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||
player->SEND_GOSSIP_MENU(4719, creature->GetGUID());
|
||||
}
|
||||
else
|
||||
player->SEND_GOSSIP_MENU(4718, creature->GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_silva_filnaveth
|
||||
######*/
|
||||
|
||||
#define GOSSIP_ITEM_RUTHERAN "I'd like to fly to Rut'theran Village."
|
||||
#define GOSSIP_ITEM_AQ_AGI "Do you know where I can find Half Pendant of Aquatic Agility?"
|
||||
|
||||
class npc_silva_filnaveth : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_silva_filnaveth() : CreatureScript("npc_silva_filnaveth") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
switch (action)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF + 1:
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
if (player->getClass() == CLASS_DRUID && player->GetTeamId() == TEAM_ALLIANCE)
|
||||
player->ActivateTaxiPathTo(TAXI_PATH_ID_ALLY);
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 2:
|
||||
player->SEND_GOSSIP_MENU(5374, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 3:
|
||||
player->SEND_GOSSIP_MENU(5375, creature->GetGUID());
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (player->getClass() != CLASS_DRUID)
|
||||
player->SEND_GOSSIP_MENU(4913, creature->GetGUID());
|
||||
else if (player->GetTeamId() != TEAM_ALLIANCE)
|
||||
{
|
||||
if (player->GetQuestStatus(QUEST_SEA_LION_HORDE) == QUEST_STATUS_INCOMPLETE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_AGI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
|
||||
player->SEND_GOSSIP_MENU(4915, creature->GetGUID());
|
||||
}
|
||||
else if (player->getClass() == CLASS_DRUID && player->GetTeamId() == TEAM_ALLIANCE)
|
||||
{
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_RUTHERAN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
|
||||
if (player->GetQuestStatus(QUEST_SEA_LION_ALLY) == QUEST_STATUS_INCOMPLETE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_AGI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
|
||||
player->SEND_GOSSIP_MENU(4914, creature->GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_clintar_spirit
|
||||
######*/
|
||||
|
||||
float const Clintar_spirit_WP[41][5] =
|
||||
{
|
||||
//pos_x pos_y pos_z orien waitTime
|
||||
{7465.28f, -3115.46f, 439.327f, 0.83f, 4000},
|
||||
{7476.49f, -3101, 443.457f, 0.89f, 0},
|
||||
{7486.57f, -3085.59f, 439.478f, 1.07f, 0},
|
||||
{7472.19f, -3085.06f, 443.142f, 3.07f, 0},
|
||||
{7456.92f, -3085.91f, 438.862f, 3.24f, 0},
|
||||
{7446.68f, -3083.43f, 438.245f, 2.40f, 0},
|
||||
{7446.17f, -3080.21f, 439.826f, 1.10f, 6000},
|
||||
{7452.41f, -3085.8f, 438.984f, 5.78f, 0},
|
||||
{7469.11f, -3084.94f, 443.048f, 6.25f, 0},
|
||||
{7483.79f, -3085.44f, 439.607f, 6.25f, 0},
|
||||
{7491.14f, -3090.96f, 439.983f, 5.44f, 0},
|
||||
{7497.62f, -3098.22f, 436.854f, 5.44f, 0},
|
||||
{7498.72f, -3113.41f, 434.596f, 4.84f, 0},
|
||||
{7500.06f, -3122.51f, 434.749f, 5.17f, 0},
|
||||
{7504.96f, -3131.53f, 434.475f, 4.74f, 0},
|
||||
{7504.31f, -3133.53f, 435.693f, 3.84f, 6000},
|
||||
{7504.55f, -3133.27f, 435.476f, 0.68f, 15000},
|
||||
{7501.99f, -3126.01f, 434.93f, 1.83f, 0},
|
||||
{7490.76f, -3114.97f, 434.431f, 2.51f, 0},
|
||||
{7479.64f, -3105.51f, 431.123f, 1.83f, 0},
|
||||
{7474.63f, -3086.59f, 428.994f, 1.83f, 2000},
|
||||
{7472.96f, -3074.18f, 427.566f, 1.57f, 0},
|
||||
{7472.25f, -3063, 428.268f, 1.55f, 0},
|
||||
{7473.46f, -3054.22f, 427.588f, 0.36f, 0},
|
||||
{7475.08f, -3053.6f, 428.653f, 0.36f, 6000},
|
||||
{7474.66f, -3053.56f, 428.433f, 3.19f, 4000},
|
||||
{7471.81f, -3058.84f, 427.073f, 4.29f, 0},
|
||||
{7472.16f, -3064.91f, 427.772f, 4.95f, 0},
|
||||
{7471.56f, -3085.36f, 428.924f, 4.72f, 0},
|
||||
{7473.56f, -3093.48f, 429.294f, 5.04f, 0},
|
||||
{7478.94f, -3104.29f, 430.638f, 5.23f, 0},
|
||||
{7484.46f, -3109.61f, 432.769f, 5.79f, 0},
|
||||
{7490.23f, -3111.08f, 434.431f, 0.02f, 0},
|
||||
{7496.29f, -3108, 434.783f, 1.15f, 0},
|
||||
{7497.46f, -3100.66f, 436.191f, 1.50f, 0},
|
||||
{7495.64f, -3093.39f, 438.349f, 2.10f, 0},
|
||||
{7492.44f, -3086.01f, 440.267f, 1.38f, 0},
|
||||
{7498.26f, -3076.44f, 440.808f, 0.71f, 0},
|
||||
{7506.4f, -3067.35f, 443.64f, 0.77f, 0},
|
||||
{7518.37f, -3057.42f, 445.584f, 0.74f, 0},
|
||||
{7517.51f, -3056.3f, 444.568f, 2.49f, 4500}
|
||||
};
|
||||
|
||||
Position const AspectRavenSummon = {7472.96f, -3074.18f, 427.566f, 0.0f};
|
||||
Position const ClintarSpiritSummon = {7459.2275f, -3122.5632f, 438.9842f, 0.8594f};
|
||||
|
||||
enum ClintarSpirit
|
||||
{
|
||||
ASPECT_RAVEN = 22915,
|
||||
|
||||
// Texts for EnterCombat, the event and the end of the event are missing
|
||||
CLINTAR_SPIRIT_SAY_START = 0,
|
||||
};
|
||||
|
||||
class npc_clintar_spirit : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_clintar_spirit() : CreatureScript("npc_clintar_spirit") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_clintar_spiritAI(creature);
|
||||
}
|
||||
|
||||
struct npc_clintar_spiritAI : public npc_escortAI
|
||||
{
|
||||
public:
|
||||
npc_clintar_spiritAI(Creature* creature) : npc_escortAI(creature)
|
||||
{
|
||||
PlayerGUID = 0;
|
||||
}
|
||||
|
||||
uint8 Step;
|
||||
uint32 CurrWP;
|
||||
uint32 EventTimer;
|
||||
uint32 checkPlayerTimer;
|
||||
|
||||
uint64 PlayerGUID;
|
||||
|
||||
bool EventOnWait;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (!PlayerGUID)
|
||||
{
|
||||
Step = 0;
|
||||
CurrWP = 0;
|
||||
EventTimer = 0;
|
||||
PlayerGUID = 0;
|
||||
checkPlayerTimer = 1000;
|
||||
EventOnWait = false;
|
||||
}
|
||||
}
|
||||
|
||||
void IsSummonedBy(Unit* /*summoner*/)
|
||||
{
|
||||
std::list<Player*> playerOnQuestList;
|
||||
Trinity::AnyPlayerInObjectRangeCheck checker(me, 5.0f);
|
||||
Trinity::PlayerListSearcher<Trinity::AnyPlayerInObjectRangeCheck> searcher(me, playerOnQuestList, checker);
|
||||
me->VisitNearbyWorldObject(5.0f, searcher);
|
||||
for (std::list<Player*>::const_iterator itr = playerOnQuestList.begin(); itr != playerOnQuestList.end(); ++itr)
|
||||
{
|
||||
// Check if found player target has active quest
|
||||
if (Player* player = (*itr))
|
||||
{
|
||||
if (player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
StartEvent(player);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (!PlayerGUID)
|
||||
return;
|
||||
|
||||
Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID);
|
||||
if (player && player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
player->FailQuest(10965);
|
||||
PlayerGUID = 0;
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID);
|
||||
if (player && player->IsInCombat() && player->getAttackerForHelper())
|
||||
{
|
||||
AttackStart(player->getAttackerForHelper());
|
||||
return;
|
||||
}
|
||||
npc_escortAI::EnterEvadeMode();
|
||||
}
|
||||
|
||||
void StartEvent(Player* player)
|
||||
{
|
||||
if (player && player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
for (uint8 i = 0; i < 41; ++i)
|
||||
{
|
||||
AddWaypoint(i, Clintar_spirit_WP[i][0], Clintar_spirit_WP[i][1], Clintar_spirit_WP[i][2], (uint32)Clintar_spirit_WP[i][4]);
|
||||
}
|
||||
PlayerGUID = player->GetGUID();
|
||||
Start(true, false, PlayerGUID);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
|
||||
if (!PlayerGUID)
|
||||
{
|
||||
me->setDeathState(JUST_DIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!me->IsInCombat() && !EventOnWait)
|
||||
{
|
||||
if (checkPlayerTimer <= diff)
|
||||
{
|
||||
Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID);
|
||||
if (player && player->IsInCombat() && player->getAttackerForHelper())
|
||||
AttackStart(player->getAttackerForHelper());
|
||||
checkPlayerTimer = 1000;
|
||||
} else checkPlayerTimer -= diff;
|
||||
}
|
||||
|
||||
if (EventOnWait && EventTimer <= diff)
|
||||
{
|
||||
Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID);
|
||||
if (!player || player->GetQuestStatus(10965) == QUEST_STATUS_NONE)
|
||||
{
|
||||
me->setDeathState(JUST_DIED);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (CurrWP)
|
||||
{
|
||||
case 0:
|
||||
switch (Step)
|
||||
{
|
||||
case 0:
|
||||
Talk(CLINTAR_SPIRIT_SAY_START, player);
|
||||
EventTimer = 8000;
|
||||
Step = 1;
|
||||
break;
|
||||
case 1:
|
||||
EventOnWait = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
switch (Step)
|
||||
{
|
||||
case 0:
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133);
|
||||
EventTimer = 5000;
|
||||
Step = 1;
|
||||
break;
|
||||
case 1:
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
|
||||
// Needs text
|
||||
EventOnWait = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
switch (Step)
|
||||
{
|
||||
case 0:
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133);
|
||||
EventTimer = 5000;
|
||||
Step = 1;
|
||||
break;
|
||||
case 1:
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
|
||||
EventOnWait = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
switch (Step)
|
||||
{
|
||||
case 0:
|
||||
// Needs text
|
||||
EventTimer = 15000;
|
||||
Step = 1;
|
||||
break;
|
||||
case 1:
|
||||
EventOnWait = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 20:
|
||||
switch (Step)
|
||||
{
|
||||
case 0:
|
||||
if (Creature* mob = me->SummonCreature(ASPECT_RAVEN, AspectRavenSummon, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000))
|
||||
{
|
||||
mob->AddThreat(me, 10000.0f);
|
||||
mob->AI()->AttackStart(me);
|
||||
}
|
||||
EventTimer = 2000;
|
||||
Step = 1;
|
||||
break;
|
||||
case 1:
|
||||
EventOnWait = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
switch (Step)
|
||||
{
|
||||
case 0:
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133);
|
||||
EventTimer = 5000;
|
||||
Step = 1;
|
||||
break;
|
||||
case 1:
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
|
||||
EventOnWait = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 25:
|
||||
switch (Step)
|
||||
{
|
||||
case 0:
|
||||
// Needs text
|
||||
EventTimer = 4000;
|
||||
Step = 1;
|
||||
break;
|
||||
case 1:
|
||||
EventOnWait = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 40:
|
||||
switch (Step)
|
||||
{
|
||||
case 0:
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 2);
|
||||
// Needs text
|
||||
player->CompleteQuest(10965);
|
||||
EventTimer = 1500;
|
||||
Step = 1;
|
||||
break;
|
||||
case 1:
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
|
||||
EventTimer = 3000;
|
||||
Step = 2;
|
||||
break;
|
||||
case 2:
|
||||
player->TalkedToCreature(me->GetEntry(), me->GetGUID());
|
||||
PlayerGUID = 0;
|
||||
Reset();
|
||||
me->setDeathState(JUST_DIED);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
EventOnWait = false;
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (EventOnWait) EventTimer -= diff;
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
CurrWP = waypointId;
|
||||
EventTimer = 0;
|
||||
Step = 0;
|
||||
EventOnWait = true;
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/*####
|
||||
# npc_omen
|
||||
####*/
|
||||
|
||||
enum Omen
|
||||
{
|
||||
NPC_OMEN = 15467,
|
||||
|
||||
SPELL_OMEN_CLEAVE = 15284,
|
||||
SPELL_OMEN_STARFALL = 26540,
|
||||
SPELL_OMEN_SUMMON_SPOTLIGHT = 26392,
|
||||
SPELL_ELUNE_CANDLE = 26374,
|
||||
|
||||
GO_ELUNE_TRAP_1 = 180876,
|
||||
GO_ELUNE_TRAP_2 = 180877,
|
||||
|
||||
EVENT_CAST_CLEAVE = 1,
|
||||
EVENT_CAST_STARFALL = 2,
|
||||
EVENT_DESPAWN = 3,
|
||||
};
|
||||
|
||||
class npc_omen : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_omen() : CreatureScript("npc_omen") { }
|
||||
|
||||
struct npc_omenAI : public ScriptedAI
|
||||
{
|
||||
npc_omenAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
|
||||
me->GetMotionMaster()->MovePoint(1, 7549.977f, -2855.137f, 456.9678f);
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
|
||||
void MovementInform(uint32 type, uint32 pointId)
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (pointId == 1)
|
||||
{
|
||||
me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
|
||||
if (Player* player = me->SelectNearestPlayer(40.0f))
|
||||
AttackStart(player);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*attacker*/)
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_CAST_CLEAVE, urand(3000, 5000));
|
||||
events.ScheduleEvent(EVENT_CAST_STARFALL, urand(8000, 10000));
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
DoCast(SPELL_OMEN_SUMMON_SPOTLIGHT);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, const SpellInfo* spell)
|
||||
{
|
||||
if (spell->Id == SPELL_ELUNE_CANDLE)
|
||||
{
|
||||
if (me->HasAura(SPELL_OMEN_STARFALL))
|
||||
me->RemoveAurasDueToSpell(SPELL_OMEN_STARFALL);
|
||||
|
||||
events.RescheduleEvent(EVENT_CAST_STARFALL, urand(14000, 16000));
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CAST_CLEAVE:
|
||||
DoCastVictim(SPELL_OMEN_CLEAVE);
|
||||
events.ScheduleEvent(EVENT_CAST_CLEAVE, urand(8000, 10000));
|
||||
break;
|
||||
case EVENT_CAST_STARFALL:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_OMEN_STARFALL);
|
||||
events.ScheduleEvent(EVENT_CAST_STARFALL, urand(14000, 16000));
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_omenAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_giant_spotlight : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_giant_spotlight() : CreatureScript("npc_giant_spotlight") { }
|
||||
|
||||
struct npc_giant_spotlightAI : public ScriptedAI
|
||||
{
|
||||
npc_giant_spotlightAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_DESPAWN, 5*MINUTE*IN_MILLISECONDS);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
if (events.ExecuteEvent() == EVENT_DESPAWN)
|
||||
{
|
||||
if (GameObject* trap = me->FindNearestGameObject(GO_ELUNE_TRAP_1, 5.0f))
|
||||
trap->RemoveFromWorld();
|
||||
|
||||
if (GameObject* trap = me->FindNearestGameObject(GO_ELUNE_TRAP_2, 5.0f))
|
||||
trap->RemoveFromWorld();
|
||||
|
||||
if (Creature* omen = me->FindNearestCreature(NPC_OMEN, 5.0f, false))
|
||||
omen->DespawnOrUnsummon();
|
||||
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_giant_spotlightAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_moonglade()
|
||||
{
|
||||
new npc_bunthen_plainswind();
|
||||
new npc_great_bear_spirit();
|
||||
new npc_silva_filnaveth();
|
||||
new npc_clintar_spirit();
|
||||
new npc_omen();
|
||||
new npc_giant_spotlight();
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "ScriptedGossip.h"
|
||||
#include "Player.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
void AddSC_mulgore()
|
||||
{
|
||||
}
|
||||
@@ -1,254 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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"
|
||||
|
||||
/*######
|
||||
## 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)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_SHATTERED_SALUTE)
|
||||
{
|
||||
CAST_AI(npc_shenthul::npc_shenthulAI, creature->AI())->CanTalk = true;
|
||||
CAST_AI(npc_shenthul::npc_shenthulAI, creature->AI())->PlayerGUID = player->GetGUID();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_shenthulAI(creature);
|
||||
}
|
||||
|
||||
struct npc_shenthulAI : public ScriptedAI
|
||||
{
|
||||
npc_shenthulAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
bool CanTalk;
|
||||
bool CanEmote;
|
||||
uint32 SaluteTimer;
|
||||
uint32 ResetTimer;
|
||||
uint64 PlayerGUID;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
CanTalk = false;
|
||||
CanEmote = false;
|
||||
SaluteTimer = 6000;
|
||||
ResetTimer = 0;
|
||||
PlayerGUID = 0;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
QUEST_6566 = 6566,
|
||||
|
||||
SPELL_CHAIN_LIGHTNING = 16033,
|
||||
SPELL_SHOCK = 16034
|
||||
};
|
||||
|
||||
#define GOSSIP_HTW "Please share your wisdom with me, Warchief."
|
||||
#define GOSSIP_STW1 "What discoveries?"
|
||||
#define GOSSIP_STW2 "Usurper?"
|
||||
#define GOSSIP_STW3 "With all due respect, Warchief - why not allow them to be destroyed? Does this not strengthen our position?"
|
||||
#define GOSSIP_STW4 "I... I did not think of it that way, Warchief."
|
||||
#define GOSSIP_STW5 "I live only to serve, Warchief! My life is empty and meaningless without your guidance."
|
||||
#define GOSSIP_STW6 "Of course, Warchief!"
|
||||
|
||||
/// @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)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
switch (action)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF+1:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
|
||||
player->SEND_GOSSIP_MENU(5733, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+2:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
|
||||
player->SEND_GOSSIP_MENU(5734, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+3:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
|
||||
player->SEND_GOSSIP_MENU(5735, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+4:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5);
|
||||
player->SEND_GOSSIP_MENU(5736, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+5:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6);
|
||||
player->SEND_GOSSIP_MENU(5737, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+6:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7);
|
||||
player->SEND_GOSSIP_MENU(5738, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+7:
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
player->AreaExploredOrEventHappens(QUEST_6566);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (creature->IsQuestGiver())
|
||||
player->PrepareQuestMenu(creature->GetGUID());
|
||||
|
||||
if (player->GetQuestStatus(QUEST_6566) == QUEST_STATUS_INCOMPLETE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HTW, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
|
||||
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_thrall_warchiefAI(creature);
|
||||
}
|
||||
|
||||
struct npc_thrall_warchiefAI : public ScriptedAI
|
||||
{
|
||||
npc_thrall_warchiefAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 ChainLightningTimer;
|
||||
uint32 ShockTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
ChainLightningTimer = 2000;
|
||||
ShockTimer = 8000;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_orgrimmar()
|
||||
{
|
||||
new npc_shenthul();
|
||||
new npc_thrall_warchief();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Stonetalon_Mountains
|
||||
SD%Complete: 95
|
||||
SDComment: Quest support: 6627, 6523
|
||||
SDCategory: Stonetalon Mountains
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_braug_dimspirit
|
||||
npc_kaya_flathoof
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "Player.h"
|
||||
|
||||
/*######
|
||||
## npc_braug_dimspirit
|
||||
######*/
|
||||
|
||||
#define GOSSIP_HBD1 "Ysera"
|
||||
#define GOSSIP_HBD2 "Neltharion"
|
||||
#define GOSSIP_HBD3 "Nozdormu"
|
||||
#define GOSSIP_HBD4 "Alexstrasza"
|
||||
#define GOSSIP_HBD5 "Malygos"
|
||||
|
||||
class npc_braug_dimspirit : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_braug_dimspirit() : CreatureScript("npc_braug_dimspirit") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
if (action == GOSSIP_ACTION_INFO_DEF+1)
|
||||
{
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
creature->CastSpell(player, 6766, false);
|
||||
|
||||
}
|
||||
if (action == GOSSIP_ACTION_INFO_DEF+2)
|
||||
{
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
player->AreaExploredOrEventHappens(6627);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (creature->IsQuestGiver())
|
||||
player->PrepareQuestMenu(creature->GetGUID());
|
||||
|
||||
if (player->GetQuestStatus(6627) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
|
||||
player->SEND_GOSSIP_MENU(5820, creature->GetGUID());
|
||||
}
|
||||
else
|
||||
player->SEND_GOSSIP_MENU(5819, creature->GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_kaya_flathoof
|
||||
######*/
|
||||
|
||||
enum Kaya
|
||||
{
|
||||
FACTION_ESCORTEE_H = 775,
|
||||
|
||||
NPC_GRIMTOTEM_RUFFIAN = 11910,
|
||||
NPC_GRIMTOTEM_BRUTE = 11912,
|
||||
NPC_GRIMTOTEM_SORCERER = 11913,
|
||||
|
||||
SAY_START = 0,
|
||||
SAY_AMBUSH = 1,
|
||||
SAY_END = 2,
|
||||
|
||||
QUEST_PROTECT_KAYA = 6523
|
||||
};
|
||||
|
||||
class npc_kaya_flathoof : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_kaya_flathoof() : CreatureScript("npc_kaya_flathoof") { }
|
||||
|
||||
struct npc_kaya_flathoofAI : public npc_escortAI
|
||||
{
|
||||
npc_kaya_flathoofAI(Creature* creature) : npc_escortAI(creature) {}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
Player* player = GetPlayerForEscort();
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
switch (waypointId)
|
||||
{
|
||||
case 16:
|
||||
Talk(SAY_AMBUSH);
|
||||
me->SummonCreature(NPC_GRIMTOTEM_BRUTE, -48.53f, -503.34f, -46.31f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||
me->SummonCreature(NPC_GRIMTOTEM_RUFFIAN, -38.85f, -503.77f, -45.90f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||
me->SummonCreature(NPC_GRIMTOTEM_SORCERER, -36.37f, -496.23f, -45.71f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||
break;
|
||||
case 18:
|
||||
me->SetFacingToObject(player);
|
||||
Talk(SAY_END);
|
||||
player->GroupEventHappens(QUEST_PROTECT_KAYA, me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned)
|
||||
{
|
||||
summoned->AI()->AttackStart(me);
|
||||
}
|
||||
|
||||
void Reset(){}
|
||||
};
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_PROTECT_KAYA)
|
||||
{
|
||||
if (npc_escortAI* pEscortAI = CAST_AI(npc_kaya_flathoof::npc_kaya_flathoofAI, creature->AI()))
|
||||
pEscortAI->Start(true, false, player->GetGUID());
|
||||
|
||||
creature->AI()->Talk(SAY_START);
|
||||
creature->setFaction(113);
|
||||
creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_kaya_flathoofAI(creature);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
## AddSC
|
||||
######*/
|
||||
|
||||
void AddSC_stonetalon_mountains()
|
||||
{
|
||||
new npc_braug_dimspirit();
|
||||
new npc_kaya_flathoof();
|
||||
}
|
||||
@@ -1,654 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Tanaris
|
||||
SD%Complete: 80
|
||||
SDComment: Quest support: 648, 1560, 2954, 4005, 10277, 10279(Special flight path). Noggenfogger vendor
|
||||
SDCategory: Tanaris
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_aquementas
|
||||
npc_custodian_of_time
|
||||
npc_steward_of_time
|
||||
npc_stone_watcher_of_norgannon
|
||||
npc_OOX17
|
||||
npc_tooga
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "ScriptedFollowerAI.h"
|
||||
#include "Player.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
/*######
|
||||
## npc_aquementas
|
||||
######*/
|
||||
|
||||
enum Aquementas
|
||||
{
|
||||
AGGRO_YELL_AQUE = 0,
|
||||
|
||||
SPELL_AQUA_JET = 13586,
|
||||
SPELL_FROST_SHOCK = 15089
|
||||
};
|
||||
|
||||
class npc_aquementas : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_aquementas() : CreatureScript("npc_aquementas") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_aquementasAI(creature);
|
||||
}
|
||||
|
||||
struct npc_aquementasAI : public ScriptedAI
|
||||
{
|
||||
npc_aquementasAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 SendItemTimer;
|
||||
uint32 SwitchFactionTimer;
|
||||
bool isFriendly;
|
||||
|
||||
uint32 FrostShockTimer;
|
||||
uint32 AquaJetTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
SendItemTimer = 0;
|
||||
SwitchFactionTimer = 10000;
|
||||
me->setFaction(35);
|
||||
isFriendly = true;
|
||||
|
||||
AquaJetTimer = 5000;
|
||||
FrostShockTimer = 1000;
|
||||
}
|
||||
|
||||
void SendItem(Unit* receiver)
|
||||
{
|
||||
Player* player = receiver->ToPlayer();
|
||||
|
||||
if (player && player->HasItemCount(11169, 1, false) &&
|
||||
player->HasItemCount(11172, 11, false) &&
|
||||
player->HasItemCount(11173, 1, false) &&
|
||||
!player->HasItemCount(11522, 1, true))
|
||||
{
|
||||
ItemPosCountVec dest;
|
||||
uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 11522, 1, NULL);
|
||||
if (msg == EQUIP_ERR_OK)
|
||||
player->StoreNewItem(dest, 11522, 1, true);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
Talk(AGGRO_YELL_AQUE, who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (isFriendly)
|
||||
{
|
||||
if (SwitchFactionTimer <= diff)
|
||||
{
|
||||
me->setFaction(91);
|
||||
isFriendly = false;
|
||||
} else SwitchFactionTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (!isFriendly)
|
||||
{
|
||||
if (SendItemTimer <= diff)
|
||||
{
|
||||
if (me->GetVictim()->GetTypeId() == TYPEID_PLAYER)
|
||||
SendItem(me->GetVictim());
|
||||
SendItemTimer = 5000;
|
||||
} else SendItemTimer -= diff;
|
||||
}
|
||||
|
||||
if (FrostShockTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_FROST_SHOCK);
|
||||
FrostShockTimer = 15000;
|
||||
} else FrostShockTimer -= diff;
|
||||
|
||||
if (AquaJetTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_AQUA_JET);
|
||||
AquaJetTimer = 15000;
|
||||
} else AquaJetTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_custodian_of_time
|
||||
######*/
|
||||
|
||||
enum CustodianOfTime
|
||||
{
|
||||
WHISPER_CUSTODIAN_1 = 0,
|
||||
WHISPER_CUSTODIAN_2 = 1,
|
||||
WHISPER_CUSTODIAN_3 = 2,
|
||||
WHISPER_CUSTODIAN_4 = 3,
|
||||
WHISPER_CUSTODIAN_5 = 4,
|
||||
WHISPER_CUSTODIAN_6 = 5,
|
||||
WHISPER_CUSTODIAN_7 = 6,
|
||||
WHISPER_CUSTODIAN_8 = 7,
|
||||
WHISPER_CUSTODIAN_9 = 8,
|
||||
WHISPER_CUSTODIAN_10 = 9,
|
||||
WHISPER_CUSTODIAN_11 = 10,
|
||||
WHISPER_CUSTODIAN_12 = 11,
|
||||
WHISPER_CUSTODIAN_13 = 12,
|
||||
WHISPER_CUSTODIAN_14 = 13
|
||||
};
|
||||
|
||||
class npc_custodian_of_time : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_custodian_of_time() : CreatureScript("npc_custodian_of_time") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_custodian_of_timeAI(creature);
|
||||
}
|
||||
|
||||
struct npc_custodian_of_timeAI : public npc_escortAI
|
||||
{
|
||||
npc_custodian_of_timeAI(Creature* creature) : npc_escortAI(creature) { }
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 0:
|
||||
Talk(WHISPER_CUSTODIAN_1, player);
|
||||
break;
|
||||
case 1:
|
||||
Talk(WHISPER_CUSTODIAN_2, player);
|
||||
break;
|
||||
case 2:
|
||||
Talk(WHISPER_CUSTODIAN_3, player);
|
||||
break;
|
||||
case 3:
|
||||
Talk(WHISPER_CUSTODIAN_4, player);
|
||||
break;
|
||||
case 5:
|
||||
Talk(WHISPER_CUSTODIAN_5, player);
|
||||
break;
|
||||
case 6:
|
||||
Talk(WHISPER_CUSTODIAN_6, player);
|
||||
break;
|
||||
case 7:
|
||||
Talk(WHISPER_CUSTODIAN_7, player);
|
||||
break;
|
||||
case 8:
|
||||
Talk(WHISPER_CUSTODIAN_8, player);
|
||||
break;
|
||||
case 9:
|
||||
Talk(WHISPER_CUSTODIAN_9, player);
|
||||
break;
|
||||
case 10:
|
||||
Talk(WHISPER_CUSTODIAN_4, player);
|
||||
break;
|
||||
case 13:
|
||||
Talk(WHISPER_CUSTODIAN_10, player);
|
||||
break;
|
||||
case 14:
|
||||
Talk(WHISPER_CUSTODIAN_4, player);
|
||||
break;
|
||||
case 16:
|
||||
Talk(WHISPER_CUSTODIAN_11, player);
|
||||
break;
|
||||
case 17:
|
||||
Talk(WHISPER_CUSTODIAN_12, player);
|
||||
break;
|
||||
case 18:
|
||||
Talk(WHISPER_CUSTODIAN_4, player);
|
||||
break;
|
||||
case 22:
|
||||
Talk(WHISPER_CUSTODIAN_13, player);
|
||||
break;
|
||||
case 23:
|
||||
Talk(WHISPER_CUSTODIAN_4, player);
|
||||
break;
|
||||
case 24:
|
||||
Talk(WHISPER_CUSTODIAN_14, player);
|
||||
DoCast(player, 34883);
|
||||
// below here is temporary workaround, to be removed when spell works properly
|
||||
player->AreaExploredOrEventHappens(10277);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
|
||||
{
|
||||
if (HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
return;
|
||||
|
||||
if (Player* player = who->ToPlayer())
|
||||
{
|
||||
if (who->HasAura(34877) && player->GetQuestStatus(10277) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
float Radius = 10.0f;
|
||||
if (me->IsWithinDistInMap(who, Radius))
|
||||
{
|
||||
Start(false, false, who->GetGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
void Reset() { }
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_steward_of_time
|
||||
######*/
|
||||
|
||||
#define GOSSIP_ITEM_FLIGHT "Please take me to the master's lair."
|
||||
|
||||
class npc_steward_of_time : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_steward_of_time() : CreatureScript("npc_steward_of_time") { }
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* /*creature*/, Quest const* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == 10279) //Quest: To The Master's Lair
|
||||
player->CastSpell(player, 34891, true); //(Flight through Caverns)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
if (action == GOSSIP_ACTION_INFO_DEF + 1)
|
||||
player->CastSpell(player, 34891, true); //(Flight through Caverns)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (creature->IsQuestGiver())
|
||||
player->PrepareQuestMenu(creature->GetGUID());
|
||||
|
||||
if (player->GetQuestStatus(10279) == QUEST_STATUS_INCOMPLETE || player->GetQuestRewardStatus(10279))
|
||||
{
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_FLIGHT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
player->SEND_GOSSIP_MENU(9978, creature->GetGUID());
|
||||
}
|
||||
else
|
||||
player->SEND_GOSSIP_MENU(9977, creature->GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_stone_watcher_of_norgannon
|
||||
######*/
|
||||
|
||||
#define GOSSIP_ITEM_NORGANNON_1 "What function do you serve?"
|
||||
#define GOSSIP_ITEM_NORGANNON_2 "What are the Plates of Uldum?"
|
||||
#define GOSSIP_ITEM_NORGANNON_3 "Where are the Plates of Uldum?"
|
||||
#define GOSSIP_ITEM_NORGANNON_4 "Excuse me? We've been \"reschedueled for visitations\"? What does that mean?!"
|
||||
#define GOSSIP_ITEM_NORGANNON_5 "So, what's inside Uldum?"
|
||||
#define GOSSIP_ITEM_NORGANNON_6 "I will return when i have the Plates of Uldum."
|
||||
|
||||
class npc_stone_watcher_of_norgannon : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_stone_watcher_of_norgannon() : CreatureScript("npc_stone_watcher_of_norgannon") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
switch (action)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
player->SEND_GOSSIP_MENU(1675, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+1:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
|
||||
player->SEND_GOSSIP_MENU(1676, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+2:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
|
||||
player->SEND_GOSSIP_MENU(1677, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+3:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
|
||||
player->SEND_GOSSIP_MENU(1678, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+4:
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5);
|
||||
player->SEND_GOSSIP_MENU(1679, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+5:
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
player->AreaExploredOrEventHappens(2954);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (creature->IsQuestGiver())
|
||||
player->PrepareQuestMenu(creature->GetGUID());
|
||||
|
||||
if (player->GetQuestStatus(2954) == QUEST_STATUS_INCOMPLETE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||
|
||||
player->SEND_GOSSIP_MENU(1674, creature->GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_OOX17
|
||||
######*/
|
||||
|
||||
enum Npc00X17
|
||||
{
|
||||
SAY_OOX_START = 0,
|
||||
SAY_OOX_AGGRO = 1,
|
||||
SAY_OOX_AMBUSH = 2,
|
||||
SAY_OOX17_AMBUSH_REPLY = 0,
|
||||
SAY_OOX_END = 3,
|
||||
|
||||
Q_OOX17 = 648,
|
||||
SPAWN_FIRST = 7803,
|
||||
SPAWN_SECOND_1 = 5617,
|
||||
SPAWN_SECOND_2 = 7805
|
||||
};
|
||||
|
||||
class npc_OOX17 : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_OOX17() : CreatureScript("npc_OOX17") { }
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == Q_OOX17)
|
||||
{
|
||||
creature->setFaction(113);
|
||||
creature->SetFullHealth();
|
||||
creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
|
||||
creature->AI()->Talk(SAY_OOX_START);
|
||||
|
||||
if (npc_escortAI* pEscortAI = CAST_AI(npc_OOX17::npc_OOX17AI, creature->AI()))
|
||||
pEscortAI->Start(true, false, player->GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_OOX17AI(creature);
|
||||
}
|
||||
|
||||
struct npc_OOX17AI : public npc_escortAI
|
||||
{
|
||||
npc_OOX17AI(Creature* creature) : npc_escortAI(creature) { }
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 23:
|
||||
me->SummonCreature(SPAWN_FIRST, -8350.96f, -4445.79f, 10.10f, 6.20f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
|
||||
me->SummonCreature(SPAWN_FIRST, -8355.96f, -4447.79f, 10.10f, 6.27f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
|
||||
me->SummonCreature(SPAWN_FIRST, -8353.96f, -4442.79f, 10.10f, 6.08f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
|
||||
Talk(SAY_OOX_AMBUSH);
|
||||
break;
|
||||
case 56:
|
||||
me->SummonCreature(SPAWN_SECOND_1, -7510.07f, -4795.50f, 9.35f, 6.06f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
|
||||
me->SummonCreature(SPAWN_SECOND_2, -7515.07f, -4797.50f, 9.35f, 6.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
|
||||
me->SummonCreature(SPAWN_SECOND_2, -7518.07f, -4792.50f, 9.35f, 6.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
|
||||
Talk(SAY_OOX_AMBUSH);
|
||||
if (Creature* scoff = me->FindNearestCreature(SPAWN_SECOND_2, 30))
|
||||
scoff->AI()->Talk(SAY_OOX17_AMBUSH_REPLY);
|
||||
break;
|
||||
case 86:
|
||||
Talk(SAY_OOX_END);
|
||||
player->GroupEventHappens(Q_OOX17, me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() { }
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_OOX_AGGRO);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned)
|
||||
{
|
||||
summoned->AI()->AttackStart(me);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/*####
|
||||
# npc_tooga
|
||||
####*/
|
||||
|
||||
enum Tooga
|
||||
{
|
||||
SAY_TOOG_WORRIED = 0,
|
||||
SAY_TOOG_POST_1 = 1,
|
||||
SAY_TORT_POST_2 = 0,
|
||||
SAY_TOOG_POST_3 = 2,
|
||||
SAY_TORT_POST_4 = 1,
|
||||
SAY_TOOG_POST_5 = 3,
|
||||
SAY_TORT_POST_6 = 2,
|
||||
|
||||
QUEST_TOOGA = 1560,
|
||||
NPC_TORTA = 6015,
|
||||
|
||||
POINT_ID_TO_WATER = 1,
|
||||
FACTION_TOOG_ESCORTEE = 113
|
||||
};
|
||||
|
||||
Position const ToWaterLoc = {-7032.664551f, -4906.199219f, -1.606446f, 0.0f};
|
||||
|
||||
class npc_tooga : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_tooga() : CreatureScript("npc_tooga") { }
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_TOOGA)
|
||||
{
|
||||
if (npc_toogaAI* pToogaAI = CAST_AI(npc_tooga::npc_toogaAI, creature->AI()))
|
||||
pToogaAI->StartFollow(player, FACTION_TOOG_ESCORTEE, quest);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_toogaAI(creature);
|
||||
}
|
||||
|
||||
struct npc_toogaAI : public FollowerAI
|
||||
{
|
||||
npc_toogaAI(Creature* creature) : FollowerAI(creature) { }
|
||||
|
||||
uint32 CheckSpeechTimer;
|
||||
uint32 PostEventTimer;
|
||||
uint32 PhasePostEvent;
|
||||
|
||||
uint64 TortaGUID;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
CheckSpeechTimer = 2500;
|
||||
PostEventTimer = 1000;
|
||||
PhasePostEvent = 0;
|
||||
|
||||
TortaGUID = 0;
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
|
||||
{
|
||||
FollowerAI::MoveInLineOfSight(who);
|
||||
|
||||
if (!me->GetVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE | STATE_FOLLOW_POSTEVENT) && who->GetEntry() == NPC_TORTA)
|
||||
{
|
||||
if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE))
|
||||
{
|
||||
Player* player = GetLeaderForFollower();
|
||||
if (player && player->GetQuestStatus(QUEST_TOOGA) == QUEST_STATUS_INCOMPLETE)
|
||||
player->GroupEventHappens(QUEST_TOOGA, me);
|
||||
|
||||
TortaGUID = who->GetGUID();
|
||||
SetFollowComplete(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 MotionType, uint32 PointId)
|
||||
{
|
||||
FollowerAI::MovementInform(MotionType, PointId);
|
||||
|
||||
if (MotionType != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (PointId == POINT_ID_TO_WATER)
|
||||
SetFollowComplete();
|
||||
}
|
||||
|
||||
void UpdateFollowerAI(uint32 Diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
//we are doing the post-event, or...
|
||||
if (HasFollowState(STATE_FOLLOW_POSTEVENT))
|
||||
{
|
||||
if (PostEventTimer <= Diff)
|
||||
{
|
||||
PostEventTimer = 5000;
|
||||
|
||||
Creature* torta = ObjectAccessor::GetCreature(*me, TortaGUID);
|
||||
if (!torta || !torta->IsAlive())
|
||||
{
|
||||
//something happened, so just complete
|
||||
SetFollowComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (PhasePostEvent)
|
||||
{
|
||||
case 1:
|
||||
Talk(SAY_TOOG_POST_1);
|
||||
break;
|
||||
case 2:
|
||||
torta->AI()->Talk(SAY_TORT_POST_2);
|
||||
break;
|
||||
case 3:
|
||||
Talk(SAY_TOOG_POST_3);
|
||||
break;
|
||||
case 4:
|
||||
torta->AI()->Talk(SAY_TORT_POST_4);
|
||||
break;
|
||||
case 5:
|
||||
Talk(SAY_TOOG_POST_5);
|
||||
break;
|
||||
case 6:
|
||||
torta->AI()->Talk(SAY_TORT_POST_6);
|
||||
me->GetMotionMaster()->MovePoint(POINT_ID_TO_WATER, ToWaterLoc);
|
||||
break;
|
||||
}
|
||||
|
||||
++PhasePostEvent;
|
||||
}
|
||||
else
|
||||
PostEventTimer -= Diff;
|
||||
}
|
||||
//...we are doing regular speech check
|
||||
else if (HasFollowState(STATE_FOLLOW_INPROGRESS))
|
||||
{
|
||||
if (CheckSpeechTimer <= Diff)
|
||||
{
|
||||
CheckSpeechTimer = 5000;
|
||||
|
||||
if (urand(0, 9) > 8)
|
||||
Talk(SAY_TOOG_WORRIED);
|
||||
}
|
||||
else
|
||||
CheckSpeechTimer -= Diff;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_tanaris()
|
||||
{
|
||||
new npc_aquementas();
|
||||
new npc_custodian_of_time();
|
||||
new npc_steward_of_time();
|
||||
new npc_stone_watcher_of_norgannon();
|
||||
new npc_OOX17();
|
||||
new npc_tooga();
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Teldrassil
|
||||
SD%Complete: 100
|
||||
SDComment: Quest support: 938
|
||||
SDCategory: Teldrassil
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_mist
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedFollowerAI.h"
|
||||
#include "Player.h"
|
||||
|
||||
void AddSC_teldrassil()
|
||||
{
|
||||
}
|
||||
@@ -1,672 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: The_Barrens
|
||||
SD%Complete: 90
|
||||
SDComment: Quest support: 863, 898, 1719, 2458, 4921, 6981,
|
||||
SDCategory: Barrens
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_beaten_corpse
|
||||
npc_gilthares
|
||||
npc_sputtervalve
|
||||
npc_taskmaster_fizzule
|
||||
npc_twiggy_flathead
|
||||
npc_wizzlecrank_shredder
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "Player.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
/*######
|
||||
## npc_beaten_corpse
|
||||
######*/
|
||||
|
||||
#define GOSSIP_CORPSE "Examine corpse in detail..."
|
||||
|
||||
enum BeatenCorpse
|
||||
{
|
||||
QUEST_LOST_IN_BATTLE = 4921
|
||||
};
|
||||
|
||||
class npc_beaten_corpse : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_beaten_corpse() : CreatureScript("npc_beaten_corpse") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
if (action == GOSSIP_ACTION_INFO_DEF +1)
|
||||
{
|
||||
player->SEND_GOSSIP_MENU(3558, creature->GetGUID());
|
||||
player->TalkedToCreature(creature->GetEntry(), creature->GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (player->GetQuestStatus(QUEST_LOST_IN_BATTLE) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_LOST_IN_BATTLE) == QUEST_STATUS_COMPLETE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CORPSE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
|
||||
player->SEND_GOSSIP_MENU(3557, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
# npc_gilthares
|
||||
######*/
|
||||
|
||||
enum Gilthares
|
||||
{
|
||||
SAY_GIL_START = 0,
|
||||
SAY_GIL_AT_LAST = 1,
|
||||
SAY_GIL_PROCEED = 2,
|
||||
SAY_GIL_FREEBOOTERS = 3,
|
||||
SAY_GIL_AGGRO = 4,
|
||||
SAY_GIL_ALMOST = 5,
|
||||
SAY_GIL_SWEET = 6,
|
||||
SAY_GIL_FREED = 7,
|
||||
|
||||
QUEST_FREE_FROM_HOLD = 898,
|
||||
AREA_MERCHANT_COAST = 391,
|
||||
FACTION_ESCORTEE = 232 //guessed, possible not needed for this quest
|
||||
};
|
||||
|
||||
class npc_gilthares : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_gilthares() : CreatureScript("npc_gilthares") { }
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_FREE_FROM_HOLD)
|
||||
{
|
||||
creature->setFaction(FACTION_ESCORTEE);
|
||||
creature->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
|
||||
creature->AI()->Talk(SAY_GIL_START, player);
|
||||
|
||||
if (npc_giltharesAI* pEscortAI = CAST_AI(npc_gilthares::npc_giltharesAI, creature->AI()))
|
||||
pEscortAI->Start(false, false, player->GetGUID(), quest);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_giltharesAI(creature);
|
||||
}
|
||||
|
||||
struct npc_giltharesAI : public npc_escortAI
|
||||
{
|
||||
npc_giltharesAI(Creature* creature) : npc_escortAI(creature) { }
|
||||
|
||||
void Reset() { }
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
Player* player = GetPlayerForEscort();
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
switch (waypointId)
|
||||
{
|
||||
case 16:
|
||||
Talk(SAY_GIL_AT_LAST, player);
|
||||
break;
|
||||
case 17:
|
||||
Talk(SAY_GIL_PROCEED, player);
|
||||
break;
|
||||
case 18:
|
||||
Talk(SAY_GIL_FREEBOOTERS, player);
|
||||
break;
|
||||
case 37:
|
||||
Talk(SAY_GIL_ALMOST, player);
|
||||
break;
|
||||
case 47:
|
||||
Talk(SAY_GIL_SWEET, player);
|
||||
break;
|
||||
case 53:
|
||||
Talk(SAY_GIL_FREED, player);
|
||||
player->GroupEventHappens(QUEST_FREE_FROM_HOLD, me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
//not always use
|
||||
if (rand()%4)
|
||||
return;
|
||||
|
||||
//only aggro text if not player and only in this area
|
||||
if (who->GetTypeId() != TYPEID_PLAYER && me->GetAreaId() == AREA_MERCHANT_COAST)
|
||||
{
|
||||
//appears to be pretty much random (possible only if escorter not in combat with who yet?)
|
||||
Talk(SAY_GIL_AGGRO, who);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_taskmaster_fizzule
|
||||
######*/
|
||||
|
||||
enum TaskmasterFizzule
|
||||
{
|
||||
FACTION_FRIENDLY_F = 35,
|
||||
SPELL_FLARE = 10113,
|
||||
SPELL_FOLLY = 10137,
|
||||
};
|
||||
|
||||
class npc_taskmaster_fizzule : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_taskmaster_fizzule() : CreatureScript("npc_taskmaster_fizzule") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_taskmaster_fizzuleAI(creature);
|
||||
}
|
||||
|
||||
struct npc_taskmaster_fizzuleAI : public ScriptedAI
|
||||
{
|
||||
npc_taskmaster_fizzuleAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
factionNorm = creature->getFaction();
|
||||
}
|
||||
|
||||
uint32 factionNorm;
|
||||
bool IsFriend;
|
||||
uint32 ResetTimer;
|
||||
uint8 FlareCount;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
IsFriend = false;
|
||||
ResetTimer = 120000;
|
||||
FlareCount = 0;
|
||||
me->setFaction(factionNorm);
|
||||
}
|
||||
|
||||
void DoFriend()
|
||||
{
|
||||
me->RemoveAllAuras();
|
||||
me->DeleteThreatList();
|
||||
me->CombatStop(true);
|
||||
|
||||
me->StopMoving();
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
|
||||
me->setFaction(FACTION_FRIENDLY_F);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, const SpellInfo* spell)
|
||||
{
|
||||
if (spell->Id == SPELL_FLARE || spell->Id == SPELL_FOLLY)
|
||||
{
|
||||
++FlareCount;
|
||||
|
||||
if (FlareCount >= 2)
|
||||
IsFriend = true;
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (IsFriend)
|
||||
{
|
||||
if (ResetTimer <= diff)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
} else ResetTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void ReceiveEmote(Player* /*player*/, uint32 emote)
|
||||
{
|
||||
if (emote == TEXT_EMOTE_SALUTE)
|
||||
{
|
||||
if (FlareCount >= 2)
|
||||
{
|
||||
if (me->getFaction() == FACTION_FRIENDLY_F)
|
||||
return;
|
||||
|
||||
DoFriend();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/*#####
|
||||
## npc_twiggy_flathead
|
||||
#####*/
|
||||
|
||||
enum TwiggyFlathead
|
||||
{
|
||||
NPC_BIG_WILL = 6238,
|
||||
NPC_AFFRAY_CHALLENGER = 6240,
|
||||
|
||||
SAY_BIG_WILL_READY = 0,
|
||||
SAY_TWIGGY_FLATHEAD_BEGIN = 0,
|
||||
SAY_TWIGGY_FLATHEAD_FRAY = 1,
|
||||
SAY_TWIGGY_FLATHEAD_DOWN = 2,
|
||||
SAY_TWIGGY_FLATHEAD_OVER = 3
|
||||
};
|
||||
|
||||
Position const AffrayChallengerLoc[6] =
|
||||
{
|
||||
{-1683.0f, -4326.0f, 2.79f, 0.0f},
|
||||
{-1682.0f, -4329.0f, 2.79f, 0.0f},
|
||||
{-1683.0f, -4330.0f, 2.79f, 0.0f},
|
||||
{-1680.0f, -4334.0f, 2.79f, 1.49f},
|
||||
{-1674.0f, -4326.0f, 2.79f, 3.49f},
|
||||
{-1677.0f, -4334.0f, 2.79f, 1.66f}
|
||||
};
|
||||
|
||||
class npc_twiggy_flathead : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_twiggy_flathead() : CreatureScript("npc_twiggy_flathead") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_twiggy_flatheadAI (creature);
|
||||
}
|
||||
|
||||
struct npc_twiggy_flatheadAI : public ScriptedAI
|
||||
{
|
||||
npc_twiggy_flatheadAI(Creature* creature) : ScriptedAI(creature) {}
|
||||
|
||||
bool EventInProgress;
|
||||
bool EventGrate;
|
||||
bool EventBigWill;
|
||||
bool ChallengerDown[6];
|
||||
uint8 Wave;
|
||||
uint32 WaveTimer;
|
||||
uint32 ChallengerChecker;
|
||||
uint64 PlayerGUID;
|
||||
uint64 AffrayChallenger[6];
|
||||
uint64 BigWill;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
EventInProgress = false;
|
||||
EventGrate = false;
|
||||
EventBigWill = false;
|
||||
WaveTimer = 600000;
|
||||
ChallengerChecker = 0;
|
||||
Wave = 0;
|
||||
PlayerGUID = 0;
|
||||
|
||||
for (uint8 i = 0; i < 6; ++i)
|
||||
{
|
||||
AffrayChallenger[i] = 0;
|
||||
ChallengerDown[i] = false;
|
||||
}
|
||||
BigWill = 0;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
CleanUp();
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
}
|
||||
|
||||
void CleanUp()
|
||||
{
|
||||
for (uint8 i = 0; i < 6; ++i) // unsummon challengers
|
||||
if (AffrayChallenger[i])
|
||||
if (Creature* creature = ObjectAccessor::GetCreature((*me), AffrayChallenger[i]))
|
||||
creature->DespawnOrUnsummon(1);
|
||||
|
||||
if (BigWill) // unsummon bigWill
|
||||
if (Creature* creature = ObjectAccessor::GetCreature((*me), BigWill))
|
||||
creature->DespawnOrUnsummon(1);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (!who->IsAlive() || EventInProgress || who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (me->IsWithinDistInMap(who, 10.0f) && who->ToPlayer()->GetQuestStatus(1719) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
PlayerGUID = who->GetGUID();
|
||||
EventInProgress = true;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (EventInProgress)
|
||||
{
|
||||
Player* pWarrior = ObjectAccessor::GetPlayer(*me, PlayerGUID);
|
||||
if (!pWarrior || me->GetDistance2d(pWarrior) >= 200.0f)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pWarrior->IsAlive() && pWarrior->GetQuestStatus(1719) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
Talk(SAY_TWIGGY_FLATHEAD_DOWN);
|
||||
pWarrior->FailQuest(1719);
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EventGrate)
|
||||
{
|
||||
float x, y, z;
|
||||
pWarrior->GetPosition(x, y, z);
|
||||
|
||||
if (x >= -1684 && x <= -1674 && y >= -4334 && y <= -4324)
|
||||
{
|
||||
pWarrior->AreaExploredOrEventHappens(1719);
|
||||
Talk(SAY_TWIGGY_FLATHEAD_BEGIN, pWarrior);
|
||||
|
||||
for (uint8 i = 0; i < 6; ++i)
|
||||
{
|
||||
Creature* creature = me->SummonCreature(NPC_AFFRAY_CHALLENGER, AffrayChallengerLoc[i], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000);
|
||||
if (!creature)
|
||||
continue;
|
||||
creature->setFaction(35);
|
||||
creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
creature->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
|
||||
AffrayChallenger[i] = creature->GetGUID();
|
||||
}
|
||||
WaveTimer = 5000;
|
||||
ChallengerChecker = 1000;
|
||||
EventGrate = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ChallengerChecker <= diff)
|
||||
{
|
||||
for (uint8 i = 0; i < 6; ++i)
|
||||
{
|
||||
if (AffrayChallenger[i])
|
||||
{
|
||||
Creature* creature = ObjectAccessor::GetCreature(*me, AffrayChallenger[i]);
|
||||
if ((!creature || !creature->IsAlive()) && !ChallengerDown[i])
|
||||
{
|
||||
Talk(SAY_TWIGGY_FLATHEAD_DOWN);
|
||||
ChallengerDown[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
ChallengerChecker = 1000;
|
||||
} else ChallengerChecker -= diff;
|
||||
|
||||
if (WaveTimer <= diff)
|
||||
{
|
||||
if (Wave < 6 && !EventBigWill)
|
||||
{
|
||||
Talk(SAY_TWIGGY_FLATHEAD_FRAY);
|
||||
Creature* creature = ObjectAccessor::GetCreature(*me, AffrayChallenger[Wave]);
|
||||
if (creature && creature->IsAlive())
|
||||
{
|
||||
creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
creature->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
|
||||
creature->setFaction(14);
|
||||
creature->AI()->AttackStart(pWarrior);
|
||||
}
|
||||
++Wave;
|
||||
WaveTimer = 20000;
|
||||
}
|
||||
else if (Wave >= 6 && !EventBigWill)
|
||||
{
|
||||
if (Creature* creature = me->SummonCreature(NPC_BIG_WILL, -1722, -4341, 6.12f, 6.26f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 480000))
|
||||
{
|
||||
BigWill = creature->GetGUID();
|
||||
creature->GetMotionMaster()->MovePoint(2, -1682, -4329, 2.79f);
|
||||
creature->HandleEmoteCommand(EMOTE_STATE_READY_UNARMED);
|
||||
EventBigWill = true;
|
||||
WaveTimer = 10000;
|
||||
}
|
||||
}
|
||||
else if (Wave >= 6 && EventBigWill)
|
||||
{
|
||||
Creature* creature = ObjectAccessor::GetCreature(*me, BigWill);
|
||||
if (!creature || !creature->IsAlive())
|
||||
{
|
||||
Talk(SAY_TWIGGY_FLATHEAD_OVER);
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
else if (creature) // Makes BIG WILL attackable.
|
||||
{
|
||||
creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
creature->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
|
||||
creature->setFaction(14);
|
||||
creature->AI()->AttackStart(pWarrior);
|
||||
}
|
||||
WaveTimer = 2000;
|
||||
}
|
||||
}
|
||||
else
|
||||
WaveTimer -= diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/*#####
|
||||
## npc_wizzlecrank_shredder
|
||||
#####*/
|
||||
|
||||
enum Wizzlecrank
|
||||
{
|
||||
SAY_MERCENARY = 0,
|
||||
SAY_START = 0,
|
||||
SAY_STARTUP1 = 1,
|
||||
SAY_STARTUP2 = 2,
|
||||
SAY_PROGRESS_1 = 3,
|
||||
SAY_PROGRESS_2 = 4,
|
||||
SAY_PROGRESS_3 = 5,
|
||||
SAY_END = 6,
|
||||
|
||||
QUEST_ESCAPE = 863,
|
||||
FACTION_RATCHET = 637,
|
||||
NPC_PILOT_WIZZ = 3451,
|
||||
NPC_MERCENARY = 3282,
|
||||
};
|
||||
|
||||
class npc_wizzlecrank_shredder : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_wizzlecrank_shredder() : CreatureScript("npc_wizzlecrank_shredder") { }
|
||||
|
||||
struct npc_wizzlecrank_shredderAI : public npc_escortAI
|
||||
{
|
||||
npc_wizzlecrank_shredderAI(Creature* creature) : npc_escortAI(creature)
|
||||
{
|
||||
IsPostEvent = false;
|
||||
PostEventTimer = 1000;
|
||||
PostEventCount = 0;
|
||||
}
|
||||
|
||||
bool IsPostEvent;
|
||||
uint32 PostEventTimer;
|
||||
uint32 PostEventCount;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (!HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
{
|
||||
if (me->getStandState() == UNIT_STAND_STATE_DEAD)
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
|
||||
IsPostEvent = false;
|
||||
PostEventTimer = 1000;
|
||||
PostEventCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 0:
|
||||
Talk(SAY_STARTUP1);
|
||||
break;
|
||||
case 9:
|
||||
SetRun(false);
|
||||
break;
|
||||
case 17:
|
||||
if (Creature* temp = me->SummonCreature(NPC_MERCENARY, 1128.489f, -3037.611f, 92.701f, 1.472f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000))
|
||||
{
|
||||
temp->AI()->Talk(SAY_MERCENARY);
|
||||
me->SummonCreature(NPC_MERCENARY, 1160.172f, -2980.168f, 97.313f, 3.690f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000);
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
IsPostEvent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WaypointStart(uint32 PointId)
|
||||
{
|
||||
Player* player = GetPlayerForEscort();
|
||||
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
switch (PointId)
|
||||
{
|
||||
case 9:
|
||||
Talk(SAY_STARTUP2, player);
|
||||
break;
|
||||
case 18:
|
||||
Talk(SAY_PROGRESS_1, player);
|
||||
SetRun();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned)
|
||||
{
|
||||
if (summoned->GetEntry() == NPC_PILOT_WIZZ)
|
||||
me->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||
|
||||
if (summoned->GetEntry() == NPC_MERCENARY)
|
||||
summoned->AI()->AttackStart(me);
|
||||
}
|
||||
|
||||
void UpdateEscortAI(uint32 Diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
if (IsPostEvent)
|
||||
{
|
||||
if (PostEventTimer <= Diff)
|
||||
{
|
||||
switch (PostEventCount)
|
||||
{
|
||||
case 0:
|
||||
Talk(SAY_PROGRESS_2);
|
||||
break;
|
||||
case 1:
|
||||
Talk(SAY_PROGRESS_3);
|
||||
break;
|
||||
case 2:
|
||||
Talk(SAY_END);
|
||||
break;
|
||||
case 3:
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
{
|
||||
player->GroupEventHappens(QUEST_ESCAPE, me);
|
||||
me->SummonCreature(NPC_PILOT_WIZZ, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 180000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
++PostEventCount;
|
||||
PostEventTimer = 5000;
|
||||
}
|
||||
else
|
||||
PostEventTimer -= Diff;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_ESCAPE)
|
||||
{
|
||||
creature->setFaction(FACTION_RATCHET);
|
||||
creature->AI()->Talk(SAY_START);
|
||||
if (npc_escortAI* pEscortAI = CAST_AI(npc_wizzlecrank_shredder::npc_wizzlecrank_shredderAI, creature->AI()))
|
||||
pEscortAI->Start(true, false, player->GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_wizzlecrank_shredderAI(creature);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void AddSC_the_barrens()
|
||||
{
|
||||
new npc_beaten_corpse();
|
||||
new npc_gilthares();
|
||||
new npc_taskmaster_fizzule();
|
||||
new npc_twiggy_flathead();
|
||||
new npc_wizzlecrank_shredder();
|
||||
}
|
||||
@@ -1,463 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Thousand Needles
|
||||
SD%Complete: 100
|
||||
SDComment: Support for Quest: 1950, 4770, 4904, 4966, 5151.
|
||||
SDCategory: Thousand Needles
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_kanati
|
||||
npc_lakota_windsong
|
||||
npc_swiftmountain
|
||||
npc_plucky
|
||||
npc_enraged_panther
|
||||
go_panther_cage
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "Player.h"
|
||||
|
||||
/*#####
|
||||
# npc_kanati
|
||||
######*/
|
||||
|
||||
enum Kanati
|
||||
{
|
||||
SAY_KAN_START = 0,
|
||||
|
||||
QUEST_PROTECT_KANATI = 4966,
|
||||
NPC_GALAK_ASS = 10720
|
||||
};
|
||||
|
||||
Position const GalakLoc = {-4867.387695f, -1357.353760f, -48.226f, 0.0f};
|
||||
|
||||
class npc_kanati : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_kanati() : CreatureScript("npc_kanati") { }
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_PROTECT_KANATI)
|
||||
if (npc_kanatiAI* pEscortAI = CAST_AI(npc_kanati::npc_kanatiAI, creature->AI()))
|
||||
pEscortAI->Start(false, false, player->GetGUID(), quest, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_kanatiAI(creature);
|
||||
}
|
||||
|
||||
struct npc_kanatiAI : public npc_escortAI
|
||||
{
|
||||
npc_kanatiAI(Creature* creature) : npc_escortAI(creature) { }
|
||||
|
||||
void Reset() { }
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 0:
|
||||
Talk(SAY_KAN_START);
|
||||
DoSpawnGalak();
|
||||
break;
|
||||
case 1:
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
player->GroupEventHappens(QUEST_PROTECT_KANATI, me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DoSpawnGalak()
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
me->SummonCreature(NPC_GALAK_ASS, GalakLoc, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned)
|
||||
{
|
||||
summoned->AI()->AttackStart(me);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
# npc_lakota_windsong
|
||||
######*/
|
||||
|
||||
enum Lakota
|
||||
{
|
||||
SAY_LAKO_START = 0,
|
||||
SAY_LAKO_LOOK_OUT = 1,
|
||||
SAY_LAKO_HERE_COME = 2,
|
||||
SAY_LAKO_MORE = 3,
|
||||
SAY_LAKO_END = 4,
|
||||
|
||||
QUEST_FREE_AT_LAST = 4904,
|
||||
NPC_GRIM_BANDIT = 10758,
|
||||
FACTION_ESCORTEE_LAKO = 232, //guessed
|
||||
|
||||
ID_AMBUSH_1 = 0,
|
||||
ID_AMBUSH_2 = 2,
|
||||
ID_AMBUSH_3 = 4
|
||||
};
|
||||
|
||||
Position const BanditLoc[6] =
|
||||
{
|
||||
{-4905.479492f, -2062.732666f, 84.352f, 0.0f},
|
||||
{-4915.201172f, -2073.528320f, 84.733f, 0.0f},
|
||||
{-4878.883301f, -1986.947876f, 91.966f, 0.0f},
|
||||
{-4877.503906f, -1966.113403f, 91.859f, 0.0f},
|
||||
{-4767.985352f, -1873.169189f, 90.192f, 0.0f},
|
||||
{-4788.861328f, -1888.007813f, 89.888f, 0.0f}
|
||||
};
|
||||
|
||||
class npc_lakota_windsong : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_lakota_windsong() : CreatureScript("npc_lakota_windsong") { }
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_FREE_AT_LAST)
|
||||
{
|
||||
creature->AI()->Talk(SAY_LAKO_START, player);
|
||||
creature->setFaction(FACTION_ESCORTEE_LAKO);
|
||||
|
||||
if (npc_lakota_windsongAI* pEscortAI = CAST_AI(npc_lakota_windsong::npc_lakota_windsongAI, creature->AI()))
|
||||
pEscortAI->Start(false, false, player->GetGUID(), quest);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_lakota_windsongAI(creature);
|
||||
}
|
||||
|
||||
struct npc_lakota_windsongAI : public npc_escortAI
|
||||
{
|
||||
npc_lakota_windsongAI(Creature* creature) : npc_escortAI(creature) { }
|
||||
|
||||
void Reset() { }
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 8:
|
||||
Talk(SAY_LAKO_LOOK_OUT);
|
||||
DoSpawnBandits(ID_AMBUSH_1);
|
||||
break;
|
||||
case 14:
|
||||
Talk(SAY_LAKO_HERE_COME);
|
||||
DoSpawnBandits(ID_AMBUSH_2);
|
||||
break;
|
||||
case 21:
|
||||
Talk(SAY_LAKO_MORE);
|
||||
DoSpawnBandits(ID_AMBUSH_3);
|
||||
break;
|
||||
case 45:
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
player->GroupEventHappens(QUEST_FREE_AT_LAST, me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DoSpawnBandits(int AmbushId)
|
||||
{
|
||||
for (int i = 0; i < 2; ++i)
|
||||
me->SummonCreature(NPC_GRIM_BANDIT, BanditLoc[i+AmbushId], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/*######
|
||||
# npc_paoka_swiftmountain
|
||||
######*/
|
||||
|
||||
enum Packa
|
||||
{
|
||||
SAY_START = 0,
|
||||
SAY_WYVERN = 1,
|
||||
SAY_COMPLETE = 2,
|
||||
|
||||
QUEST_HOMEWARD = 4770,
|
||||
NPC_WYVERN = 4107,
|
||||
FACTION_ESCORTEE = 232 //guessed
|
||||
};
|
||||
|
||||
Position const WyvernLoc[3] =
|
||||
{
|
||||
{-4990.606f, -906.057f, -5.343f, 0.0f},
|
||||
{-4970.241f, -927.378f, -4.951f, 0.0f},
|
||||
{-4985.364f, -952.528f, -5.199f, 0.0f}
|
||||
};
|
||||
|
||||
class npc_paoka_swiftmountain : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_paoka_swiftmountain() : CreatureScript("npc_paoka_swiftmountain") { }
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_HOMEWARD)
|
||||
{
|
||||
creature->AI()->Talk(SAY_START, player);
|
||||
creature->setFaction(FACTION_ESCORTEE);
|
||||
|
||||
if (npc_paoka_swiftmountainAI* pEscortAI = CAST_AI(npc_paoka_swiftmountain::npc_paoka_swiftmountainAI, creature->AI()))
|
||||
pEscortAI->Start(false, false, player->GetGUID(), quest);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_paoka_swiftmountainAI(creature);
|
||||
}
|
||||
|
||||
struct npc_paoka_swiftmountainAI : public npc_escortAI
|
||||
{
|
||||
npc_paoka_swiftmountainAI(Creature* creature) : npc_escortAI(creature) { }
|
||||
|
||||
void Reset() { }
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 15:
|
||||
Talk(SAY_WYVERN);
|
||||
DoSpawnWyvern();
|
||||
break;
|
||||
case 26:
|
||||
Talk(SAY_COMPLETE);
|
||||
break;
|
||||
case 27:
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
player->GroupEventHappens(QUEST_HOMEWARD, me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DoSpawnWyvern()
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
me->SummonCreature(NPC_WYVERN, WyvernLoc[i], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/*#####
|
||||
# npc_plucky
|
||||
######*/
|
||||
|
||||
#define GOSSIP_P "Please tell me the Phrase.."
|
||||
|
||||
enum Plucky
|
||||
{
|
||||
FACTION_FRIENDLY = 35,
|
||||
QUEST_SCOOP = 1950,
|
||||
SPELL_PLUCKY_HUMAN = 9192,
|
||||
SPELL_PLUCKY_CHICKEN = 9220
|
||||
};
|
||||
|
||||
class npc_plucky : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_plucky() : CreatureScript("npc_plucky") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
switch (action)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF+1:
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
player->CompleteQuest(QUEST_SCOOP);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (player->GetQuestStatus(QUEST_SCOOP) == QUEST_STATUS_INCOMPLETE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_P, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
|
||||
player->SEND_GOSSIP_MENU(738, creature->GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_pluckyAI(creature);
|
||||
}
|
||||
|
||||
struct npc_pluckyAI : public ScriptedAI
|
||||
{
|
||||
npc_pluckyAI(Creature* creature) : ScriptedAI(creature) { NormFaction = creature->getFaction(); }
|
||||
|
||||
uint32 NormFaction;
|
||||
uint32 ResetTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
ResetTimer = 120000;
|
||||
|
||||
if (me->getFaction() != NormFaction)
|
||||
me->setFaction(NormFaction);
|
||||
|
||||
if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP))
|
||||
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
|
||||
DoCast(me, SPELL_PLUCKY_CHICKEN, false);
|
||||
}
|
||||
|
||||
void ReceiveEmote(Player* player, uint32 TextEmote)
|
||||
{
|
||||
if (player->GetQuestStatus(QUEST_SCOOP) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
if (TextEmote == TEXT_EMOTE_BECKON)
|
||||
{
|
||||
me->setFaction(FACTION_FRIENDLY);
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
DoCast(me, SPELL_PLUCKY_HUMAN, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (TextEmote == TEXT_EMOTE_CHICKEN)
|
||||
{
|
||||
if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP))
|
||||
return;
|
||||
else
|
||||
{
|
||||
me->setFaction(FACTION_FRIENDLY);
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
DoCast(me, SPELL_PLUCKY_HUMAN, false);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_WAVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 Diff)
|
||||
{
|
||||
if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP))
|
||||
{
|
||||
if (ResetTimer <= Diff)
|
||||
{
|
||||
if (!me->GetVictim())
|
||||
EnterEvadeMode();
|
||||
else
|
||||
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
ResetTimer -= Diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
enum PantherCage
|
||||
{
|
||||
ENRAGED_PANTHER = 10992
|
||||
};
|
||||
|
||||
class go_panther_cage : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_panther_cage() : GameObjectScript("go_panther_cage") { }
|
||||
|
||||
bool OnGossipHello(Player* player, GameObject* go)
|
||||
{
|
||||
go->UseDoorOrButton();
|
||||
if (player->GetQuestStatus(5151) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
if (Creature* panther = go->FindNearestCreature(ENRAGED_PANTHER, 5, true))
|
||||
{
|
||||
panther->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
panther->SetReactState(REACT_AGGRESSIVE);
|
||||
panther->AI()->AttackStart(player);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class npc_enraged_panther : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_enraged_panther() : CreatureScript("npc_enraged_panther") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_enraged_pantherAI(creature);
|
||||
}
|
||||
|
||||
struct npc_enraged_pantherAI : public ScriptedAI
|
||||
{
|
||||
npc_enraged_pantherAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 /*diff*/)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_thousand_needles()
|
||||
{
|
||||
new npc_kanati();
|
||||
new npc_lakota_windsong();
|
||||
new npc_paoka_swiftmountain();
|
||||
new npc_plucky();
|
||||
new npc_enraged_panther();
|
||||
new go_panther_cage();
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Thunder_Bluff
|
||||
SD%Complete: 100
|
||||
SDComment: Quest support: 925
|
||||
SDCategory: Thunder Bluff
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "Player.h"
|
||||
|
||||
/*#####
|
||||
# npc_cairne_bloodhoof
|
||||
######*/
|
||||
|
||||
enum CairneBloodhoof
|
||||
{
|
||||
SPELL_BERSERKER_CHARGE = 16636,
|
||||
SPELL_CLEAVE = 16044,
|
||||
SPELL_MORTAL_STRIKE = 16856,
|
||||
SPELL_THUNDERCLAP = 23931,
|
||||
SPELL_UPPERCUT = 22916
|
||||
};
|
||||
|
||||
#define GOSSIP_HCB "I know this is rather silly but a young ward who is a bit shy would like your hoofprint."
|
||||
/// @todo verify abilities/timers
|
||||
class npc_cairne_bloodhoof : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_cairne_bloodhoof() : CreatureScript("npc_cairne_bloodhoof") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
if (action == GOSSIP_SENDER_INFO)
|
||||
{
|
||||
player->CastSpell(player, 23123, false);
|
||||
player->SEND_GOSSIP_MENU(7014, creature->GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (creature->IsQuestGiver())
|
||||
player->PrepareQuestMenu(creature->GetGUID());
|
||||
|
||||
if (player->GetQuestStatus(925) == QUEST_STATUS_INCOMPLETE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HCB, GOSSIP_SENDER_MAIN, GOSSIP_SENDER_INFO);
|
||||
|
||||
player->SEND_GOSSIP_MENU(7013, creature->GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_cairne_bloodhoofAI(creature);
|
||||
}
|
||||
|
||||
struct npc_cairne_bloodhoofAI : public ScriptedAI
|
||||
{
|
||||
npc_cairne_bloodhoofAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 BerserkerChargeTimer;
|
||||
uint32 CleaveTimer;
|
||||
uint32 MortalStrikeTimer;
|
||||
uint32 ThunderclapTimer;
|
||||
uint32 UppercutTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
BerserkerChargeTimer = 30000;
|
||||
CleaveTimer = 5000;
|
||||
MortalStrikeTimer = 10000;
|
||||
ThunderclapTimer = 15000;
|
||||
UppercutTimer = 10000;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (BerserkerChargeTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_BERSERKER_CHARGE);
|
||||
BerserkerChargeTimer = 25000;
|
||||
} else BerserkerChargeTimer -= diff;
|
||||
|
||||
if (UppercutTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_UPPERCUT);
|
||||
UppercutTimer = 20000;
|
||||
} else UppercutTimer -= diff;
|
||||
|
||||
if (ThunderclapTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_THUNDERCLAP);
|
||||
ThunderclapTimer = 15000;
|
||||
} else ThunderclapTimer -= diff;
|
||||
|
||||
if (MortalStrikeTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_MORTAL_STRIKE);
|
||||
MortalStrikeTimer = 15000;
|
||||
} else MortalStrikeTimer -= diff;
|
||||
|
||||
if (CleaveTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
CleaveTimer = 7000;
|
||||
} else CleaveTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_thunder_bluff()
|
||||
{
|
||||
new npc_cairne_bloodhoof();
|
||||
}
|
||||
@@ -1,349 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Ungoro Crater
|
||||
SD%Complete: 100
|
||||
SDComment: Support for Quest: 4245, 4491
|
||||
SDCategory: Ungoro Crater
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_a-me
|
||||
npc_ringo
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "ScriptedFollowerAI.h"
|
||||
#include "Player.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
enum AmeData
|
||||
{
|
||||
SAY_READY = 0,
|
||||
SAY_AGGRO1 = 1,
|
||||
SAY_SEARCH = 2,
|
||||
SAY_AGGRO2 = 3,
|
||||
SAY_AGGRO3 = 4,
|
||||
SAY_FINISH = 5,
|
||||
|
||||
SPELL_DEMORALIZINGSHOUT = 13730,
|
||||
|
||||
QUEST_CHASING_AME = 4245,
|
||||
ENTRY_TARLORD = 6519,
|
||||
ENTRY_TARLORD1 = 6519,
|
||||
ENTRY_STOMPER = 6513,
|
||||
};
|
||||
|
||||
class npc_ame : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ame() : CreatureScript("npc_ame") { }
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_CHASING_AME)
|
||||
{
|
||||
CAST_AI(npc_escortAI, (creature->AI()))->Start(false, false, player->GetGUID());
|
||||
creature->AI()->Talk(SAY_READY, player);
|
||||
creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
// Change faction so mobs attack
|
||||
creature->setFaction(113);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_ameAI(creature);
|
||||
}
|
||||
|
||||
struct npc_ameAI : public npc_escortAI
|
||||
{
|
||||
npc_ameAI(Creature* creature) : npc_escortAI(creature) { }
|
||||
|
||||
uint32 DemoralizingShoutTimer;
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 19:
|
||||
me->SummonCreature(ENTRY_STOMPER, -6391.69f, -1730.49f, -272.83f, 4.96f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
|
||||
Talk(SAY_AGGRO1, player);
|
||||
break;
|
||||
case 28:
|
||||
Talk(SAY_SEARCH, player);
|
||||
break;
|
||||
case 38:
|
||||
me->SummonCreature(ENTRY_TARLORD, -6370.75f, -1382.84f, -270.51f, 6.06f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
|
||||
Talk(SAY_AGGRO2, player);
|
||||
break;
|
||||
case 49:
|
||||
me->SummonCreature(ENTRY_TARLORD1, -6324.44f, -1181.05f, -270.17f, 4.34f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
|
||||
Talk(SAY_AGGRO3, player);
|
||||
break;
|
||||
case 55:
|
||||
Talk(SAY_FINISH, player);
|
||||
player->GroupEventHappens(QUEST_CHASING_AME, me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
DemoralizingShoutTimer = 5000;
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned)
|
||||
{
|
||||
summoned->AI()->AttackStart(me);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
player->FailQuest(QUEST_CHASING_AME);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (DemoralizingShoutTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_DEMORALIZINGSHOUT);
|
||||
DemoralizingShoutTimer = 70000;
|
||||
} else DemoralizingShoutTimer -= diff;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/*####
|
||||
# npc_ringo
|
||||
####*/
|
||||
|
||||
enum Ringo
|
||||
{
|
||||
SAY_RIN_START = 0,
|
||||
|
||||
SAY_FAINT = 1,
|
||||
|
||||
SAY_WAKE = 2,
|
||||
|
||||
SAY_RIN_END_1 = 3,
|
||||
SAY_SPR_END_2 = 0,
|
||||
SAY_RIN_END_3 = 4,
|
||||
EMOTE_RIN_END_4 = 5,
|
||||
EMOTE_RIN_END_5 = 6,
|
||||
SAY_RIN_END_6 = 7,
|
||||
SAY_SPR_END_7 = 1,
|
||||
EMOTE_RIN_END_8 = 8,
|
||||
|
||||
SPELL_REVIVE_RINGO = 15591,
|
||||
QUEST_A_LITTLE_HELP = 4491,
|
||||
NPC_SPRAGGLE = 9997,
|
||||
FACTION_ESCORTEE = 113
|
||||
};
|
||||
|
||||
class npc_ringo : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ringo() : CreatureScript("npc_ringo") { }
|
||||
|
||||
bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_A_LITTLE_HELP)
|
||||
{
|
||||
if (npc_ringoAI* ringoAI = CAST_AI(npc_ringo::npc_ringoAI, creature->AI()))
|
||||
{
|
||||
creature->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
ringoAI->StartFollow(player, FACTION_ESCORTEE, quest);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_ringoAI(creature);
|
||||
}
|
||||
|
||||
struct npc_ringoAI : public FollowerAI
|
||||
{
|
||||
npc_ringoAI(Creature* creature) : FollowerAI(creature) { }
|
||||
|
||||
uint32 FaintTimer;
|
||||
uint32 EndEventProgress;
|
||||
uint32 EndEventTimer;
|
||||
|
||||
uint64 SpraggleGUID;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
FaintTimer = urand(30000, 60000);
|
||||
EndEventProgress = 0;
|
||||
EndEventTimer = 1000;
|
||||
SpraggleGUID = 0;
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
|
||||
{
|
||||
FollowerAI::MoveInLineOfSight(who);
|
||||
|
||||
if (!me->GetVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_SPRAGGLE)
|
||||
{
|
||||
if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE))
|
||||
{
|
||||
if (Player* player = GetLeaderForFollower())
|
||||
{
|
||||
if (player->GetQuestStatus(QUEST_A_LITTLE_HELP) == QUEST_STATUS_INCOMPLETE)
|
||||
player->GroupEventHappens(QUEST_A_LITTLE_HELP, me);
|
||||
}
|
||||
|
||||
SpraggleGUID = who->GetGUID();
|
||||
SetFollowComplete(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell)
|
||||
{
|
||||
if (HasFollowState(STATE_FOLLOW_INPROGRESS | STATE_FOLLOW_PAUSED) && pSpell->Id == SPELL_REVIVE_RINGO)
|
||||
ClearFaint();
|
||||
}
|
||||
|
||||
void SetFaint()
|
||||
{
|
||||
if (!HasFollowState(STATE_FOLLOW_POSTEVENT))
|
||||
{
|
||||
SetFollowPaused(true);
|
||||
|
||||
Talk(SAY_FAINT);
|
||||
}
|
||||
|
||||
//what does actually happen here? Emote? Aura?
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
}
|
||||
|
||||
void ClearFaint()
|
||||
{
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
|
||||
if (HasFollowState(STATE_FOLLOW_POSTEVENT))
|
||||
return;
|
||||
|
||||
Talk(SAY_WAKE);
|
||||
|
||||
SetFollowPaused(false);
|
||||
}
|
||||
|
||||
void UpdateFollowerAI(uint32 Diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
if (HasFollowState(STATE_FOLLOW_POSTEVENT))
|
||||
{
|
||||
if (EndEventTimer <= Diff)
|
||||
{
|
||||
Creature* spraggle = ObjectAccessor::GetCreature(*me, SpraggleGUID);
|
||||
if (!spraggle || !spraggle->IsAlive())
|
||||
{
|
||||
SetFollowComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (EndEventProgress)
|
||||
{
|
||||
case 1:
|
||||
Talk(SAY_RIN_END_1);
|
||||
EndEventTimer = 3000;
|
||||
break;
|
||||
case 2:
|
||||
spraggle->AI()->Talk(SAY_SPR_END_2);
|
||||
EndEventTimer = 5000;
|
||||
break;
|
||||
case 3:
|
||||
Talk(SAY_RIN_END_3);
|
||||
EndEventTimer = 1000;
|
||||
break;
|
||||
case 4:
|
||||
Talk(EMOTE_RIN_END_4);
|
||||
SetFaint();
|
||||
EndEventTimer = 9000;
|
||||
break;
|
||||
case 5:
|
||||
Talk(EMOTE_RIN_END_5);
|
||||
ClearFaint();
|
||||
EndEventTimer = 1000;
|
||||
break;
|
||||
case 6:
|
||||
Talk(SAY_RIN_END_6);
|
||||
EndEventTimer = 3000;
|
||||
break;
|
||||
case 7:
|
||||
spraggle->AI()->Talk(SAY_SPR_END_7);
|
||||
EndEventTimer = 10000;
|
||||
break;
|
||||
case 8:
|
||||
Talk(EMOTE_RIN_END_8);
|
||||
EndEventTimer = 5000;
|
||||
break;
|
||||
case 9:
|
||||
SetFollowComplete();
|
||||
break;
|
||||
}
|
||||
|
||||
++EndEventProgress;
|
||||
}
|
||||
else
|
||||
EndEventTimer -= Diff;
|
||||
}
|
||||
else if (HasFollowState(STATE_FOLLOW_INPROGRESS) && !HasFollowState(STATE_FOLLOW_PAUSED))
|
||||
{
|
||||
if (FaintTimer <= Diff)
|
||||
{
|
||||
SetFaint();
|
||||
FaintTimer = urand(60000, 120000);
|
||||
}
|
||||
else
|
||||
FaintTimer -= Diff;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_ungoro_crater()
|
||||
{
|
||||
new npc_ame();
|
||||
new npc_ringo();
|
||||
}
|
||||
@@ -1,805 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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: Winterspring
|
||||
SD%Complete: Almost Completely Emptied
|
||||
SDComment: Vendor Rivern Frostwind. Quest Support 4901
|
||||
SDCategory: Winterspring
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_rivern_frostwind
|
||||
npc_ranshalla
|
||||
go_elune_fire
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "Player.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
// Ours
|
||||
enum eStaveQuest
|
||||
{
|
||||
QUEST_STAVE_OF_THE_ANCIENTS = 7636,
|
||||
|
||||
NPC_SIMONE_NORMAL = 14527,
|
||||
NPC_FRANKLIN_NORMAL = 14529,
|
||||
NPC_ARTORIUS_NORMAL = 14531,
|
||||
NPC_NELSON_NORMAL = 14536,
|
||||
NPC_PRECIOUS = 14528,
|
||||
|
||||
NPC_SIMONE_EVIL = 14533,
|
||||
NPC_FRANKLIN_EVIL = 14534,
|
||||
NPC_ARTORIUS_EVIL = 14535,
|
||||
NPC_NELSON_EVIL = 14530,
|
||||
NPC_PRECIOUS_EVIL = 14538,
|
||||
|
||||
EVENT_CHECK_PLAYER = 1,
|
||||
EVENT_SPELL_CHAIN_LIGHTNING = 23206,
|
||||
EVENT_SPELL_TEMPTRESS_KISS = 23205,
|
||||
EVENT_SPELL_DEMONIC_ENRAGE = 23257,
|
||||
EVENT_SPELL_ENTROPIC_STING = 23260,
|
||||
EVENT_SPELL_DEMONIC_DOOM = 23298,
|
||||
EVENT_SPELL_STINGING_TRAUMA = 23299,
|
||||
EVENT_SPELL_DREADFUL_FRIGHT = 23275,
|
||||
|
||||
SPELL_FOOLS_PLIGHT = 23504,
|
||||
SPELL_SOUL_FLAME = 23272,
|
||||
};
|
||||
|
||||
class npc_stave_of_the_ancients : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_stave_of_the_ancients() : CreatureScript("npc_stave_of_the_ancients") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_stave_of_the_ancientsAI(creature);
|
||||
}
|
||||
|
||||
struct npc_stave_of_the_ancientsAI : public ScriptedAI
|
||||
{
|
||||
npc_stave_of_the_ancientsAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
changeEntry = me->GetEntry();
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_SIMONE_NORMAL: changeEntry = NPC_SIMONE_EVIL; break;
|
||||
case NPC_FRANKLIN_NORMAL: changeEntry = NPC_FRANKLIN_EVIL; break;
|
||||
case NPC_ARTORIUS_NORMAL: changeEntry = NPC_ARTORIUS_EVIL; break;
|
||||
case NPC_NELSON_NORMAL: changeEntry = NPC_NELSON_EVIL; break;
|
||||
case NPC_PRECIOUS: changeEntry = NPC_PRECIOUS_EVIL; break;
|
||||
}
|
||||
}
|
||||
|
||||
uint64 playerGUID;
|
||||
EventMap events;
|
||||
uint32 changeEntry;
|
||||
bool damaged;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (me->GetOriginalEntry() != me->GetEntry())
|
||||
me->UpdateEntry(me->GetOriginalEntry());
|
||||
|
||||
events.Reset();
|
||||
playerGUID = 0;
|
||||
damaged = false;
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32&, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (!damaged)
|
||||
{
|
||||
if (who && who->GetGUID() != playerGUID && (who->GetTypeId() == TYPEID_PLAYER || IS_PLAYER_GUID(who->GetOwnerGUID())))
|
||||
{
|
||||
damaged = true;
|
||||
me->CastSpell(who, SPELL_FOOLS_PLIGHT, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
damaged = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit*)
|
||||
{
|
||||
switch (changeEntry)
|
||||
{
|
||||
case NPC_SIMONE_EVIL:
|
||||
events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, 3000);
|
||||
events.ScheduleEvent(EVENT_SPELL_TEMPTRESS_KISS, 1000);
|
||||
break;
|
||||
case NPC_FRANKLIN_EVIL:
|
||||
events.ScheduleEvent(EVENT_SPELL_DEMONIC_ENRAGE, 3000);
|
||||
events.ScheduleEvent(EVENT_SPELL_ENTROPIC_STING, 5000);
|
||||
break;
|
||||
case NPC_ARTORIUS_EVIL:
|
||||
events.ScheduleEvent(EVENT_SPELL_DEMONIC_DOOM, 3000);
|
||||
events.ScheduleEvent(EVENT_SPELL_STINGING_TRAUMA, 5000);
|
||||
break;
|
||||
case NPC_NELSON_EVIL:
|
||||
me->CastSpell(me, SPELL_SOUL_FLAME, true);
|
||||
events.ScheduleEvent(EVENT_SPELL_DREADFUL_FRIGHT, 5000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (me->GetEntry() != changeEntry && who->GetTypeId() == TYPEID_PLAYER && who->ToPlayer()->GetQuestStatus(QUEST_STAVE_OF_THE_ANCIENTS) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
playerGUID = who->GetGUID();
|
||||
me->UpdateEntry(changeEntry);
|
||||
events.ScheduleEvent(EVENT_CHECK_PLAYER, 5000);
|
||||
return;
|
||||
}
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
events.Update(diff);
|
||||
uint32 eventId = events.GetEvent();
|
||||
if (eventId == EVENT_CHECK_PLAYER)
|
||||
{
|
||||
Player* player = ObjectAccessor::GetPlayer(*me, playerGUID);
|
||||
if (!player || !player->IsWithinDist2d(me, 60.0f))
|
||||
EnterEvadeMode();
|
||||
else
|
||||
events.RepeatEvent(5000);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SPELL_CHAIN_LIGHTNING:
|
||||
me->CastSpell(me->GetVictim(), eventId, false);
|
||||
events.RepeatEvent(7000);
|
||||
break;
|
||||
case EVENT_SPELL_TEMPTRESS_KISS:
|
||||
me->CastSpell(me->GetVictim(), eventId, false);
|
||||
events.RepeatEvent(45000);
|
||||
break;
|
||||
case EVENT_SPELL_DEMONIC_ENRAGE:
|
||||
me->CastSpell(me, eventId, false);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_ENTROPIC_STING:
|
||||
me->CastSpell(me->GetVictim(), eventId, false);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_DEMONIC_DOOM:
|
||||
me->CastSpell(me->GetVictim(), eventId, false);
|
||||
events.RepeatEvent(50000);
|
||||
break;
|
||||
case EVENT_SPELL_STINGING_TRAUMA:
|
||||
me->CastSpell(me->GetVictim(), eventId, false);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_DREADFUL_FRIGHT:
|
||||
me->CastSpell(me->GetVictim(), eventId, false);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Theirs
|
||||
/*######
|
||||
## npc_rivern_frostwind
|
||||
######*/
|
||||
|
||||
class npc_rivern_frostwind : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_rivern_frostwind() : CreatureScript("npc_rivern_frostwind") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
if (action == GOSSIP_ACTION_TRADE)
|
||||
player->GetSession()->SendListInventory(creature->GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (creature->IsQuestGiver())
|
||||
player->PrepareQuestMenu(creature->GetGUID());
|
||||
|
||||
if (creature->IsVendor() && player->GetReputationRank(589) == REP_EXALTED)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
|
||||
|
||||
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
enum Says
|
||||
{
|
||||
// Escort texts
|
||||
SAY_QUEST_START = 0,
|
||||
SAY_ENTER_OWL_THICKET = 1,
|
||||
SAY_REACH_TORCH = 2,
|
||||
SAY_AFTER_TORCH = 3,
|
||||
SAY_REACH_ALTAR_1 = 4,
|
||||
SAY_REACH_ALTAR_2 = 5,
|
||||
|
||||
// After lighting the altar cinematic
|
||||
SAY_RANSHALLA_ALTAR_1 = 6,
|
||||
SAY_RANSHALLA_ALTAR_2 = 7,
|
||||
SAY_PRIESTESS_ALTAR_3 = 8,
|
||||
SAY_PRIESTESS_ALTAR_4 = 9,
|
||||
SAY_RANSHALLA_ALTAR_5 = 10,
|
||||
SAY_RANSHALLA_ALTAR_6 = 11,
|
||||
SAY_PRIESTESS_ALTAR_7 = 12,
|
||||
SAY_PRIESTESS_ALTAR_8 = 13,
|
||||
SAY_PRIESTESS_ALTAR_9 = 14,
|
||||
SAY_PRIESTESS_ALTAR_10 = 15,
|
||||
SAY_PRIESTESS_ALTAR_11 = 16,
|
||||
SAY_PRIESTESS_ALTAR_12 = 17,
|
||||
SAY_PRIESTESS_ALTAR_13 = 18,
|
||||
SAY_PRIESTESS_ALTAR_14 = 19,
|
||||
SAY_VOICE_ALTAR_15 = 20,
|
||||
SAY_PRIESTESS_ALTAR_16 = 21,
|
||||
SAY_PRIESTESS_ALTAR_17 = 22,
|
||||
SAY_PRIESTESS_ALTAR_18 = 23,
|
||||
SAY_PRIESTESS_ALTAR_19 = 24,
|
||||
SAY_PRIESTESS_ALTAR_20 = 25,
|
||||
SAY_PRIESTESS_ALTAR_21 = 26,
|
||||
SAY_RANSHALLA_END_1 = 27,
|
||||
SAY_RANSHALLA_END_2 = 28,
|
||||
|
||||
EMOTE_CHANT_SPELL = 29,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_LIGHT_TORCH = 18953, // channeled spell by Ranshalla while waiting for the torches / altar
|
||||
};
|
||||
|
||||
enum NPCs
|
||||
{
|
||||
NPC_RANSHALLA = 10300,
|
||||
NPC_PRIESTESS_ELUNE = 12116,
|
||||
NPC_VOICE_ELUNE = 12152,
|
||||
NPC_GUARDIAN_ELUNE = 12140,
|
||||
};
|
||||
|
||||
enum GOs
|
||||
{
|
||||
GO_ELUNE_ALTAR = 177404,
|
||||
GO_ELUNE_FIRE = 177417,
|
||||
GO_ELUNE_GEM = 177414, // is respawned in script
|
||||
GO_ELUNE_LIGHT = 177415, // are respawned in script
|
||||
};
|
||||
|
||||
enum Quests
|
||||
{
|
||||
QUEST_GUARDIANS_ALTAR = 4901,
|
||||
};
|
||||
|
||||
enum Dummies
|
||||
{
|
||||
NPC_PRIESTESS_DATA_1 = -1, // dummy member for the first priestess (right)
|
||||
NPC_PRIESTESS_DATA_2 = -2, // dummy member for the second priestess (left)
|
||||
DATA_MOVE_PRIESTESS = -3, // dummy member to check the priestess movement
|
||||
DATA_EVENT_END = -4, // dummy member to indicate the event end
|
||||
|
||||
EVENT_RESUME = 1, // trigger rest of event
|
||||
};
|
||||
|
||||
// DialogueHelper (imported from SD)
|
||||
|
||||
struct DialogueEntry
|
||||
{
|
||||
int32 TextEntry; ///< To be said text entry
|
||||
int32 SayerEntry; ///< Entry of the mob who should say
|
||||
uint32 SayTimer; ///< Time delay until next text of array is said (0 stops)
|
||||
};
|
||||
|
||||
class DialogueHelper
|
||||
{
|
||||
public:
|
||||
// The array MUST be terminated by {0, 0, 0}
|
||||
DialogueHelper(DialogueEntry const* dialogueArray) :
|
||||
_dialogueArray(dialogueArray),
|
||||
_currentEntry(NULL),
|
||||
_actionTimer(0)
|
||||
{ }
|
||||
// The array MUST be terminated by {0, 0, 0, 0, 0}
|
||||
|
||||
/// Function to initialize the dialogue helper for instances. If not used with instances, GetSpeakerByEntry MUST be overwritten to obtain the speakers
|
||||
/// Set if take first entries or second entries
|
||||
|
||||
void StartNextDialogueText(int32 textEntry)
|
||||
{
|
||||
// Find textEntry
|
||||
bool found = false;
|
||||
|
||||
for (DialogueEntry const* entry = _dialogueArray; entry->TextEntry; ++entry)
|
||||
{
|
||||
if (entry->TextEntry == textEntry)
|
||||
{
|
||||
_currentEntry = entry;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return;
|
||||
|
||||
DoNextDialogueStep();
|
||||
}
|
||||
|
||||
void DialogueUpdate(uint32 diff)
|
||||
{
|
||||
if (_actionTimer)
|
||||
{
|
||||
if (_actionTimer <= diff)
|
||||
DoNextDialogueStep();
|
||||
else
|
||||
_actionTimer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Will be called when a dialogue step was done
|
||||
virtual void JustDidDialogueStep(int32 /*entry*/) { }
|
||||
/// Will be called to get a speaker, MUST be implemented if not used in instances
|
||||
virtual Creature* GetSpeakerByEntry(int32 /*entry*/) { return NULL; }
|
||||
|
||||
private:
|
||||
void DoNextDialogueStep()
|
||||
{
|
||||
// Last Dialogue Entry done?
|
||||
if (!_currentEntry || !_currentEntry->TextEntry)
|
||||
{
|
||||
_actionTimer = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get Text, SpeakerEntry and Timer
|
||||
int32 textEntry = _currentEntry->TextEntry;
|
||||
uint32 sayerEntry = _currentEntry->SayerEntry;
|
||||
_actionTimer = _currentEntry->SayTimer;
|
||||
|
||||
// Simulate Case
|
||||
if (sayerEntry && textEntry >= 0)
|
||||
{
|
||||
// Use Speaker if directly provided
|
||||
if (Creature* speaker = GetSpeakerByEntry(sayerEntry))
|
||||
speaker->AI()->Talk(textEntry);
|
||||
}
|
||||
|
||||
JustDidDialogueStep(_currentEntry->TextEntry);
|
||||
|
||||
// Increment position
|
||||
++_currentEntry;
|
||||
}
|
||||
|
||||
DialogueEntry const* _dialogueArray;
|
||||
DialogueEntry const* _currentEntry;
|
||||
|
||||
uint32 _actionTimer;
|
||||
};
|
||||
|
||||
const DialogueEntry introDialogue[] =
|
||||
{
|
||||
{SAY_REACH_ALTAR_1, NPC_RANSHALLA, 2000},
|
||||
{SAY_REACH_ALTAR_2, NPC_RANSHALLA, 3000},
|
||||
{NPC_RANSHALLA, 0, 0}, // start the altar channeling
|
||||
{SAY_PRIESTESS_ALTAR_3, NPC_PRIESTESS_DATA_2, 1000},
|
||||
{SAY_PRIESTESS_ALTAR_4, NPC_PRIESTESS_DATA_1, 4000},
|
||||
{SAY_RANSHALLA_ALTAR_5, NPC_RANSHALLA, 4000},
|
||||
{SAY_RANSHALLA_ALTAR_6, NPC_RANSHALLA, 4000}, // start the escort here
|
||||
{SAY_PRIESTESS_ALTAR_7, NPC_PRIESTESS_DATA_2, 4000},
|
||||
{SAY_PRIESTESS_ALTAR_8, NPC_PRIESTESS_DATA_2, 5000}, // show the gem
|
||||
{GO_ELUNE_GEM, 0, 5000},
|
||||
{SAY_PRIESTESS_ALTAR_9, NPC_PRIESTESS_DATA_1, 4000}, // move priestess 1 near me
|
||||
{NPC_PRIESTESS_DATA_1, 0, 3000},
|
||||
{SAY_PRIESTESS_ALTAR_10, NPC_PRIESTESS_DATA_1, 5000},
|
||||
{SAY_PRIESTESS_ALTAR_11, NPC_PRIESTESS_DATA_1, 4000},
|
||||
{SAY_PRIESTESS_ALTAR_12, NPC_PRIESTESS_DATA_1, 5000},
|
||||
{SAY_PRIESTESS_ALTAR_13, NPC_PRIESTESS_DATA_1, 8000}, // summon voice and guard of elune
|
||||
{NPC_VOICE_ELUNE, 0, 12000},
|
||||
{SAY_VOICE_ALTAR_15, NPC_VOICE_ELUNE, 5000}, // move priestess 2 near me
|
||||
{NPC_PRIESTESS_DATA_2, 0, 3000},
|
||||
{SAY_PRIESTESS_ALTAR_16, NPC_PRIESTESS_DATA_2, 4000},
|
||||
{SAY_PRIESTESS_ALTAR_17, NPC_PRIESTESS_DATA_2, 6000},
|
||||
{SAY_PRIESTESS_ALTAR_18, NPC_PRIESTESS_DATA_1, 5000},
|
||||
{SAY_PRIESTESS_ALTAR_19, NPC_PRIESTESS_DATA_1, 3000}, // move the owlbeast
|
||||
{NPC_GUARDIAN_ELUNE, 0, 2000},
|
||||
{SAY_PRIESTESS_ALTAR_20, NPC_PRIESTESS_DATA_1, 4000}, // move the first priestess up
|
||||
{SAY_PRIESTESS_ALTAR_21, NPC_PRIESTESS_DATA_2, 10000}, // move second priestess up
|
||||
{DATA_MOVE_PRIESTESS, 0, 6000}, // despawn the gem
|
||||
{DATA_EVENT_END, 0, 2000}, // turn towards the player
|
||||
{SAY_RANSHALLA_END_2, NPC_RANSHALLA, 0},
|
||||
{0, 0, 0},
|
||||
};
|
||||
|
||||
static Position wingThicketLocations[] =
|
||||
{
|
||||
{5515.98f, -4903.43f, 846.30f, 4.58f}, // 0 right priestess summon loc
|
||||
{5501.94f, -4920.20f, 848.69f, 6.15f}, // 1 left priestess summon loc
|
||||
{5497.35f, -4906.49f, 850.83f, 2.76f}, // 2 guard of elune summon loc
|
||||
{5518.38f, -4913.47f, 845.57f, 0.00f}, // 3 right priestess move loc
|
||||
{5510.36f, -4921.17f, 846.33f, 0.00f}, // 4 left priestess move loc
|
||||
{5511.31f, -4913.82f, 847.17f, 0.00f}, // 5 guard of elune move loc
|
||||
{5518.51f, -4917.56f, 845.23f, 0.00f}, // 6 right priestess second move loc
|
||||
{5514.40f, -4921.16f, 845.49f, 0.00f} // 7 left priestess second move loc
|
||||
};
|
||||
|
||||
/*#####
|
||||
# npc_ranshalla
|
||||
#####*/
|
||||
|
||||
class npc_ranshalla : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ranshalla() : CreatureScript("npc_ranshalla") { }
|
||||
bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest)
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_GUARDIANS_ALTAR)
|
||||
{
|
||||
creature->AI()->Talk(SAY_QUEST_START);
|
||||
creature->setFaction(FACTION_ESCORT_A_NEUTRAL_PASSIVE);
|
||||
|
||||
if (npc_ranshallaAI* escortAI = dynamic_cast<npc_ranshallaAI*>(creature->AI()))
|
||||
escortAI->Start(false, false, player->GetGUID(), quest);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_ranshallaAI(creature);
|
||||
}
|
||||
|
||||
struct npc_ranshallaAI : public npc_escortAI, private DialogueHelper
|
||||
{
|
||||
npc_ranshallaAI(Creature* creature) : npc_escortAI(creature),
|
||||
DialogueHelper(introDialogue)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
uint32 _delayTimer;
|
||||
|
||||
uint64 _firstPriestessGUID;
|
||||
uint64 _secondPriestessGUID;
|
||||
uint64 _guardEluneGUID;
|
||||
uint64 _voiceEluneGUID;
|
||||
uint64 _altarGUID;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_delayTimer = 0;
|
||||
}
|
||||
|
||||
// Called when the player activates the torch / altar
|
||||
void DoContinueEscort(bool isAltarWaypoint = false)
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
|
||||
if (isAltarWaypoint)
|
||||
Talk(SAY_RANSHALLA_ALTAR_1);
|
||||
else
|
||||
Talk(SAY_AFTER_TORCH);
|
||||
|
||||
_delayTimer = 2000;
|
||||
}
|
||||
|
||||
// Called when Ranshalla starts to channel on a torch / altar
|
||||
void DoChannelTorchSpell(bool isAltarWaypoint = false)
|
||||
{
|
||||
// Check if we are using the fire or the altar and remove the no_interact flag
|
||||
if (isAltarWaypoint)
|
||||
{
|
||||
if (GameObject* go = GetClosestGameObjectWithEntry(me, GO_ELUNE_ALTAR, 10.0f))
|
||||
{
|
||||
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
me->SetFacingToObject(go);
|
||||
_altarGUID = go->GetGUID();
|
||||
}
|
||||
}
|
||||
else if (GameObject* go = GetClosestGameObjectWithEntry(me, GO_ELUNE_FIRE, 10.0f))
|
||||
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
|
||||
// Yell and set escort to pause
|
||||
Talk(SAY_REACH_TORCH);
|
||||
Talk(EMOTE_CHANT_SPELL);
|
||||
SetEscortPaused(true);
|
||||
DoCast(me, SPELL_LIGHT_TORCH);
|
||||
}
|
||||
|
||||
void DoSummonPriestess()
|
||||
{
|
||||
// Summon 2 Elune priestess and make each of them move to a different spot
|
||||
if (Creature* priestess = me->SummonCreature(NPC_PRIESTESS_ELUNE, wingThicketLocations[0].m_positionX, wingThicketLocations[0].m_positionY, wingThicketLocations[0].m_positionZ, wingThicketLocations[0].m_orientation, TEMPSUMMON_CORPSE_DESPAWN, 0))
|
||||
{
|
||||
priestess->GetMotionMaster()->MovePoint(0, wingThicketLocations[3].m_positionX, wingThicketLocations[3].m_positionY, wingThicketLocations[3].m_positionZ);
|
||||
_firstPriestessGUID = priestess->GetGUID();
|
||||
}
|
||||
if (Creature* priestess = me->SummonCreature(NPC_PRIESTESS_ELUNE, wingThicketLocations[1].m_positionX, wingThicketLocations[1].m_positionY, wingThicketLocations[1].m_positionZ, wingThicketLocations[1].m_orientation, TEMPSUMMON_CORPSE_DESPAWN, 0))
|
||||
{
|
||||
// Left priestess should have a distinct move point because she is the one who starts the dialogue at point reach
|
||||
priestess->GetMotionMaster()->MovePoint(1, wingThicketLocations[4].m_positionX, wingThicketLocations[4].m_positionY, wingThicketLocations[4].m_positionZ);
|
||||
_secondPriestessGUID = priestess->GetGUID();
|
||||
}
|
||||
}
|
||||
|
||||
void SummonedMovementInform(Creature* summoned, uint32 type, uint32 pointId)
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE || summoned->GetEntry() != NPC_PRIESTESS_ELUNE || pointId != 1)
|
||||
return;
|
||||
|
||||
// Start the dialogue when the priestess reach the altar (they should both reach the point in the same time)
|
||||
StartNextDialogueText(SAY_PRIESTESS_ALTAR_3);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 pointId)
|
||||
{
|
||||
switch (pointId)
|
||||
{
|
||||
case 3:
|
||||
Talk(SAY_ENTER_OWL_THICKET);
|
||||
break;
|
||||
case 10: // Cavern 1
|
||||
case 15: // Cavern 2
|
||||
case 20: // Cavern 3
|
||||
case 25: // Cavern 4
|
||||
case 36: // Cavern 5
|
||||
DoChannelTorchSpell();
|
||||
break;
|
||||
case 39:
|
||||
StartNextDialogueText(SAY_REACH_ALTAR_1);
|
||||
SetEscortPaused(true);
|
||||
break;
|
||||
case 41:
|
||||
{
|
||||
// Search for all nearest lights and respawn them
|
||||
std::list<GameObject*> eluneLights;
|
||||
GetGameObjectListWithEntryInGrid(eluneLights, me, GO_ELUNE_LIGHT, 20.0f);
|
||||
for (std::list<GameObject*>::const_iterator itr = eluneLights.begin(); itr != eluneLights.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->isSpawned())
|
||||
continue;
|
||||
|
||||
(*itr)->SetRespawnTime(115);
|
||||
(*itr)->Refresh();
|
||||
}
|
||||
|
||||
if (GameObject* altar = me->GetMap()->GetGameObject(_altarGUID))
|
||||
me->SetFacingToObject(altar);
|
||||
break;
|
||||
}
|
||||
case 42:
|
||||
// Summon the 2 priestess
|
||||
SetEscortPaused(true);
|
||||
DoSummonPriestess();
|
||||
Talk(SAY_RANSHALLA_ALTAR_2);
|
||||
events.ScheduleEvent(EVENT_RESUME, 2000);
|
||||
break;
|
||||
case 44:
|
||||
// Stop the escort and turn towards the altar
|
||||
SetEscortPaused(true);
|
||||
if (GameObject* altar = me->GetMap()->GetGameObject(_altarGUID))
|
||||
me->SetFacingToObject(altar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustDidDialogueStep(int32 entry)
|
||||
{
|
||||
switch (entry)
|
||||
{
|
||||
case NPC_RANSHALLA:
|
||||
// Start the altar channeling
|
||||
DoChannelTorchSpell(true);
|
||||
break;
|
||||
case SAY_RANSHALLA_ALTAR_6:
|
||||
SetEscortPaused(false);
|
||||
break;
|
||||
case SAY_PRIESTESS_ALTAR_8:
|
||||
// make the gem respawn
|
||||
if (GameObject* gem = GetClosestGameObjectWithEntry(me, GO_ELUNE_GEM, 10.0f))
|
||||
{
|
||||
if (gem->isSpawned())
|
||||
break;
|
||||
|
||||
gem->SetRespawnTime(90);
|
||||
gem->Refresh();
|
||||
}
|
||||
break;
|
||||
case SAY_PRIESTESS_ALTAR_9:
|
||||
// move near the escort npc
|
||||
if (Creature* priestess = me->GetMap()->GetCreature(_firstPriestessGUID))
|
||||
priestess->GetMotionMaster()->MovePoint(0, wingThicketLocations[6].m_positionX, wingThicketLocations[6].m_positionY, wingThicketLocations[6].m_positionZ);
|
||||
break;
|
||||
case SAY_PRIESTESS_ALTAR_13:
|
||||
// summon the Guardian of Elune
|
||||
if (Creature* guard = me->SummonCreature(NPC_GUARDIAN_ELUNE, wingThicketLocations[2].m_positionX, wingThicketLocations[2].m_positionY, wingThicketLocations[2].m_positionZ, wingThicketLocations[2].m_orientation, TEMPSUMMON_CORPSE_DESPAWN, 0))
|
||||
{
|
||||
guard->GetMotionMaster()->MovePoint(0, wingThicketLocations[5].m_positionX, wingThicketLocations[5].m_positionY, wingThicketLocations[5].m_positionZ);
|
||||
_guardEluneGUID = guard->GetGUID();
|
||||
}
|
||||
// summon the Voice of Elune
|
||||
if (GameObject* altar = me->GetMap()->GetGameObject(_altarGUID))
|
||||
{
|
||||
if (Creature* voice = me->SummonCreature(NPC_VOICE_ELUNE, altar->GetPositionX(), altar->GetPositionY(), altar->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 30000))
|
||||
_voiceEluneGUID = voice->GetGUID();
|
||||
}
|
||||
break;
|
||||
case SAY_VOICE_ALTAR_15:
|
||||
// move near the escort npc and continue dialogue
|
||||
if (Creature* priestess = me->GetMap()->GetCreature(_secondPriestessGUID))
|
||||
{
|
||||
priestess->AI()->Talk(SAY_PRIESTESS_ALTAR_14);
|
||||
priestess->GetMotionMaster()->MovePoint(0, wingThicketLocations[7].m_positionX, wingThicketLocations[7].m_positionY, wingThicketLocations[7].m_positionZ);
|
||||
}
|
||||
break;
|
||||
case SAY_PRIESTESS_ALTAR_19:
|
||||
// make the voice of elune leave
|
||||
if (Creature* guard = me->GetMap()->GetCreature(_guardEluneGUID))
|
||||
{
|
||||
guard->GetMotionMaster()->MovePoint(0, wingThicketLocations[2].m_positionX, wingThicketLocations[2].m_positionY, wingThicketLocations[2].m_positionZ);
|
||||
guard->DespawnOrUnsummon(4000);
|
||||
}
|
||||
break;
|
||||
case SAY_PRIESTESS_ALTAR_20:
|
||||
// make the first priestess leave
|
||||
if (Creature* priestess = me->GetMap()->GetCreature(_firstPriestessGUID))
|
||||
{
|
||||
priestess->GetMotionMaster()->MovePoint(0, wingThicketLocations[0].m_positionX, wingThicketLocations[0].m_positionY, wingThicketLocations[0].m_positionZ);
|
||||
priestess->DespawnOrUnsummon(4000);
|
||||
}
|
||||
break;
|
||||
case SAY_PRIESTESS_ALTAR_21:
|
||||
// make the second priestess leave
|
||||
if (Creature* priestess = me->GetMap()->GetCreature(_secondPriestessGUID))
|
||||
{
|
||||
priestess->GetMotionMaster()->MovePoint(0, wingThicketLocations[1].m_positionX, wingThicketLocations[1].m_positionY, wingThicketLocations[1].m_positionZ);
|
||||
priestess->DespawnOrUnsummon(4000);
|
||||
}
|
||||
break;
|
||||
case DATA_EVENT_END:
|
||||
// Turn towards the player
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
{
|
||||
me->SetFacingToObject(player);
|
||||
Talk(SAY_RANSHALLA_END_1, player);
|
||||
}
|
||||
break;
|
||||
case SAY_RANSHALLA_END_2:
|
||||
// Turn towards the altar and kneel - quest complete
|
||||
if (GameObject* altar = me->GetMap()->GetGameObject(_altarGUID))
|
||||
{
|
||||
me->SetFacingToObject(altar);
|
||||
altar->ResetDoorOrButton();
|
||||
}
|
||||
me->SetStandState(UNIT_STAND_STATE_KNEEL);
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
{
|
||||
player->GroupEventHappens(QUEST_GUARDIANS_ALTAR, me);
|
||||
Talk(SAY_RANSHALLA_END_2, player);
|
||||
}
|
||||
me->DespawnOrUnsummon(4000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Creature* GetSpeakerByEntry(int32 entry)
|
||||
{
|
||||
switch (entry)
|
||||
{
|
||||
case NPC_RANSHALLA:
|
||||
return me;
|
||||
case NPC_VOICE_ELUNE:
|
||||
return me->GetMap()->GetCreature(_voiceEluneGUID);
|
||||
case NPC_PRIESTESS_DATA_1:
|
||||
return me->GetMap()->GetCreature(_firstPriestessGUID);
|
||||
case NPC_PRIESTESS_DATA_2:
|
||||
return me->GetMap()->GetCreature(_secondPriestessGUID);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void UpdateEscortAI(uint32 diff)
|
||||
{
|
||||
DialogueUpdate(diff);
|
||||
|
||||
if (_delayTimer)
|
||||
{
|
||||
if (_delayTimer <= diff)
|
||||
{
|
||||
SetEscortPaused(false);
|
||||
_delayTimer = 0;
|
||||
}
|
||||
else
|
||||
_delayTimer -= diff;
|
||||
}
|
||||
events.Update(diff);
|
||||
if (events.ExecuteEvent() == EVENT_RESUME)
|
||||
StartNextDialogueText(SAY_PRIESTESS_ALTAR_3);
|
||||
|
||||
npc_escortAI::UpdateEscortAI(diff);
|
||||
}
|
||||
private:
|
||||
EventMap events;
|
||||
};
|
||||
};
|
||||
|
||||
/*#####
|
||||
# go_elune_fire
|
||||
#####*/
|
||||
|
||||
class go_elune_fire : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_elune_fire() : GameObjectScript("go_elune_fire") { }
|
||||
bool OnGossipHello(Player* /*player*/, GameObject* go)
|
||||
{
|
||||
// Check if we are using the torches or the altar
|
||||
bool isAltar = false;
|
||||
|
||||
if (go->GetEntry() == GO_ELUNE_ALTAR)
|
||||
isAltar = true;
|
||||
|
||||
if (Creature* ranshalla = GetClosestCreatureWithEntry(go, NPC_RANSHALLA, 10.0f))
|
||||
{
|
||||
if (npc_ranshalla::npc_ranshallaAI* escortAI = dynamic_cast<npc_ranshalla::npc_ranshallaAI*>(ranshalla->AI()))
|
||||
escortAI->DoContinueEscort(isAltar);
|
||||
}
|
||||
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_winterspring()
|
||||
{
|
||||
// Ours
|
||||
new npc_stave_of_the_ancients();
|
||||
|
||||
// Theirs
|
||||
new npc_rivern_frostwind();
|
||||
new npc_ranshalla();
|
||||
new go_elune_fire();
|
||||
}
|
||||
Reference in New Issue
Block a user