mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-18 16:38:42 +01:00
Scripts/Quests: An Apexis Relic, The Relic's Emanation and Guardian of the Monument.
This commit is contained in:
@@ -562,6 +562,564 @@ class go_thunderspike : public GameObjectScript
|
||||
}
|
||||
};
|
||||
|
||||
enum SimonGame
|
||||
{
|
||||
NPC_SIMON_BUNNY = 22923,
|
||||
NPC_APEXIS_GUARDIAN = 22275,
|
||||
|
||||
GO_APEXIS_RELIC = 185890,
|
||||
GO_APEXIS_MONUMENT = 185944,
|
||||
GO_AURA_BLUE = 185872,
|
||||
GO_AURA_GREEN = 185873,
|
||||
GO_AURA_RED = 185874,
|
||||
GO_AURA_YELLOW = 185875,
|
||||
|
||||
GO_BLUE_CLUSTER_DISPLAY = 7369,
|
||||
GO_GREEN_CLUSTER_DISPLAY = 7371,
|
||||
GO_RED_CLUSTER_DISPLAY = 7373,
|
||||
GO_YELLOW_CLUSTER_DISPLAY = 7375,
|
||||
GO_BLUE_CLUSTER_DISPLAY_LARGE = 7364,
|
||||
GO_GREEN_CLUSTER_DISPLAY_LARGE = 7365,
|
||||
GO_RED_CLUSTER_DISPLAY_LARGE = 7366,
|
||||
GO_YELLOW_CLUSTER_DISPLAY_LARGE = 7367,
|
||||
|
||||
SPELL_PRE_GAME_BLUE = 40176,
|
||||
SPELL_PRE_GAME_GREEN = 40177,
|
||||
SPELL_PRE_GAME_RED = 40178,
|
||||
SPELL_PRE_GAME_YELLOW = 40179,
|
||||
SPELL_VISUAL_BLUE = 40244,
|
||||
SPELL_VISUAL_GREEN = 40245,
|
||||
SPELL_VISUAL_RED = 40246,
|
||||
SPELL_VISUAL_YELLOW = 40247,
|
||||
|
||||
SOUND_BLUE = 11588,
|
||||
SOUND_GREEN = 11589,
|
||||
SOUND_RED = 11590,
|
||||
SOUND_YELLOW = 11591,
|
||||
SOUND_DISABLE_NODE = 11758,
|
||||
|
||||
SPELL_AUDIBLE_GAME_TICK = 40391,
|
||||
SPELL_VISUAL_START_PLAYER_LEVEL = 40436,
|
||||
SPELL_VISUAL_START_AI_LEVEL = 40387,
|
||||
|
||||
SPELL_BAD_PRESS_TRIGGER = 41241,
|
||||
SPELL_BAD_PRESS_DAMAGE = 40065,
|
||||
SPELL_REWARD_BUFF_1 = 40310,
|
||||
SPELL_REWARD_BUFF_2 = 40311,
|
||||
SPELL_REWARD_BUFF_3 = 40312,
|
||||
};
|
||||
|
||||
enum SimonEvents
|
||||
{
|
||||
EVENT_SIMON_SETUP_PRE_GAME = 1,
|
||||
EVENT_SIMON_PLAY_SEQUENCE = 2,
|
||||
EVENT_SIMON_RESET_CLUSTERS = 3,
|
||||
EVENT_SIMON_PERIODIC_PLAYER_CHECK = 4,
|
||||
EVENT_SIMON_TOO_LONG_TIME = 5,
|
||||
EVENT_SIMON_GAME_TICK = 6,
|
||||
EVENT_SIMON_ROUND_FINISHED = 7,
|
||||
|
||||
ACTION_SIMON_CORRECT_FULL_SEQUENCE = 8,
|
||||
ACTION_SIMON_WRONG_SEQUENCE = 9,
|
||||
ACTION_SIMON_ROUND_FINISHED = 10,
|
||||
};
|
||||
|
||||
enum SimonColors
|
||||
{
|
||||
SIMON_BLUE = 0,
|
||||
SIMON_RED = 1,
|
||||
SIMON_GREEN = 2,
|
||||
SIMON_YELLOW = 3,
|
||||
SIMON_MAX_COLORS = 4,
|
||||
};
|
||||
|
||||
class npc_simon_bunny : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_simon_bunny() : CreatureScript("npc_simon_bunny") { }
|
||||
|
||||
struct npc_simon_bunnyAI : public ScriptedAI
|
||||
{
|
||||
npc_simon_bunnyAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
bool large;
|
||||
bool listening;
|
||||
uint8 gameLevel;
|
||||
uint8 fails;
|
||||
uint8 gameTicks;
|
||||
uint64 playerGUID;
|
||||
uint32 clusterIds[SIMON_MAX_COLORS];
|
||||
float zCoordCorrection;
|
||||
float searchDistance;
|
||||
EventMap _events;
|
||||
std::list<uint8> colorSequence, playableSequence, playerSequence;
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
switch(_events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SIMON_PERIODIC_PLAYER_CHECK:
|
||||
if (!CheckPlayer())
|
||||
ResetNode();
|
||||
else
|
||||
_events.ScheduleEvent(EVENT_SIMON_PERIODIC_PLAYER_CHECK, 2000);
|
||||
break;
|
||||
case EVENT_SIMON_SETUP_PRE_GAME:
|
||||
SetUpPreGame();
|
||||
_events.CancelEvent(EVENT_SIMON_GAME_TICK);
|
||||
_events.ScheduleEvent(EVENT_SIMON_PLAY_SEQUENCE, 1000);
|
||||
break;
|
||||
case EVENT_SIMON_PLAY_SEQUENCE:
|
||||
if (!playableSequence.empty())
|
||||
{
|
||||
PlayNextColor();
|
||||
_events.ScheduleEvent(EVENT_SIMON_PLAY_SEQUENCE, 1500);
|
||||
}
|
||||
else
|
||||
{
|
||||
listening = true;
|
||||
DoCast(SPELL_VISUAL_START_PLAYER_LEVEL);
|
||||
playerSequence.clear();
|
||||
PrepareClusters();
|
||||
gameTicks = 0;
|
||||
_events.ScheduleEvent(EVENT_SIMON_GAME_TICK, 3000);
|
||||
}
|
||||
break;
|
||||
case EVENT_SIMON_GAME_TICK:
|
||||
DoCast(SPELL_AUDIBLE_GAME_TICK);
|
||||
|
||||
if (gameTicks > gameLevel)
|
||||
_events.ScheduleEvent(EVENT_SIMON_TOO_LONG_TIME, 500);
|
||||
else
|
||||
_events.ScheduleEvent(EVENT_SIMON_GAME_TICK, 3000);
|
||||
gameTicks++;
|
||||
break;
|
||||
case EVENT_SIMON_RESET_CLUSTERS:
|
||||
PrepareClusters(true);
|
||||
break;
|
||||
case EVENT_SIMON_TOO_LONG_TIME:
|
||||
DoAction(ACTION_SIMON_WRONG_SEQUENCE);
|
||||
break;
|
||||
case EVENT_SIMON_ROUND_FINISHED:
|
||||
DoAction(ACTION_SIMON_ROUND_FINISHED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(const int32 action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_SIMON_ROUND_FINISHED:
|
||||
listening = false;
|
||||
DoCast(SPELL_VISUAL_START_AI_LEVEL);
|
||||
GiveRewardForLevel(gameLevel);
|
||||
_events.CancelEventGroup(0);
|
||||
if (gameLevel == 10)
|
||||
ResetNode();
|
||||
else
|
||||
_events.ScheduleEvent(EVENT_SIMON_SETUP_PRE_GAME, 1000);
|
||||
break;
|
||||
case ACTION_SIMON_CORRECT_FULL_SEQUENCE:
|
||||
gameLevel++;
|
||||
DoAction(ACTION_SIMON_ROUND_FINISHED);
|
||||
break;
|
||||
case ACTION_SIMON_WRONG_SEQUENCE:
|
||||
GivePunishment();
|
||||
DoAction(ACTION_SIMON_ROUND_FINISHED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Called by color clusters script (go_simon_cluster) and used for knowing the button pressed by player
|
||||
void SetData(uint32 type, uint32 /*data*/)
|
||||
{
|
||||
if (!listening)
|
||||
return;
|
||||
|
||||
uint8 pressedColor;
|
||||
|
||||
if (type == clusterIds[SIMON_RED])
|
||||
pressedColor = SIMON_RED;
|
||||
else if (type == clusterIds[SIMON_BLUE])
|
||||
pressedColor = SIMON_BLUE;
|
||||
else if (type == clusterIds[SIMON_GREEN])
|
||||
pressedColor = SIMON_GREEN;
|
||||
else if (type == clusterIds[SIMON_YELLOW])
|
||||
pressedColor = SIMON_YELLOW;
|
||||
|
||||
PlayColor(pressedColor);
|
||||
playerSequence.push_back(pressedColor);
|
||||
_events.ScheduleEvent(EVENT_SIMON_RESET_CLUSTERS, 500);
|
||||
CheckPlayerSequence();
|
||||
}
|
||||
|
||||
// Used for getting involved player guid. Parameter id is used for defining if is a large(Monument) or small(Relic) node
|
||||
void SetGUID(uint64 guid, int32 id)
|
||||
{
|
||||
me->SetFlying(true);
|
||||
|
||||
large = (bool)id;
|
||||
playerGUID = guid;
|
||||
StartGame();
|
||||
}
|
||||
|
||||
/*
|
||||
Resets all variables and also find the ids of the four closests color clusters, since every simon
|
||||
node have diferent ids for clusters this is absolutely NECESSARY.
|
||||
*/
|
||||
void StartGame()
|
||||
{
|
||||
listening = false;
|
||||
gameLevel = 0;
|
||||
fails = 0;
|
||||
gameTicks = 0;
|
||||
zCoordCorrection = large ? 8.0f : 2.75f;
|
||||
searchDistance = large ? 13.0f : 5.0f;
|
||||
colorSequence.clear();
|
||||
playableSequence.clear();
|
||||
playerSequence.clear();
|
||||
me->SetFloatValue(OBJECT_FIELD_SCALE_X, large ? 2 : 1);
|
||||
|
||||
std::list<WorldObject*> ClusterList;
|
||||
Trinity::AllWorldObjectsInRange objects(me, searchDistance);
|
||||
Trinity::WorldObjectListSearcher<Trinity::AllWorldObjectsInRange> searcher(me, ClusterList, objects);
|
||||
me->VisitNearbyObject(searchDistance, searcher);
|
||||
|
||||
for (std::list<WorldObject*>::const_iterator i = ClusterList.begin(); i != ClusterList.end(); ++i)
|
||||
{
|
||||
if (GameObject* go = (*i)->ToGameObject())
|
||||
{
|
||||
// We are checking for displayid because all simon nodes have 4 clusters with different entries
|
||||
if (large)
|
||||
{
|
||||
switch (go->GetGOInfo()->displayId)
|
||||
{
|
||||
case GO_BLUE_CLUSTER_DISPLAY_LARGE: clusterIds[SIMON_BLUE] = go->GetEntry(); break;
|
||||
case GO_RED_CLUSTER_DISPLAY_LARGE: clusterIds[SIMON_RED] = go->GetEntry(); break;
|
||||
case GO_GREEN_CLUSTER_DISPLAY_LARGE: clusterIds[SIMON_GREEN] = go->GetEntry(); break;
|
||||
case GO_YELLOW_CLUSTER_DISPLAY_LARGE: clusterIds[SIMON_YELLOW] = go->GetEntry(); break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (go->GetGOInfo()->displayId)
|
||||
{
|
||||
case GO_BLUE_CLUSTER_DISPLAY: clusterIds[SIMON_BLUE] = go->GetEntry(); break;
|
||||
case GO_RED_CLUSTER_DISPLAY: clusterIds[SIMON_RED] = go->GetEntry(); break;
|
||||
case GO_GREEN_CLUSTER_DISPLAY: clusterIds[SIMON_GREEN] = go->GetEntry(); break;
|
||||
case GO_YELLOW_CLUSTER_DISPLAY: clusterIds[SIMON_YELLOW] = go->GetEntry(); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_events.Reset();
|
||||
_events.ScheduleEvent(EVENT_SIMON_ROUND_FINISHED, 1000);
|
||||
_events.ScheduleEvent(EVENT_SIMON_PERIODIC_PLAYER_CHECK, 2000);
|
||||
|
||||
if (GameObject* relic = me->FindNearestGameObject(large ? GO_APEXIS_MONUMENT : GO_APEXIS_RELIC, searchDistance))
|
||||
relic->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
// Called when despawning the bunny. Sets all the node GOs to their default states.
|
||||
void ResetNode()
|
||||
{
|
||||
DoPlaySoundToSet(me, SOUND_DISABLE_NODE);
|
||||
|
||||
for (uint32 clusterId = SIMON_BLUE; clusterId < SIMON_MAX_COLORS; clusterId++)
|
||||
if (GameObject* cluster = me->FindNearestGameObject(clusterIds[clusterId], searchDistance))
|
||||
cluster->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
|
||||
for (uint32 auraId = GO_AURA_BLUE; auraId <= GO_AURA_YELLOW; auraId++)
|
||||
if (GameObject* auraGo = me->FindNearestGameObject(auraId, searchDistance))
|
||||
auraGo->RemoveFromWorld();
|
||||
|
||||
if (GameObject* relic = me->FindNearestGameObject(large ? GO_APEXIS_MONUMENT : GO_APEXIS_RELIC, searchDistance))
|
||||
relic->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
|
||||
me->ForcedDespawn(1000);
|
||||
}
|
||||
|
||||
/*
|
||||
Called on every button click of player. Adds the clicked color to the player created sequence and
|
||||
checks if it corresponds to the AI created sequence. If so, incremente gameLevel and start a new
|
||||
round, if not, give punishment and restart current level.
|
||||
*/
|
||||
void CheckPlayerSequence()
|
||||
{
|
||||
bool correct = true;
|
||||
if (playerSequence.size() <= colorSequence.size())
|
||||
for (std::list<uint8>::const_iterator i = playerSequence.begin(), j = colorSequence.begin(); i != playerSequence.end(); ++i, ++j)
|
||||
if ((*i) != (*j))
|
||||
correct = false;
|
||||
|
||||
if (correct && (playerSequence.size() == colorSequence.size()))
|
||||
DoAction(ACTION_SIMON_CORRECT_FULL_SEQUENCE);
|
||||
else if (!correct)
|
||||
DoAction(ACTION_SIMON_WRONG_SEQUENCE);
|
||||
}
|
||||
|
||||
/*
|
||||
Generates a random sequence of colors depending on the gameLevel. We also copy this sequence to
|
||||
the playableSequence wich will be used when playing the sequence to the player.
|
||||
*/
|
||||
void GenerateColorSequence()
|
||||
{
|
||||
colorSequence.clear();
|
||||
for (uint8 i = 0; i <= gameLevel; i++)
|
||||
colorSequence.push_back(RAND(SIMON_BLUE, SIMON_RED, SIMON_GREEN, SIMON_YELLOW));
|
||||
|
||||
for (std::list<uint8>::const_iterator i = colorSequence.begin(); i != colorSequence.end(); ++i)
|
||||
playableSequence.push_back(*i);
|
||||
}
|
||||
|
||||
|
||||
// Remove any existant glowing auras over clusters and set clusters ready for interating with them.
|
||||
void PrepareClusters(bool clustersOnly = false)
|
||||
{
|
||||
for (uint32 clusterId = SIMON_BLUE; clusterId < SIMON_MAX_COLORS; clusterId++)
|
||||
if (GameObject* cluster = me->FindNearestGameObject(clusterIds[clusterId], searchDistance))
|
||||
cluster->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
|
||||
if (clustersOnly)
|
||||
return;
|
||||
|
||||
for (uint32 auraId = GO_AURA_BLUE; auraId <= GO_AURA_YELLOW; auraId++)
|
||||
if (GameObject* auraGo = me->FindNearestGameObject(auraId, searchDistance))
|
||||
auraGo->RemoveFromWorld();
|
||||
}
|
||||
|
||||
/*
|
||||
Called when AI is playing the sequence for player. We cast the visual spell and then remove the
|
||||
casted color from the casting sequence.
|
||||
*/
|
||||
void PlayNextColor()
|
||||
{
|
||||
PlayColor(*playableSequence.begin());
|
||||
playableSequence.erase(playableSequence.begin());
|
||||
}
|
||||
|
||||
// Casts a spell and plays a sound depending on parameter color.
|
||||
void PlayColor(uint8 color)
|
||||
{
|
||||
switch (color)
|
||||
{
|
||||
case SIMON_BLUE:
|
||||
DoCast(SPELL_VISUAL_BLUE);
|
||||
DoPlaySoundToSet(me, SOUND_BLUE);
|
||||
break;
|
||||
case SIMON_GREEN:
|
||||
DoCast(SPELL_VISUAL_GREEN);
|
||||
DoPlaySoundToSet(me, SOUND_GREEN);
|
||||
break;
|
||||
case SIMON_RED:
|
||||
DoCast(SPELL_VISUAL_RED);
|
||||
DoPlaySoundToSet(me, SOUND_RED);
|
||||
break;
|
||||
case SIMON_YELLOW:
|
||||
DoCast(SPELL_VISUAL_YELLOW);
|
||||
DoPlaySoundToSet(me, SOUND_YELLOW);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Creates the transparent glowing auras on every cluster of this node.
|
||||
After calling this function bunny is teleported to the center of the node.
|
||||
*/
|
||||
void SetUpPreGame()
|
||||
{
|
||||
for (uint32 clusterId = SIMON_BLUE; clusterId < SIMON_MAX_COLORS; clusterId++)
|
||||
{
|
||||
if (GameObject* cluster = me->FindNearestGameObject(clusterIds[clusterId], 2.0f*searchDistance))
|
||||
{
|
||||
cluster->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
|
||||
// break since we don't need glowing auras for large clusters
|
||||
if (large)
|
||||
break;
|
||||
|
||||
float x, y, z, o;
|
||||
cluster->GetPosition(x, y, z, o);
|
||||
me->NearTeleportTo(x, y, z, o);
|
||||
|
||||
uint32 preGameSpellId;
|
||||
if (cluster->GetEntry() == clusterIds[SIMON_RED])
|
||||
preGameSpellId = SPELL_PRE_GAME_RED;
|
||||
else if (cluster->GetEntry() == clusterIds[SIMON_BLUE])
|
||||
preGameSpellId = SPELL_PRE_GAME_BLUE;
|
||||
else if (cluster->GetEntry() == clusterIds[SIMON_GREEN])
|
||||
preGameSpellId = SPELL_PRE_GAME_GREEN;
|
||||
else if (cluster->GetEntry() == clusterIds[SIMON_YELLOW])
|
||||
preGameSpellId = SPELL_PRE_GAME_YELLOW;
|
||||
else break;
|
||||
|
||||
me->CastSpell(cluster, preGameSpellId, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (GameObject* relic = me->FindNearestGameObject(large ? GO_APEXIS_MONUMENT : GO_APEXIS_RELIC, searchDistance))
|
||||
{
|
||||
float x, y, z, o;
|
||||
relic->GetPosition(x, y, z, o);
|
||||
me->NearTeleportTo(x, y, z + zCoordCorrection, o);
|
||||
}
|
||||
|
||||
GenerateColorSequence();
|
||||
}
|
||||
|
||||
// Handles the spell rewards. The spells also have the QuestCompleteEffect, so quests credits are working.
|
||||
void GiveRewardForLevel(uint8 level)
|
||||
{
|
||||
uint32 rewSpell;
|
||||
switch (level)
|
||||
{
|
||||
case 6:
|
||||
if (large)
|
||||
GivePunishment();
|
||||
else
|
||||
rewSpell = SPELL_REWARD_BUFF_1;
|
||||
break;
|
||||
case 8:
|
||||
rewSpell = SPELL_REWARD_BUFF_2;
|
||||
break;
|
||||
case 10:
|
||||
rewSpell = SPELL_REWARD_BUFF_3;
|
||||
break;
|
||||
default:
|
||||
rewSpell = 0;
|
||||
}
|
||||
|
||||
if (rewSpell)
|
||||
if (Player* player = me->GetPlayer(*me, playerGUID))
|
||||
DoCast(player, rewSpell, true);
|
||||
}
|
||||
|
||||
/*
|
||||
Depending on the number of failed pushes for player the damage of the spell scales, so we first
|
||||
cast the spell on the target that hits for 50 and shows the visual and then forces the player
|
||||
to cast the damaging spell on it self with the modified basepoints.
|
||||
4 fails = death.
|
||||
On large nodes punishment and reward are the same, summoning the Apexis Guardian.
|
||||
*/
|
||||
void GivePunishment()
|
||||
{
|
||||
if (large)
|
||||
{
|
||||
if (Player* player = me->GetPlayer(*me, playerGUID))
|
||||
if (Creature* guardian = me->SummonCreature(NPC_APEXIS_GUARDIAN, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() - zCoordCorrection, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000))
|
||||
guardian->AI()->AttackStart(player);
|
||||
|
||||
ResetNode();
|
||||
}
|
||||
else
|
||||
{
|
||||
fails++;
|
||||
|
||||
if (Player* player = me->GetPlayer(*me, playerGUID))
|
||||
DoCast(player, SPELL_BAD_PRESS_TRIGGER, true);
|
||||
|
||||
if (fails >= 4)
|
||||
ResetNode();
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, const SpellInfo* spell)
|
||||
{
|
||||
// Cast SPELL_BAD_PRESS_DAMAGE with scaled basepoints when the visual hits the target.
|
||||
// Need Fix: When SPELL_BAD_PRESS_TRIGGER hits target it triggers spell SPELL_BAD_PRESS_DAMAGE by itself
|
||||
// so player gets damage equal to calculated damage dbc basepoints for SPELL_BAD_PRESS_DAMAGE (~50)
|
||||
if (spell->Id == SPELL_BAD_PRESS_TRIGGER)
|
||||
{
|
||||
int32 bp = (int32)((float)(fails)*0.33f*target->GetMaxHealth());
|
||||
target->CastCustomSpell(target, SPELL_BAD_PRESS_DAMAGE, &bp, NULL, NULL, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if player has already die or has get too far from the current node
|
||||
bool CheckPlayer()
|
||||
{
|
||||
if (Player* player = me->GetPlayer(*me, playerGUID))
|
||||
{
|
||||
if (player->isDead())
|
||||
return false;
|
||||
if (player->GetDistance2d(me) >= 2.0f*searchDistance)
|
||||
{
|
||||
GivePunishment();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_simon_bunnyAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class go_simon_cluster : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_simon_cluster() : GameObjectScript("go_simon_cluster") { }
|
||||
|
||||
bool OnGossipHello(Player* player, GameObject* go)
|
||||
{
|
||||
if (Creature* bunny = go->FindNearestCreature(NPC_SIMON_BUNNY, 12.0f, true))
|
||||
bunny->AI()->SetData(go->GetEntry(), 0);
|
||||
|
||||
player->CastSpell(player, go->GetGOInfo()->goober.spellId, true);
|
||||
go->AddUse();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
enum ApexisRelic
|
||||
{
|
||||
QUEST_CRYSTALS = 11025,
|
||||
GOSSIP_TEXT_ID = 10948,
|
||||
|
||||
ITEM_APEXIS_SHARD = 32569,
|
||||
SPELL_TAKE_REAGENTS_SOLO = 41145,
|
||||
SPELL_TAKE_REAGENTS_GROUP = 41146,
|
||||
};
|
||||
|
||||
class go_apexis_relic : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_apexis_relic() : GameObjectScript("go_apexis_relic") { }
|
||||
|
||||
bool OnGossipHello(Player* player, GameObject* go)
|
||||
{
|
||||
player->PrepareGossipMenu(go, go->GetGOInfo()->questgiver.gossipID);
|
||||
player->SendPreparedGossip(go);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, GameObject* go, uint32 /*sender*/, uint32 /*action*/)
|
||||
{
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
|
||||
bool large = (go->GetEntry() == GO_APEXIS_MONUMENT);
|
||||
if (player->HasItemCount(ITEM_APEXIS_SHARD, large ? 35 : 1))
|
||||
{
|
||||
player->CastSpell(player, large ? SPELL_TAKE_REAGENTS_GROUP : SPELL_TAKE_REAGENTS_SOLO, false);
|
||||
|
||||
if (Creature* bunny = player->SummonCreature(NPC_SIMON_BUNNY, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ()))
|
||||
bunny->AI()->SetGUID(player->GetGUID(), large);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_blades_edge_mountains()
|
||||
{
|
||||
new mobs_bladespire_ogre();
|
||||
@@ -573,4 +1131,7 @@ void AddSC_blades_edge_mountains()
|
||||
new npc_bloodmaul_brutebane();
|
||||
new npc_ogre_brute();
|
||||
new go_thunderspike();
|
||||
new npc_simon_bunny();
|
||||
new go_simon_cluster();
|
||||
new go_apexis_relic();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user