Big re-organization of repository [W.I.P]

This commit is contained in:
Yehonal
2016-08-11 20:25:27 +02:00
parent c62a72c0a8
commit 0f85ce1c54
3016 changed files with 1271 additions and 1 deletions

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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")

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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()
{
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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()
{
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}