Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a63829a130 |
@@ -0,0 +1,6 @@
|
|||||||
|
-- Exiles Reach: bind the Giant Boar ride scene (SceneId 2338, package 2712) to its SceneScript.
|
||||||
|
-- During the boar ride ("Ride of the Scientifically Enhanced Boar" / "The Redeather") the client
|
||||||
|
-- fires "Trampling Time", "Big Kill Credit" and "Knockback" trigger events; core only dispatches
|
||||||
|
-- those to a bound SceneScript via scene_template.ScriptName. The script itself lives in
|
||||||
|
-- src/server/scripts/ExilesReach/exiles_reach.cpp (scene_exiles_reach_boar_ride).
|
||||||
|
UPDATE `scene_template` SET `ScriptName` = 'scene_exiles_reach_boar_ride' WHERE `SceneId` = 2338;
|
||||||
@@ -95,41 +95,11 @@ public:
|
|||||||
if (player->GetMapId() != MAP_EXILES_REACH)
|
if (player->GetMapId() != MAP_EXILES_REACH)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (sceneEvent == "Big Kill Credit")
|
// NOTE: The Giant Boar ride triggers ("Big Kill Credit", "Knockback",
|
||||||
{
|
// "Trampling Time") are handled in scene_exiles_reach_boar_ride below,
|
||||||
player->CastSpell(player, SPELL_CADAVER_KILL_CREDIT);
|
// bound to scene_template.SceneId = 2338 via SQL. SceneScripts are
|
||||||
|
// dispatched by core on every branch, so the ride works without any
|
||||||
if (player->GetQuestObjectiveProgress(QUEST_H_THE_REDEATHER, 2) == 8)
|
// core changes and fires exactly once per event.
|
||||||
{
|
|
||||||
player->CastSpell(player, SPELL_CADAVER_CREDIT_CHECK_CHOPPY_MALFUNCTION, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player->GetQuestObjectiveProgress(QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR, 2) == 8)
|
|
||||||
{
|
|
||||||
player->CastSpell(player, SPELL_GIANT_BOAR_PING_VEHICLE, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The boar mowed the undead down: despawn the hostile mobs around
|
|
||||||
// the rider so the trampled army actually vanishes (and stops
|
|
||||||
// attacking). Tied to the reliable scene credit rather than the
|
|
||||||
// trample's own grid search.
|
|
||||||
std::list<Creature*> mobs;
|
|
||||||
Trinity::AnyUnitInObjectRangeCheck u_check(player, 50.0f);
|
|
||||||
Trinity::CreatureListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(player, mobs, u_check);
|
|
||||||
Cell::VisitGridObjects(player, searcher, 50.0f);
|
|
||||||
for (Creature* mob : mobs)
|
|
||||||
{
|
|
||||||
if (!player->IsHostileTo(mob))
|
|
||||||
continue;
|
|
||||||
if (mob->GetEntry() == NPC_OGRE_RUINS_TORGOK)
|
|
||||||
continue; // leave the boss for the fight
|
|
||||||
// Track so the undead can be respawned if the quest is abandoned.
|
|
||||||
s_mowedDownUndead.insert(mob->GetSpawnId());
|
|
||||||
// Long respawn delay so the mowed-down undead stay dead
|
|
||||||
// through the rest of the ride instead of popping back.
|
|
||||||
mob->DespawnOrUnsummon(0s, 1h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sceneEvent == "Teleport")
|
if (sceneEvent == "Teleport")
|
||||||
{
|
{
|
||||||
@@ -164,21 +134,6 @@ public:
|
|||||||
player->CastSpell(player, SPELL_ORGRIMMAR_TELEPORT, true);
|
player->CastSpell(player, SPELL_ORGRIMMAR_TELEPORT, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sceneEvent == "Knockback")
|
|
||||||
{
|
|
||||||
player->CastSpell(player, SPELL_GIANT_BOAR_RIDING_KNOCKBACK, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sceneEvent == "Trampling Time")
|
|
||||||
{
|
|
||||||
if (Creature* giantBoarVehicle = player->GetVehicleCreatureBase())
|
|
||||||
{
|
|
||||||
Position targetLoc = giantBoarVehicle->GetFirstCollisionPosition(20.f, 0.f);
|
|
||||||
giantBoarVehicle->GetMotionMaster()->MoveCharge(targetLoc.GetPositionX(), targetLoc.GetPositionY(), targetLoc.GetPositionZ());
|
|
||||||
player->CastSpell(player, SPELL_GIANT_BOAR_TRAMPLE, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnUpdateArea(Player* player, uint32 newArea, uint32 /*oldArea*/) override
|
void OnUpdateArea(Player* player, uint32 newArea, uint32 /*oldArea*/) override
|
||||||
@@ -255,6 +210,84 @@ public:
|
|||||||
std::unordered_set<ObjectGuid::LowType> exiles_reach_general_playerscript::s_mowedDownUndead;
|
std::unordered_set<ObjectGuid::LowType> exiles_reach_general_playerscript::s_mowedDownUndead;
|
||||||
std::unordered_set<ObjectGuid> exiles_reach_general_playerscript::s_rideActivePlayers;
|
std::unordered_set<ObjectGuid> exiles_reach_general_playerscript::s_rideActivePlayers;
|
||||||
|
|
||||||
|
/* ## SCENE SCRIPTS > ## */
|
||||||
|
|
||||||
|
// Giant Boar ride (scene_template.SceneId = 2338, package 2712) -
|
||||||
|
// "Ride of the Scientifically Enhanced Boar" / "The Redeather".
|
||||||
|
//
|
||||||
|
// The client fires these trigger events from scene package 2712 during the boar
|
||||||
|
// ride (verified against a retail 12.1 packet capture):
|
||||||
|
// Conversation, then repeating pairs of "Trampling Time" + "Big Kill Credit",
|
||||||
|
// plus "Knockback" and "Hint", until SMSG_CANCEL_SCENE.
|
||||||
|
//
|
||||||
|
// The logic is bound to the scene via scene_template.ScriptName (see SQL
|
||||||
|
// update) instead of living in the PlayerScript hook above: core dispatches
|
||||||
|
// scene trigger events to a bound SceneScript on every branch, while
|
||||||
|
// OnSceneTriggerEvent only reaches PlayerScripts when an extra core change is
|
||||||
|
// present. Keeping it here means each event fires exactly once on both.
|
||||||
|
class scene_exiles_reach_boar_ride : public SceneScript
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
scene_exiles_reach_boar_ride() : SceneScript("scene_exiles_reach_boar_ride") {}
|
||||||
|
|
||||||
|
void OnSceneTriggerEvent(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/, std::string const& triggerName) override
|
||||||
|
{
|
||||||
|
if (player->GetMapId() != MAP_EXILES_REACH)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (triggerName == "Big Kill Credit")
|
||||||
|
{
|
||||||
|
player->CastSpell(player, SPELL_CADAVER_KILL_CREDIT);
|
||||||
|
|
||||||
|
if (player->GetQuestObjectiveProgress(QUEST_H_THE_REDEATHER, 2) == 8)
|
||||||
|
{
|
||||||
|
player->CastSpell(player, SPELL_CADAVER_CREDIT_CHECK_CHOPPY_MALFUNCTION, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player->GetQuestObjectiveProgress(QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR, 2) == 8)
|
||||||
|
{
|
||||||
|
player->CastSpell(player, SPELL_GIANT_BOAR_PING_VEHICLE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The boar mowed the undead down: despawn the hostile mobs around
|
||||||
|
// the rider so the trampled army actually vanishes (and stops
|
||||||
|
// attacking). Tied to the reliable scene credit rather than the
|
||||||
|
// trample's own grid search.
|
||||||
|
std::list<Creature*> mobs;
|
||||||
|
Trinity::AnyUnitInObjectRangeCheck u_check(player, 50.0f);
|
||||||
|
Trinity::CreatureListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(player, mobs, u_check);
|
||||||
|
Cell::VisitGridObjects(player, searcher, 50.0f);
|
||||||
|
for (Creature* mob : mobs)
|
||||||
|
{
|
||||||
|
if (!player->IsHostileTo(mob))
|
||||||
|
continue;
|
||||||
|
if (mob->GetEntry() == NPC_OGRE_RUINS_TORGOK)
|
||||||
|
continue; // leave the boss for the fight
|
||||||
|
// Track so the undead can be respawned if the quest is abandoned.
|
||||||
|
exiles_reach_general_playerscript::s_mowedDownUndead.insert(mob->GetSpawnId());
|
||||||
|
// Long respawn delay so the mowed-down undead stay dead
|
||||||
|
// through the rest of the ride instead of popping back.
|
||||||
|
mob->DespawnOrUnsummon(0s, 1h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (triggerName == "Knockback")
|
||||||
|
{
|
||||||
|
player->CastSpell(player, SPELL_GIANT_BOAR_RIDING_KNOCKBACK, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (triggerName == "Trampling Time")
|
||||||
|
{
|
||||||
|
if (Creature* giantBoarVehicle = player->GetVehicleCreatureBase())
|
||||||
|
{
|
||||||
|
Position targetLoc = giantBoarVehicle->GetFirstCollisionPosition(20.f, 0.f);
|
||||||
|
giantBoarVehicle->GetMotionMaster()->MoveCharge(targetLoc.GetPositionX(), targetLoc.GetPositionY(), targetLoc.GetPositionZ());
|
||||||
|
player->CastSpell(player, SPELL_GIANT_BOAR_TRAMPLE, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class map_exiles_reach : public WorldMapScript
|
class map_exiles_reach : public WorldMapScript
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -464,6 +497,8 @@ void AddSC_exiles_reach_general()
|
|||||||
{
|
{
|
||||||
// Player Scripts
|
// Player Scripts
|
||||||
new exiles_reach_general_playerscript();
|
new exiles_reach_general_playerscript();
|
||||||
|
// Scene Scripts
|
||||||
|
new scene_exiles_reach_boar_ride();
|
||||||
// WorldMap Scripts
|
// WorldMap Scripts
|
||||||
new map_exiles_reach();
|
new map_exiles_reach();
|
||||||
// Spell Scripts
|
// Spell Scripts
|
||||||
|
|||||||
Reference in New Issue
Block a user