Merge remote-tracking branch 'origin/master' into mmaps

Conflicts:
	src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp
	src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
This commit is contained in:
Nay
2012-10-07 14:51:21 +01:00
58 changed files with 2762 additions and 408 deletions

View File

@@ -476,12 +476,12 @@ public:
}
else if (map->IsDungeon())
{
Map* map = target->GetMap();
Map* destMap = target->GetMap();
if (map->Instanceable() && map->GetInstanceId() != map->GetInstanceId())
if (destMap->Instanceable() && destMap->GetInstanceId() != map->GetInstanceId())
target->UnbindInstance(map->GetInstanceId(), target->GetDungeonDifficulty(), true);
// we are in instance, and can summon only player in our group with us as lead
// we are in an instance, and can only summon players in our group with us as leader
if (!handler->GetSession()->GetPlayer()->GetGroup() || !target->GetGroup() ||
(target->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()) ||
(handler->GetSession()->GetPlayer()->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()))
@@ -2568,7 +2568,7 @@ public:
{
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
// not let dismiss dead pet
if (pet && pet->isAlive())
if (pet->isAlive())
player->RemovePet(pet, PET_SAVE_NOT_IN_SLOT);
}
}

View File

@@ -27,6 +27,7 @@ EndScriptData */
#include "ScriptedCreature.h"
#include "SpellMgr.h"
#include "scarlet_monastery.h"
#include "LFGMgr.h"
//this texts are already used by 3975 and 3976
enum Says
@@ -562,6 +563,13 @@ public:
CAST_AI(mob_wisp_invis::mob_wisp_invisAI, wisp->AI())->SetType(4);
if (instance)
instance->SetData(DATA_HORSEMAN_EVENT, DONE);
Map::PlayerList const& players = me->GetMap()->GetPlayers();
if (!players.isEmpty())
for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
if (Player* player = i->getSource())
if (player->IsAtGroupRewardDistance(me))
sLFGMgr->RewardDungeonDoneFor(285, player);
}
void SpellHit(Unit* caster, const SpellInfo* spell)

View File

@@ -44,7 +44,7 @@ enum event
{
EVENT_SPAWN = 1,
EVENT_MINI,
EVENT_ROOT,
EVENT_ROOT,
EVENT_BASH,
EVENT_BOLT,
EVENT_AURA
@@ -58,13 +58,13 @@ public:
struct boss_amanitarAI : public BossAI
{
boss_amanitarAI(Creature* creature) : BossAI(creature, DATA_AMANITAR) { }
void Reset()
{
_Reset();
me->SetMeleeDamageSchool(SPELL_SCHOOL_NATURE);
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true);
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true);
summons.DespawnAll();
if (instance)
@@ -119,7 +119,7 @@ public:
{
trigger->DisappearAndDie();
}
else
else
{
u = 1 - u;
trigger->DisappearAndDie();
@@ -143,7 +143,7 @@ public:
{
switch (eventId)
{
case EVENT_SPAWN:
case EVENT_SPAWN:
SpawnAdds();
events.ScheduleEvent(EVENT_SPAWN, 20*IN_MILLISECONDS);
break;
@@ -151,7 +151,7 @@ public:
DoCast(SPELL_MINI);
events.ScheduleEvent(EVENT_MINI, urand(25,30)*IN_MILLISECONDS);
break;
case EVENT_ROOT:
case EVENT_ROOT:
DoCast(SelectTarget(SELECT_TARGET_RANDOM,0, 100, true),SPELL_ENTANGLING_ROOTS,true);
events.ScheduleEvent(EVENT_ROOT, urand(10,15)*IN_MILLISECONDS);
break;
@@ -192,7 +192,7 @@ public:
{
events.Reset();
events.ScheduleEvent(EVENT_AURA, 1*IN_MILLISECONDS);
me->SetDisplayId(me->GetCreatureTemplate()->Modelid2);
DoCast(SPELL_PUTRID_MUSHROOM);

View File

@@ -17,6 +17,7 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "ahnkahet.h"
enum Yells
@@ -30,22 +31,31 @@ enum Yells
enum Spells
{
SPELL_BROOD_PLAGUE = 56130,
H_SPELL_BROOD_PLAGUE = 59467,
H_SPELL_BROOD_RAGE = 59465,
SPELL_ENRAGE = 26662, // Enraged if too far away from home
SPELL_SUMMON_SWARMERS = 56119, //2x 30178 -- 2x every 10secs
SPELL_SUMMON_SWARM_GUARD = 56120, //1x 30176 -- every 25secs
SPELL_BROOD_PLAGUE = 56130,
H_SPELL_BROOD_RAGE = 59465,
SPELL_ENRAGE = 26662, // Enraged if too far away from home
SPELL_SUMMON_SWARMERS = 56119, // 2x 30178 -- 2x every 10secs
SPELL_SUMMON_SWARM_GUARD = 56120, // 1x 30176 -- every 25%
// Spells Adds
SPELL_SPRINT = 56354,
SPELL_GUARDIAN_AURA = 56151
};
enum Creatures
{
MOB_AHNKAHAR_SWARMER = 30178,
MOB_AHNKAHAR_GUARDIAN_ENTRY = 30176
NPC_AHNKAHAR_SWARMER = 30178,
NPC_AHNKAHAR_GUARDIAN = 30176
};
#define ACTION_AHNKAHAR_GUARDIAN_DEAD 1
#define DATA_RESPECT_YOUR_ELDERS 2
enum Events
{
EVENT_PLAGUE = 1,
EVENT_RAGE,
EVENT_SUMMON_SWARMER,
EVENT_CHECK_ENRAGE,
EVENT_SPRINT,
DATA_RESPECT_YOUR_ELDERS
};
class boss_elder_nadox : public CreatureScript
{
@@ -54,32 +64,24 @@ class boss_elder_nadox : public CreatureScript
struct boss_elder_nadoxAI : public ScriptedAI
{
boss_elder_nadoxAI(Creature* creature) : ScriptedAI(creature)
boss_elder_nadoxAI(Creature* creature) : ScriptedAI(creature), summons(me)
{
instance = creature->GetInstanceScript();
}
uint32 uiPlagueTimer;
uint32 uiRagueTimer;
uint32 uiSwarmerSpawnTimer;
uint32 uiGuardSpawnTimer;
uint32 uiEnrageTimer;
bool bGuardSpawned;
bool respectYourElders;
bool GuardianDied;
uint8 AmountHealthModifier;
InstanceScript* instance;
SummonList summons;
EventMap events;
void Reset()
{
uiPlagueTimer = 13000;
uiRagueTimer = 20000;
uiSwarmerSpawnTimer = 10000;
uiGuardSpawnTimer = 25000;
uiEnrageTimer = 5000;
bGuardSpawned = false;
respectYourElders = true;
events.Reset();
summons.DespawnAll();
AmountHealthModifier = 1;
GuardianDied = false;
if (instance)
instance->SetData(DATA_ELDER_NADOX_EVENT, NOT_STARTED);
@@ -91,9 +93,38 @@ class boss_elder_nadox : public CreatureScript
if (instance)
instance->SetData(DATA_ELDER_NADOX_EVENT, IN_PROGRESS);
events.ScheduleEvent(EVENT_PLAGUE, 13*IN_MILLISECONDS);
events.ScheduleEvent(EVENT_SUMMON_SWARMER, 10*IN_MILLISECONDS);
if (IsHeroic())
{
events.ScheduleEvent(EVENT_RAGE, 12*IN_MILLISECONDS);
events.ScheduleEvent(EVENT_CHECK_ENRAGE, 5*IN_MILLISECONDS);
}
}
void KilledUnit(Unit* /*who*/)
void JustSummoned(Creature* summon)
{
summons.Summon(summon);
summon->AI()->DoZoneInCombat();
}
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/)
{
if (summon->GetEntry() == NPC_AHNKAHAR_GUARDIAN)
GuardianDied = true;
}
uint32 GetData(uint32 type)
{
if (type == DATA_RESPECT_YOUR_ELDERS)
return !GuardianDied ? 1 : 0;
return 0;
}
void KilledUnit(Unit* /*victim*/)
{
Talk(SAY_SLAY);
}
@@ -102,87 +133,55 @@ class boss_elder_nadox : public CreatureScript
{
Talk(SAY_DEATH);
summons.DespawnAll();
if (instance)
instance->SetData(DATA_ELDER_NADOX_EVENT, DONE);
}
void DoAction(int32 const action)
{
if (action == ACTION_AHNKAHAR_GUARDIAN_DEAD)
respectYourElders = false;
}
uint32 GetData(uint32 type)
{
if (type == DATA_RESPECT_YOUR_ELDERS)
return respectYourElders ? 1 : 0;
return 0;
}
void UpdateAI(uint32 const diff)
{
if (!UpdateVictim())
return;
if (uiPlagueTimer <= diff)
{
DoCastVictim(SPELL_BROOD_PLAGUE);
uiPlagueTimer = 15000;
}
else
uiPlagueTimer -= diff;
events.Update(diff);
if (IsHeroic())
while (uint32 eventId = events.ExecuteEvent())
{
if (uiRagueTimer <= diff)
switch (eventId)
{
if (Creature* Swarmer = me->FindNearestCreature(MOB_AHNKAHAR_SWARMER, 35.0f))
{
DoCast(Swarmer, H_SPELL_BROOD_RAGE, true);
uiRagueTimer = 15000;
}
case EVENT_PLAGUE:
DoCast(SelectTarget(SELECT_TARGET_RANDOM,0, 100, true),SPELL_BROOD_PLAGUE,true);
events.ScheduleEvent(EVENT_PLAGUE, 15*IN_MILLISECONDS);
break;
case EVENT_RAGE:
DoCast(H_SPELL_BROOD_RAGE);
events.ScheduleEvent(EVENT_RAGE, urand(10*IN_MILLISECONDS, 50*IN_MILLISECONDS));
break;
case EVENT_SUMMON_SWARMER:
DoCast(me, SPELL_SUMMON_SWARMERS);
if (urand(1, 3) == 3) // 33% chance of dialog
Talk(SAY_EGG_SAC);
events.ScheduleEvent(EVENT_SUMMON_SWARMER, 10*IN_MILLISECONDS);
break;
case EVENT_CHECK_ENRAGE:
if (me->HasAura(SPELL_ENRAGE))
return;
if (me->GetPositionZ() < 24.0f)
DoCast(me, SPELL_ENRAGE, true);
events.ScheduleEvent(EVENT_CHECK_ENRAGE, 5*IN_MILLISECONDS);
break;
default:
break;
}
else
uiRagueTimer -= diff;
}
if (uiSwarmerSpawnTimer <= diff)
{
DoCast(me, SPELL_SUMMON_SWARMERS, true);
DoCast(me, SPELL_SUMMON_SWARMERS);
if (urand(1, 3) == 3) // 33% chance of dialog
Talk(SAY_EGG_SAC);
uiSwarmerSpawnTimer = 10000;
}
else
uiSwarmerSpawnTimer -= diff;
if (!bGuardSpawned && uiGuardSpawnTimer <= diff)
if (me->HealthBelowPct(100 - AmountHealthModifier * 25))
{
Talk(EMOTE_HATCHES, me->GetGUID());
DoCast(me, SPELL_SUMMON_SWARM_GUARD);
bGuardSpawned = true;
++AmountHealthModifier;
}
else
uiGuardSpawnTimer -= diff;
if (uiEnrageTimer <= diff)
{
if (me->HasAura(SPELL_ENRAGE, 0))
return;
float x, y, z, o;
me->GetHomePosition(x, y, z, o);
if (z < 24)
if (!me->IsNonMeleeSpellCasted(false))
DoCast(me, SPELL_ENRAGE, true);
uiEnrageTimer = 5000;
}
else
uiEnrageTimer -= diff;
DoMeleeAttackIfReady();
}
@@ -194,12 +193,6 @@ class boss_elder_nadox : public CreatureScript
}
};
enum AddSpells
{
SPELL_SPRINT = 56354,
SPELL_GUARDIAN_AURA = 56151
};
class mob_ahnkahar_nerubian : public CreatureScript
{
public:
@@ -207,50 +200,44 @@ class mob_ahnkahar_nerubian : public CreatureScript
struct mob_ahnkahar_nerubianAI : public ScriptedAI
{
mob_ahnkahar_nerubianAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}
mob_ahnkahar_nerubianAI(Creature* creature) : ScriptedAI(creature) { }
InstanceScript* instance;
uint32 uiSprintTimer;
EventMap events;
void Reset()
{
if (me->GetEntry() == MOB_AHNKAHAR_GUARDIAN_ENTRY)
if (me->GetEntry() == NPC_AHNKAHAR_GUARDIAN)
DoCast(me, SPELL_GUARDIAN_AURA, true);
uiSprintTimer = 10000;
events.ScheduleEvent(EVENT_SPRINT, 13*IN_MILLISECONDS);
}
void JustDied(Unit* /*killer*/)
{
if (me->GetEntry() == MOB_AHNKAHAR_GUARDIAN_ENTRY)
if (Creature* Nadox = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ELDER_NADOX)))
Nadox->AI()->DoAction(ACTION_AHNKAHAR_GUARDIAN_DEAD);
if (me->GetEntry() == NPC_AHNKAHAR_GUARDIAN)
me->RemoveAurasDueToSpell(SPELL_GUARDIAN_AURA);
}
void EnterCombat(Unit* /*who*/) {}
void UpdateAI(uint32 const diff)
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (me->GetEntry() == MOB_AHNKAHAR_GUARDIAN_ENTRY)
me->RemoveAurasDueToSpell(SPELL_GUARDIAN_AURA);
events.Update(diff);
if (instance)
if (instance->GetData(DATA_ELDER_NADOX_EVENT) != IN_PROGRESS)
me->DespawnOrUnsummon();
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
if (uiSprintTimer <= diff)
while (uint32 eventId = events.ExecuteEvent())
{
DoCast(me, SPELL_SPRINT);
uiSprintTimer = 25000;
switch (eventId)
{
case EVENT_SPRINT:
DoCast(me, SPELL_SPRINT);
events.ScheduleEvent(EVENT_SPRINT, 20*IN_MILLISECONDS);
break;
}
}
else
uiSprintTimer -= diff;
DoMeleeAttackIfReady();
}
};
@@ -274,6 +261,7 @@ public:
creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
creature->UpdateAllStats();
}
void Reset() {}
void EnterCombat(Unit* /*who*/) {}
void AttackStart(Unit* /*victim*/) {}
@@ -287,28 +275,68 @@ public:
}
};
class GuardianCheck
{
public:
bool operator()(const WorldObject* target) const
{
if (target->GetEntry() == NPC_AHNKAHAR_GUARDIAN)
return true;
return false;
}
};
class spell_elder_nadox_guardian : public SpellScriptLoader
{
public:
spell_elder_nadox_guardian() : SpellScriptLoader("spell_elder_nadox_guardian") { }
class spell_elder_nadox_guardian_SpellScript : public SpellScript
{
PrepareSpellScript(spell_elder_nadox_guardian_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(GuardianCheck());
}
void Register()
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_elder_nadox_guardian_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_elder_nadox_guardian_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ALLY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_elder_nadox_guardian_SpellScript();
}
};
class achievement_respect_your_elders : public AchievementCriteriaScript
{
public:
achievement_respect_your_elders() : AchievementCriteriaScript("achievement_respect_your_elders") {}
bool OnCheck(Player* /*player*/, Unit* target)
{
if (!target)
return false;
if (Creature* Nadox = target->ToCreature())
if (Nadox->AI()->GetData(DATA_RESPECT_YOUR_ELDERS))
return true;
public:
achievement_respect_your_elders() : AchievementCriteriaScript("achievement_respect_your_elders") {}
bool OnCheck(Player* /*player*/, Unit* target)
{
if (!target)
return false;
}
if (Creature* Nadox = target->ToCreature())
if (Nadox->AI()->GetData(DATA_RESPECT_YOUR_ELDERS))
return true;
return false;
}
};
void AddSC_boss_elder_nadox()
{
new boss_elder_nadox;
new mob_ahnkahar_nerubian;
new mob_nadox_eggs;
new boss_elder_nadox();
new mob_ahnkahar_nerubian();
new mob_nadox_eggs();
new spell_elder_nadox_guardian();
new achievement_respect_your_elders();
}

View File

@@ -51,6 +51,7 @@ set(scripts_STAT_SRCS
Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp
Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp
Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp
Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h
Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp
Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp

View File

@@ -158,9 +158,9 @@ class boss_general_zarithrian : public CreatureScript
{
case EVENT_SUMMON_ADDS:
{
if (Creature* stalker1 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ZARITHIAN_SPAWN_STALKER_1)))
if (Creature* stalker1 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ZARITHRIAN_SPAWN_STALKER_1)))
stalker1->AI()->DoCast(stalker1, SPELL_SUMMON_FLAMECALLER);
if (Creature* stalker2 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ZARITHIAN_SPAWN_STALKER_2)))
if (Creature* stalker2 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ZARITHRIAN_SPAWN_STALKER_2)))
stalker2->AI()->DoCast(stalker2, SPELL_SUMMON_FLAMECALLER);
Talk(SAY_ADDS);
events.ScheduleEvent(EVENT_SUMMON_ADDS, 42000);

File diff suppressed because it is too large Load Diff

View File

@@ -37,18 +37,23 @@ class instance_ruby_sanctum : public InstanceMapScript
{
SetBossNumber(EncounterCount);
LoadDoorData(doorData);
BaltharusTheWarbornGUID = 0;
GeneralZarithrianGUID = 0;
SavianaRagefireGUID = 0;
HalionGUID = 0;
HalionControllerGUID = 0;
BaltharusTheWarbornGUID = 0;
GeneralZarithrianGUID = 0;
SavianaRagefireGUID = 0;
HalionGUID = 0;
TwilightHalionGUID = 0;
OrbCarrierGUID = 0;
OrbRotationFocusGUID = 0;
HalionControllerGUID = 0;
CombatStalkerGUID = 0;
CrystalChannelTargetGUID = 0;
XerestraszaGUID = 0;
BaltharusSharedHealth = 0;
FlameWallsGUID = 0;
FlameRingGUID = 0;
memset(ZarithianSpawnStalkerGUID, 0, 2*sizeof(uint64));
memset(BurningTreeGUID, 0, 4*sizeof(uint64));
XerestraszaGUID = 0;
BaltharusSharedHealth = 0;
FlameWallsGUID = 0;
FlameRingGUID = 0;
memset(ZarithrianSpawnStalkerGUID, 0, 2 * sizeof(uint64));
memset(BurningTreeGUID, 0, 4 * sizeof(uint64));
}
void OnCreatureCreate(Creature* creature)
@@ -67,19 +72,32 @@ class instance_ruby_sanctum : public InstanceMapScript
case NPC_HALION:
HalionGUID = creature->GetGUID();
break;
case NPC_TWILIGHT_HALION:
TwilightHalionGUID = creature->GetGUID();
break;
case NPC_HALION_CONTROLLER:
HalionControllerGUID = creature->GetGUID();
break;
case NPC_ORB_CARRIER:
OrbCarrierGUID = creature->GetGUID();
break;
case NPC_ORB_ROTATION_FOCUS:
OrbRotationFocusGUID = creature->GetGUID();
break;
case NPC_COMBAT_STALKER:
CombatStalkerGUID = creature->GetGUID();
break;
case NPC_BALTHARUS_TARGET:
CrystalChannelTargetGUID = creature->GetGUID();
break;
case NPC_XERESTRASZA:
XerestraszaGUID = creature->GetGUID();
break;
case NPC_ZARITHIAN_SPAWN_STALKER:
if (!ZarithianSpawnStalkerGUID[0])
ZarithianSpawnStalkerGUID[0] = creature->GetGUID();
case NPC_ZARITHRIAN_SPAWN_STALKER:
if (!ZarithrianSpawnStalkerGUID[0])
ZarithrianSpawnStalkerGUID[0] = creature->GetGUID();
else
ZarithianSpawnStalkerGUID[1] = creature->GetGUID();
ZarithrianSpawnStalkerGUID[1] = creature->GetGUID();
break;
default:
break;
@@ -101,6 +119,9 @@ class instance_ruby_sanctum : public InstanceMapScript
case GO_FLAME_RING:
FlameRingGUID = go->GetGUID();
break;
case GO_TWILIGHT_FLAME_RING:
TwilightFlameRingGUID = go->GetGUID();
break;
case GO_BURNING_TREE_1:
BurningTreeGUID[0] = go->GetGUID();
if (GetBossState(DATA_GENERAL_ZARITHRIAN) == DONE)
@@ -152,24 +173,30 @@ class instance_ruby_sanctum : public InstanceMapScript
return SavianaRagefireGUID;
case DATA_GENERAL_ZARITHRIAN:
return GeneralZarithrianGUID;
case DATA_ZARITHIAN_SPAWN_STALKER_1:
return ZarithianSpawnStalkerGUID[0];
case DATA_ZARITHIAN_SPAWN_STALKER_2:
return ZarithianSpawnStalkerGUID[1];
case DATA_ZARITHRIAN_SPAWN_STALKER_1:
case DATA_ZARITHRIAN_SPAWN_STALKER_2:
return ZarithrianSpawnStalkerGUID[type - DATA_ZARITHRIAN_SPAWN_STALKER_1];
case DATA_HALION:
return HalionGUID;
case DATA_TWILIGHT_HALION:
return TwilightHalionGUID;
case DATA_ORB_CARRIER:
return OrbCarrierGUID;
case DATA_ORB_ROTATION_FOCUS:
return OrbRotationFocusGUID;
case DATA_HALION_CONTROLLER:
return HalionControllerGUID;
case DATA_BURNING_TREE_1:
return BurningTreeGUID[0];
case DATA_BURNING_TREE_2:
return BurningTreeGUID[1];
case DATA_BURNING_TREE_3:
return BurningTreeGUID[2];
case DATA_BURNING_TREE_4:
return BurningTreeGUID[3];
return BurningTreeGUID[type - DATA_BURNING_TREE_1];
case DATA_FLAME_RING:
return FlameRingGUID;
case DATA_TWILIGHT_FLAME_RING:
return TwilightFlameRingGUID;
case DATA_COMBAT_STALKER:
return CombatStalkerGUID;
default:
break;
}
@@ -180,7 +207,14 @@ class instance_ruby_sanctum : public InstanceMapScript
bool SetBossState(uint32 type, EncounterState state)
{
if (!InstanceScript::SetBossState(type, state))
{
// Summon Halion on instance loading if conditions are met. Without those lines,
// InstanceScript::SetBossState returns false, thus preventing the switch from being called.
if (type == DATA_HALION && state != DONE && GetBossState(DATA_GENERAL_ZARITHRIAN) == DONE && !GetData64(DATA_HALION_CONTROLLER))
if (Creature* halionController = instance->SummonCreature(NPC_HALION_CONTROLLER, HalionControllerSpawnPos))
halionController->AI()->DoAction(ACTION_INTRO_HALION);
return false;
}
switch (type)
{
@@ -205,20 +239,30 @@ class instance_ruby_sanctum : public InstanceMapScript
break;
}
case DATA_GENERAL_ZARITHRIAN:
{
if (GetBossState(DATA_SAVIANA_RAGEFIRE) == DONE && GetBossState(DATA_BALTHARUS_THE_WARBORN) == DONE)
HandleGameObject(FlameWallsGUID, state != IN_PROGRESS);
/*
if (state == DONE)
// Not called at instance loading, no big deal.
if (state == DONE && GetBossState(DATA_HALION) != DONE)
if (Creature* halionController = instance->SummonCreature(NPC_HALION_CONTROLLER, HalionControllerSpawnPos))
halionController->AI()->DoAction(ACTION_INTRO_HALION);
*/
break;
}
case DATA_HALION:
/*
if (state != IN_PROGRESS)
{
DoUpdateWorldState(WORLDSTATE_CORPOREALITY_TOGGLE, 0);
DoUpdateWorldState(WORLDSTATE_CORPOREALITY_TWILIGHT, 0);
DoUpdateWorldState(WORLDSTATE_CORPOREALITY_MATERIAL, 0);
// Reopen rings on wipe or success
if (state == DONE || state == FAIL)
{
HandleGameObject(FlameRingGUID, true);
*/
HandleGameObject(TwilightFlameRingGUID, true);
}
break;
}
default:
break;
}
@@ -228,25 +272,18 @@ class instance_ruby_sanctum : public InstanceMapScript
void SetData(uint32 type, uint32 data)
{
switch (type)
{
case DATA_BALTHARUS_SHARED_HEALTH:
BaltharusSharedHealth = data;
break;
}
if (type != DATA_BALTHARUS_SHARED_HEALTH)
return;
BaltharusSharedHealth = data;
}
uint32 GetData(uint32 type)
{
switch (type)
{
case DATA_BALTHARUS_SHARED_HEALTH:
return BaltharusSharedHealth;
default:
break;
}
if (type != DATA_BALTHARUS_SHARED_HEALTH)
return 0;
return 0;
return BaltharusSharedHealth;
}
std::string GetSaveData()
@@ -260,6 +297,13 @@ class instance_ruby_sanctum : public InstanceMapScript
return saveStream.str();
}
void FillInitialWorldStates(WorldPacket& data)
{
data << uint32(WORLDSTATE_CORPOREALITY_MATERIAL) << uint32(50);
data << uint32(WORLDSTATE_CORPOREALITY_TWILIGHT) << uint32(50);
data << uint32(WORLDSTATE_CORPOREALITY_TOGGLE) << uint32(0);
}
void Load(char const* str)
{
if (!str)
@@ -298,13 +342,19 @@ class instance_ruby_sanctum : public InstanceMapScript
uint64 GeneralZarithrianGUID;
uint64 SavianaRagefireGUID;
uint64 HalionGUID;
uint64 TwilightHalionGUID;
uint64 HalionControllerGUID;
uint64 OrbCarrierGUID;
uint64 OrbRotationFocusGUID;
uint64 CrystalChannelTargetGUID;
uint64 XerestraszaGUID;
uint64 FlameWallsGUID;
uint64 ZarithianSpawnStalkerGUID[2];
uint64 ZarithrianSpawnStalkerGUID[2];
uint64 BurningTreeGUID[4];
uint64 FlameRingGUID;
uint64 TwilightFlameRingGUID;
uint64 CombatStalkerGUID;
uint32 BaltharusSharedHealth;
};

View File

@@ -21,6 +21,7 @@
#include "SpellScript.h"
#include "Map.h"
#include "Creature.h"
#include "GameObjectAI.h"
#define RSScriptName "instance_ruby_sanctum"
uint32 const EncounterCount = 4;
@@ -36,17 +37,22 @@ enum DataTypes
DATA_HALION = 3,
// Etc
DATA_XERESTRASZA = 4,
DATA_CRYSTAL_CHANNEL_TARGET = 5,
DATA_BALTHARUS_SHARED_HEALTH = 6,
DATA_ZARITHIAN_SPAWN_STALKER_1 = 7,
DATA_ZARITHIAN_SPAWN_STALKER_2 = 8,
DATA_HALION_CONTROLLER = 9,
DATA_BURNING_TREE_1 = 10,
DATA_BURNING_TREE_2 = 11,
DATA_BURNING_TREE_3 = 12,
DATA_BURNING_TREE_4 = 13,
DATA_FLAME_RING = 14,
DATA_TWILIGHT_HALION = 4,
DATA_XERESTRASZA = 5,
DATA_CRYSTAL_CHANNEL_TARGET = 6,
DATA_BALTHARUS_SHARED_HEALTH = 7,
DATA_ZARITHRIAN_SPAWN_STALKER_1 = 8,
DATA_ZARITHRIAN_SPAWN_STALKER_2 = 9,
DATA_HALION_CONTROLLER = 10,
DATA_ORB_CARRIER = 11,
DATA_ORB_ROTATION_FOCUS = 12,
DATA_BURNING_TREE_1 = 13,
DATA_BURNING_TREE_2 = 14,
DATA_BURNING_TREE_3 = 15,
DATA_BURNING_TREE_4 = 16,
DATA_FLAME_RING = 17,
DATA_TWILIGHT_FLAME_RING = 18,
DATA_COMBAT_STALKER = 19,
};
enum SharedActions
@@ -66,14 +72,14 @@ enum CreaturesIds
// General Zarithrian
NPC_GENERAL_ZARITHRIAN = 39746,
NPC_ONYX_FLAMECALLER = 39814,
NPC_ZARITHIAN_SPAWN_STALKER = 39794,
NPC_ZARITHRIAN_SPAWN_STALKER = 39794,
// Saviana Ragefire
NPC_SAVIANA_RAGEFIRE = 39747,
// Halion
NPC_HALION = 39863,
NPC_HALION_TWILIGHT = 40142,
NPC_TWILIGHT_HALION = 40142,
NPC_HALION_CONTROLLER = 40146,
NPC_LIVING_INFERNO = 40681,
NPC_LIVING_EMBER = 40683,
@@ -81,6 +87,8 @@ enum CreaturesIds
NPC_ORB_ROTATION_FOCUS = 40091,
NPC_SHADOW_ORB_N = 40083,
NPC_SHADOW_ORB_S = 40100,
NPC_SHADOW_ORB_E = 40468,
NPC_SHADOW_ORB_W = 40469,
NPC_METEOR_STRIKE_MARK = 40029,
NPC_METEOR_STRIKE_NORTH = 40041,
NPC_METEOR_STRIKE_EAST = 40042,
@@ -88,6 +96,8 @@ enum CreaturesIds
NPC_METEOR_STRIKE_SOUTH = 40044,
NPC_METEOR_STRIKE_FLAME = 40055,
NPC_COMBUSTION = 40001,
NPC_CONSUMPTION = 40135,
NPC_COMBAT_STALKER = 40151,
// Xerestrasza
NPC_XERESTRASZA = 40429,
@@ -101,6 +111,7 @@ enum GameObjectsIds
GO_FIRE_FIELD = 203005,
GO_FLAME_WALLS = 203006,
GO_FLAME_RING = 203007,
GO_TWILIGHT_FLAME_RING = 203624,
GO_BURNING_TREE_1 = 203034,
GO_BURNING_TREE_2 = 203035,
GO_BURNING_TREE_3 = 203036,
@@ -114,6 +125,11 @@ enum WorldStatesRS
WORLDSTATE_CORPOREALITY_TOGGLE = 5051,
};
enum InstanceSpell
{
SPELL_BERSERK = 26662,
};
template<class AI>
CreatureAI* GetRubySanctumAI(Creature* creature)
{
@@ -124,4 +140,15 @@ CreatureAI* GetRubySanctumAI(Creature* creature)
return NULL;
}
template<class AI>
GameObjectAI* GetRubySanctumAI(GameObject* go)
{
if (InstanceMap* instance = go->GetMap()->ToInstanceMap())
if (instance->GetInstanceScript())
if (instance->GetScriptId() == sObjectMgr->GetScriptId(RSScriptName))
return new AI(go);
return NULL;
}
#endif // RUBY_SANCTUM_H_

View File

@@ -105,8 +105,8 @@ public:
void Reset()
{
me->CastSpell(me, SPELL_EVOCATE);
_Reset();
_Reset();
if (instance->GetData(DATA_UROM_PLATAFORM) == 0)
{

View File

@@ -278,7 +278,7 @@ public:
eternos->GetMotionMaster()->MovePoint(0, 943.202f, 1059.35f, 359.967f);
if (Creature* verdisa = instance->GetCreature(verdisaGUID))
verdisa->SetWalk(true),
verdisa->GetMotionMaster()->MovePoint(0, 949.188f, 1032.91f, 359.967f);
verdisa->GetMotionMaster()->MovePoint(0, 949.188f, 1032.91f, 359.967f);
}
void GreaterWhelps()

View File

@@ -108,10 +108,10 @@ class npc_verdisa_beglaristrasz_eternos : public CreatureScript
{
public:
npc_verdisa_beglaristrasz_eternos() : CreatureScript("npc_verdisa_beglaristrasz_eternos") { }
InstanceScript* instance;
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
InstanceScript* instance;
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
{
player->PlayerTalkClass->ClearMenus();
switch (creature->GetEntry())
@@ -245,7 +245,7 @@ public:
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
};
CreatureAI* GetAI(Creature* creature) const
{
return new npc_verdisa_beglaristrasz_eternosAI(creature);
@@ -293,7 +293,7 @@ public:
{
instance = creature->GetInstanceScript();
}
InstanceScript* instance;
uint64 summonerGUID;
@@ -324,9 +324,9 @@ public:
HealthWarningOff = false;
DisableTakeOff = false;
}
void IsSummonedBy(Unit* summoner)
{
{
if (instance->GetBossState(DATA_EREGOS_EVENT) == IN_PROGRESS)
if (Creature* eregos = me->FindNearestCreature(NPC_EREGOS, 450.0f, true))
{
@@ -357,7 +357,7 @@ public:
void UpdateAI(const uint32 diff)
{
if (!(instance->GetBossState(DATA_VAROS_EVENT) == DONE))
{
{
if (me->HasAuraType(SPELL_AURA_CONTROL_VEHICLE))
{
if (!(WelcomeOff))
@@ -380,7 +380,7 @@ public:
{
Talk(WHISPER_DRAKES_ABILITIES, me->GetCreatorGUID());
WelcomeSequelOff = false;
}
}
else WelcomeSequelTimer -= diff;
}
}
@@ -391,10 +391,10 @@ public:
if (!(SpecialOff))
{
if (SpecialTimer <= diff)
{
{
Talk(WHISPER_DRAKES_SPECIAL, me->GetCreatorGUID());
SpecialOff = true;
}
}
else SpecialTimer -= diff;
}
}
@@ -402,25 +402,25 @@ public:
if (me->HasAuraType(SPELL_AURA_CONTROL_VEHICLE))
{
if (!(HealthWarningOff))
{
{
if (me->GetHealthPct() <= 40.0f)
{
Talk(WHISPER_DRAKES_LOWHEALTH, me->GetCreatorGUID());
HealthWarningOff = true;
}
}
}
}
if (me->HasAuraType(SPELL_AURA_CONTROL_VEHICLE))
{
{
if (HealthWarningOff)
{
{
if (WarningTimer <= diff)
{
HealthWarningOff = false;
WarningTimer = 25000;
}
else WarningTimer -= diff;
}
}
}
if (!(me->HasAuraType(SPELL_AURA_CONTROL_VEHICLE)))
{
@@ -433,7 +433,7 @@ public:
me->SetSpeed(MOVE_FLIGHT, 1.0f, true);
Talk(SAY_DRAKES_TAKEOFF);
Position pos;
me->GetPosition(&pos);
me->GetPosition(&pos);
pos.m_positionX += 10.0f;
pos.m_positionY += 10.0f;
pos.m_positionZ += 12.0f;

View File

@@ -255,7 +255,12 @@ class boss_steelbreaker : public CreatureScript
{
DoScriptText(RAND(SAY_STEELBREAKER_DEATH_1, SAY_STEELBREAKER_DEATH_2), me);
if (IsEncounterComplete(instance, me))
instance->SetData(BOSS_ASSEMBLY_OF_IRON, DONE);
{
instance->SetBossState(BOSS_ASSEMBLY_OF_IRON, DONE);
instance->SetBossState(BOSS_STEELBREAKER, DONE);
instance->SetBossState(BOSS_MOLGEIM, DONE);
instance->SetBossState(BOSS_BRUNDIR, DONE);
}
else
me->SetLootRecipient(NULL);
@@ -379,7 +384,12 @@ class boss_runemaster_molgeim : public CreatureScript
{
DoScriptText(RAND(SAY_MOLGEIM_DEATH_1, SAY_MOLGEIM_DEATH_2), me);
if (IsEncounterComplete(instance, me))
instance->SetData(BOSS_ASSEMBLY_OF_IRON, DONE);
{
instance->SetBossState(BOSS_ASSEMBLY_OF_IRON, DONE);
instance->SetBossState(BOSS_STEELBREAKER, DONE);
instance->SetBossState(BOSS_MOLGEIM, DONE);
instance->SetBossState(BOSS_BRUNDIR, DONE);
}
else
me->SetLootRecipient(NULL);
@@ -620,7 +630,12 @@ class boss_stormcaller_brundir : public CreatureScript
{
DoScriptText(RAND(SAY_BRUNDIR_DEATH_1, SAY_BRUNDIR_DEATH_2), me);
if (IsEncounterComplete(instance, me))
instance->SetData(BOSS_ASSEMBLY_OF_IRON, DONE);
{
instance->SetBossState(BOSS_ASSEMBLY_OF_IRON, DONE);
instance->SetBossState(BOSS_STEELBREAKER, DONE);
instance->SetBossState(BOSS_MOLGEIM, DONE);
instance->SetBossState(BOSS_BRUNDIR, DONE);
}
else
me->SetLootRecipient(NULL);

View File

@@ -541,6 +541,11 @@ public:
}
};
enum WgTeleport
{
SPELL_WINTERGRASP_TELEPORT_TRIGGER = 54643,
};
class spell_wintergrasp_defender_teleport : public SpellScriptLoader
{
public:
@@ -554,7 +559,7 @@ public:
{
if (Battlefield* wg = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG))
if (Player* target = GetExplTargetUnit()->ToPlayer())
if (target->GetTeamId() != wg->GetDefenderTeam())
if (target->GetTeamId() != wg->GetDefenderTeam() || target->HasAura(SPELL_WINTERGRASP_TELEPORT_TRIGGER))
return SPELL_FAILED_BAD_TARGETS;
return SPELL_CAST_OK;
}
@@ -571,6 +576,37 @@ public:
}
};
class spell_wintergrasp_defender_teleport_trigger : public SpellScriptLoader
{
public:
spell_wintergrasp_defender_teleport_trigger() : SpellScriptLoader("spell_wintergrasp_defender_teleport_trigger") { }
class spell_wintergrasp_defender_teleport_trigger_SpellScript : public SpellScript
{
PrepareSpellScript(spell_wintergrasp_defender_teleport_trigger_SpellScript);
void HandleDummy(SpellEffIndex /*effindex*/)
{
if (Unit* target = GetHitUnit())
{
WorldLocation loc;
target->GetPosition(&loc);
SetExplTargetDest(loc);
}
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_wintergrasp_defender_teleport_trigger_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_wintergrasp_defender_teleport_trigger_SpellScript();
}
};
void AddSC_wintergrasp()
{
new npc_wg_queue();
@@ -582,4 +618,5 @@ void AddSC_wintergrasp()
new spell_wintergrasp_grab_passenger();
new achievement_wg_didnt_stand_a_chance();
new spell_wintergrasp_defender_teleport();
new spell_wintergrasp_defender_teleport_trigger();
}

View File

@@ -277,27 +277,31 @@ class spell_hun_masters_call : public SpellScriptLoader
return true;
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
if (Unit* ally = GetHitUnit())
if (Player* caster = GetCaster()->ToPlayer())
if (Pet* target = caster->GetPet())
{
TriggerCastFlags castMask = TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_CASTER_AURASTATE);
target->CastSpell(ally, GetEffectValue(), castMask);
target->CastSpell(ally, GetSpellInfo()->Effects[EFFECT_0].CalcValue(), castMask);
}
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
if (Unit* target = GetHitUnit())
{
// Cannot be processed while pet is dead
TriggerCastFlags castMask = TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_CASTER_AURASTATE);
target->CastSpell(target, GetEffectValue(), castMask);
target->CastSpell(target, HUNTER_SPELL_MASTERS_CALL_TRIGGERED, castMask);
// there is a possibility that this effect should access effect 0 (dummy) target, but i dubt that
// it's more likely that on on retail it's possible to call target selector based on dbc values
// anyways, we're using GetExplTargetUnit() here and it's ok
if (Unit* ally = GetExplTargetUnit())
{
target->CastSpell(ally, GetEffectValue(), castMask);
target->CastSpell(ally, GetSpellInfo()->Effects[EFFECT_0].CalcValue(), castMask);
}
}
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_hun_masters_call_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
OnEffectHitTarget += SpellEffectFn(spell_hun_masters_call_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
};

View File

@@ -53,12 +53,14 @@ EndContentData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "GameObjectAI.h"
#include "Spell.h"
/*######
## go_cat_figurine
######*/
enum eCatFigurine
enum CatFigurine
{
SPELL_SUMMON_GHOST_SABER = 5968,
};
@@ -178,7 +180,7 @@ public:
## go_gilded_brazier (Paladin First Trail quest (9678))
######*/
enum eGildedBrazier
enum GildedBrazier
{
NPC_STILLBLADE = 17716,
};
@@ -282,7 +284,7 @@ public:
## go_ethereum_prison
######*/
enum eEthereumPrison
enum EthereumPrison
{
SPELL_REP_LC = 39456,
SPELL_REP_SHAT = 39457,
@@ -367,7 +369,7 @@ public:
## go_resonite_cask
######*/
enum eResoniteCask
enum ResoniteCask
{
NPC_GOGGEROC = 11920
};
@@ -410,7 +412,7 @@ public:
## go_shrine_of_the_birds
######*/
enum eShrineOfTheBirds
enum ShrineOfTheBirds
{
NPC_HAWK_GUARD = 22992,
NPC_EAGLE_GUARD = 22993,
@@ -456,7 +458,7 @@ public:
## go_southfury_moonstone
######*/
enum eSouthfury
enum Southfury
{
NPC_RIZZLE = 23002,
SPELL_BLACKJACK = 39865, //stuns player
@@ -484,7 +486,7 @@ public:
## go_tele_to_dalaran_crystal
######*/
enum eDalaranCrystal
enum DalaranCrystal
{
QUEST_LEARN_LEAVE_RETURN = 12790,
QUEST_TELE_CRYSTAL_FLAG = 12845
@@ -536,7 +538,7 @@ public:
#define GOSSIP_FEL_CRYSTALFORGE_ITEM_5 "Purchase 5 Unstable Flask of the Beast for the cost of 50 Apexis Shards"
#define GOSSIP_FEL_CRYSTALFORGE_ITEM_RETURN "Use the fel crystalforge to make another purchase."
enum eFelCrystalforge
enum FelCrystalforge
{
SPELL_CREATE_1_FLASK_OF_BEAST = 40964,
SPELL_CREATE_5_FLASK_OF_BEAST = 40965,
@@ -595,7 +597,7 @@ public:
#define GOSSIP_BASHIR_CRYSTALFORGE_ITEM_5 "Purchase 5 Unstable Flask of the Sorcerer for the cost of 50 Apexis Shards"
#define GOSSIP_BASHIR_CRYSTALFORGE_ITEM_RETURN "Use the bashir crystalforge to make another purchase."
enum eBashirCrystalforge
enum BashirCrystalforge
{
SPELL_CREATE_1_FLASK_OF_SORCERER = 40968,
SPELL_CREATE_5_FLASK_OF_SORCERER = 40970,
@@ -648,7 +650,7 @@ public:
## matrix_punchograph
######*/
enum eMatrixPunchograph
enum MatrixPunchograph
{
ITEM_WHITE_PUNCH_CARD = 9279,
ITEM_YELLOW_PUNCH_CARD = 9280,
@@ -713,7 +715,7 @@ public:
## go_scourge_cage
######*/
enum eScourgeCage
enum ScourgeCage
{
NPC_SCOURGE_PRISONER = 25610
};
@@ -740,7 +742,7 @@ public:
## go_arcane_prison
######*/
enum eArcanePrison
enum ArcanePrison
{
QUEST_PRISON_BREAK = 11587,
SPELL_ARCANE_PRISONER_KILL_CREDIT = 45456
@@ -787,7 +789,7 @@ public:
## go_jotunheim_cage
######*/
enum eJotunheimCage
enum JotunheimCage
{
NPC_EBON_BLADE_PRISONER_HUMAN = 30186,
NPC_EBON_BLADE_PRISONER_NE = 30194,
@@ -842,7 +844,7 @@ public:
}
};
enum eTableTheka
enum TableTheka
{
GOSSIP_TABLE_THEKA = 1653,
@@ -869,7 +871,7 @@ public:
## go_inconspicuous_landmark
######*/
enum eInconspicuousLandmark
enum InconspicuousLandmark
{
SPELL_SUMMON_PIRATES_TREASURE_AND_TRIGGER_MOB = 11462,
ITEM_CUERGOS_KEY = 9275,
@@ -895,7 +897,7 @@ public:
## go_ethereal_teleport_pad
######*/
enum eEtherealTeleportPad
enum EtherealTeleportPad
{
NPC_IMAGE_WIND_TRADER = 20518,
ITEM_TELEPORTER_POWER_PACK = 28969,
@@ -921,45 +923,105 @@ public:
## go_soulwell
######*/
enum SoulWellData
{
GO_SOUL_WELL_R1 = 181621,
GO_SOUL_WELL_R2 = 193169,
SPELL_IMPROVED_HEALTH_STONE_R1 = 18692,
SPELL_IMPROVED_HEALTH_STONE_R2 = 18693,
SPELL_CREATE_MASTER_HEALTH_STONE_R0 = 34130,
SPELL_CREATE_MASTER_HEALTH_STONE_R1 = 34149,
SPELL_CREATE_MASTER_HEALTH_STONE_R2 = 34150,
SPELL_CREATE_FEL_HEALTH_STONE_R0 = 58890,
SPELL_CREATE_FEL_HEALTH_STONE_R1 = 58896,
SPELL_CREATE_FEL_HEALTH_STONE_R2 = 58898,
};
class go_soulwell : public GameObjectScript
{
public:
go_soulwell() : GameObjectScript("go_soulwell") { }
public:
go_soulwell() : GameObjectScript("go_soulwell") {}
bool OnGossipHello(Player* player, GameObject* go)
{
Unit* caster = go->GetOwner();
if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
return true;
if (!player->IsInSameRaidWith(static_cast<Player*>(caster)))
return true;
// Repeating this at every use is ugly and inefficient. But as long as we don't have proper
// GO scripting with at least On Create and On Update events, the other options are no less
// ugly and hacky.
uint32 newSpell = 0;
if (go->GetEntry() == 193169) // Soulwell for rank 2
struct go_soulwellAI : public GameObjectAI
{
if (caster->HasAura(18693)) // Improved Healthstone rank 2
newSpell = 58898;
else if (caster->HasAura(18692)) // Improved Healthstone rank 1
newSpell = 58896;
else newSpell = 58890;
}
else if (go->GetEntry() == 181621) // Soulwell for rank 1
{
if (caster->HasAura(18693)) // Improved Healthstone rank 2
newSpell = 34150;
else if (caster->HasAura(18692)) // Improved Healthstone rank 1
newSpell = 34149;
else newSpell = 34130;
}
go_soulwellAI(GameObject* go) : GameObjectAI(go)
{
_stoneSpell = 0;
_stoneId = 0;
switch (go->GetEntry())
{
case GO_SOUL_WELL_R1:
_stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R0;
if (Unit* owner = go->GetOwner())
{
if (owner->HasAura(SPELL_IMPROVED_HEALTH_STONE_R1))
_stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R1;
else if (owner->HasAura(SPELL_CREATE_MASTER_HEALTH_STONE_R2))
_stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R2;
}
break;
case GO_SOUL_WELL_R2:
_stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R0;
if (Unit* owner = go->GetOwner())
{
if (owner->HasAura(SPELL_IMPROVED_HEALTH_STONE_R1))
_stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R1;
else if (owner->HasAura(SPELL_CREATE_MASTER_HEALTH_STONE_R2))
_stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R2;
}
break;
}
if (_stoneSpell == 0) // Should never happen
return;
go->AddUse();
player->CastSpell(player, newSpell, true);
return true;
}
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(_stoneSpell);
if (!spellInfo)
return;
_stoneId = spellInfo->Effects[EFFECT_0].ItemType;
}
/// Due to the fact that this GameObject triggers CMSG_GAMEOBJECT_USE
/// _and_ CMSG_GAMEOBJECT_REPORT_USE, this GossipHello hook is called
/// twice. The script's handling is fine as it won't remove two charges
/// on the well. We have to find how to segregate REPORT_USE and USE.
bool GossipHello(Player* player)
{
Unit* owner = go->GetOwner();
if (_stoneSpell == 0 || _stoneId == 0)
return true;
if (!owner || owner->GetTypeId() != TYPEID_PLAYER || !player->IsInSameRaidWith(owner->ToPlayer()))
return true;
// Don't try to add a stone if we already have one.
if (player->HasItemCount(_stoneId, 1))
{
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_stoneSpell))
Spell::SendCastResult(player, spell, 0, SPELL_FAILED_TOO_MANY_OF_ITEM);
return true;
}
owner->CastSpell(player, _stoneSpell, true);
// Item has to actually be created to remove a charge on the well.
if (player->HasItemCount(_stoneId, 1))
go->AddUse();
return false;
}
private:
uint32 _stoneSpell;
uint32 _stoneId;
};
GameObjectAI* GetAI(GameObject* go) const
{
return new go_soulwellAI(go);
}
};
/*######
@@ -967,7 +1029,7 @@ public:
## go_dragonflayer_cage
######*/
enum ePrisonersOfWyrmskull
enum PrisonersOfWyrmskull
{
QUEST_PRISONERS_OF_WYRMSKULL = 11255,
NPC_PRISONER_PRIEST = 24086,
@@ -1017,7 +1079,7 @@ public:
## go_tadpole_cage
######*/
enum eTadpoles
enum Tadpoles
{
QUEST_OH_NOES_THE_TADPOLES = 11560,
NPC_WINTERFIN_TADPOLE = 25201
@@ -1052,7 +1114,7 @@ public:
#define GOSSIP_USE_OUTHOUSE "Use the outhouse."
#define GO_ANDERHOLS_SLIDER_CIDER_NOT_FOUND "Quest item Anderhol's Slider Cider not found."
enum eAmberpineOuthouse
enum AmberpineOuthouse
{
ITEM_ANDERHOLS_SLIDER_CIDER = 37247,
NPC_OUTHOUSE_BUNNY = 27326,
@@ -1114,7 +1176,7 @@ public:
## go_hive_pod
######*/
enum eHives
enum Hives
{
QUEST_HIVE_IN_THE_TOWER = 9544,
NPC_HIVE_AMBUSHER = 13301
@@ -1281,7 +1343,7 @@ public:
## go_midsummer_bonfire
######*/
enum eMidsummerBonfire
enum MidsummerBonfire
{
STAMP_OUT_BONFIRE_QUEST_COMPLETE = 45458,
};