Scripts/Stratholme: Portcullis Trap (#29596)

Co-authored-by: Shauren <[email protected]>
(cherry picked from commit 75e38a5d8f739358421ca5eece7e3701f6b8d190)
Signed-off-by: luis <[email protected]>
This commit is contained in:
bibi
2026-05-30 00:34:24 -03:00
committed by luis
parent b4721bbdac
commit 7ee637fdbb
2 changed files with 122 additions and 11 deletions
@@ -32,13 +32,15 @@ EndScriptData */
#include "Log.h"
#include "Map.h"
#include "MotionMaster.h"
#include "Pet.h"
#include "Player.h"
#include "stratholme.h"
enum InstanceEvents
{
EVENT_BARON_RUN = 1,
EVENT_SLAUGHTER_SQUARE = 2
EVENT_SLAUGHTER_SQUARE = 2,
EVENT_RAT_TRAP_CLOSE = 3,
};
enum StratholmeMisc
@@ -46,9 +48,6 @@ enum StratholmeMisc
SAY_YSIDA_SAVED = 0
};
Position const timmyTheCruelSpawnPosition = { 3625.358f, -3188.108f, 130.3985f, 4.834562f };
EllipseBoundary const beforeScarletGate(Position(3671.158f, -3181.79f), 60.0f, 40.0f);
static constexpr DungeonEncounterData Encounters[] =
{
{ BOSS_HEARTHSINGER_FORRESTEN, {{ 473 }} }, // Hearthsinger Forresten
@@ -67,6 +66,28 @@ static constexpr DungeonEncounterData Encounters[] =
{ BOSS_POSTMASTER_MALOWN, {{ 1885 }} } // Postmaster Malown
};
Position const timmyTheCruelSpawnPosition = { 3625.358f, -3188.108f, 130.3985f, 4.834562f };
EllipseBoundary const beforeScarletGate(Position(3671.158f, -3181.79f), 60.0f, 40.0f);
enum class StratholmeGateTrapType : uint8
{
ScaletSide = 0,
UndeadSide = 1
};
Position const GateTrapPos[] = // Positions of the two Gate Traps 3919.88 -3547.34 134.269
{
{ 3612.29f, -3335.39f, 124.077f }, // Scarlet side
{ 3919.88f, -3545.34f, 134.269f } // Undead side
};
struct GateTrapData
{
std::array<ObjectGuid, 2> Gates;
GuidUnorderedSet Rats;
bool Triggered = false;
};
class instance_stratholme : public InstanceMapScript
{
public:
@@ -87,6 +108,8 @@ class instance_stratholme : public InstanceMapScript
scarletsKilled = 0;
brokenCrystals = 0;
baronRunState = NOT_STARTED;
events.ScheduleEvent(EVENT_RAT_TRAP_CLOSE, 15s);
}
uint8 scarletsKilled;
@@ -115,6 +138,8 @@ class instance_stratholme : public InstanceMapScript
GuidSet abomnationGUID;
EventMap events;
std::array<GateTrapData, 2> TrapGates;
void OnUnitDeath(Unit* who) override
{
switch (who->GetEntry())
@@ -153,6 +178,20 @@ class instance_stratholme : public InstanceMapScript
break;
default:
break;
case NPC_PLAGUED_RAT:
{
for (GateTrapData& trapGate : TrapGates)
{
auto el = trapGate.Rats.find(who->GetGUID());
if (el != trapGate.Rats.end())
{
trapGate.Rats.erase(el);
for (ObjectGuid gate : trapGate.Gates)
UpdateGoState(gate, GO_STATE_ACTIVE);
}
}
break;
}
}
}
@@ -169,21 +208,39 @@ class instance_stratholme : public InstanceMapScript
return false;
}
//if withRestoreTime true, then newState will be ignored and GO should be restored to original state after 10 seconds
void UpdateGoState(ObjectGuid goGuid, uint32 newState, bool withRestoreTime)
//if restoreTime is not 0, then newState will be ignored and GO should be restored to original state after "restoreTime" millisecond
void UpdateGoState(ObjectGuid goGuid, uint32 newState, uint32 restoreTime = 0u)
{
if (!goGuid)
return;
if (GameObject* go = instance->GetGameObject(goGuid))
{
if (withRestoreTime)
go->UseDoorOrButton(10);
if (restoreTime)
go->UseDoorOrButton(restoreTime);
else
go->SetGoState((GOState)newState);
}
}
void DoGateTrap(StratholmeGateTrapType type, Unit* where)
{
// close the gate, but in two minutes it will open on its own
for (ObjectGuid trapGateGuid : TrapGates[AsUnderlyingType(type)].Gates)
UpdateGoState(trapGateGuid, GO_STATE_READY, 20 * IN_MILLISECONDS);
for (uint8 i = 0; i < 30; ++i)
{
Position summonPos = where->GetRandomPoint(GateTrapPos[AsUnderlyingType(type)], 5.0f);
if (Creature* creature = where->SummonCreature(NPC_PLAGUED_RAT, summonPos, TEMPSUMMON_DEAD_DESPAWN, 0s))
{
TrapGates[AsUnderlyingType(type)].Rats.insert(creature->GetGUID());
creature->EngageWithTarget(where);
}
}
TrapGates[AsUnderlyingType(type)].Triggered = true;
}
void OnCreatureCreate(Creature* creature) override
{
switch (creature->GetEntry())
@@ -275,6 +332,18 @@ class instance_stratholme : public InstanceMapScript
case GO_YSIDA_CAGE:
ysidaCageGUID = go->GetGUID();
break;
case GO_PORT_TRAP_GATE_1:
TrapGates[AsUnderlyingType(StratholmeGateTrapType::ScaletSide)].Gates[0] = go->GetGUID();
break;
case GO_PORT_TRAP_GATE_2:
TrapGates[AsUnderlyingType(StratholmeGateTrapType::ScaletSide)].Gates[1] = go->GetGUID();
break;
case GO_PORT_TRAP_GATE_3:
TrapGates[AsUnderlyingType(StratholmeGateTrapType::UndeadSide)].Gates[0] = go->GetGUID();
break;
case GO_PORT_TRAP_GATE_4:
TrapGates[AsUnderlyingType(StratholmeGateTrapType::UndeadSide)].Gates[1] = go->GetGUID();
break;
}
}
@@ -511,6 +580,41 @@ class instance_stratholme : public InstanceMapScript
TC_LOG_DEBUG("scripts", "Instance Stratholme: Black guard sentries spawned. Opening gates to baron.");
}
break;
case EVENT_RAT_TRAP_CLOSE:
{
for (uint8 i = 0; i < std::size(GateTrapPos); ++i)
{
if (TrapGates[i].Triggered)
continue;
Position const* gateTrapPos = &GateTrapPos[i];
// Check that the trap is not on cooldown, if so check if player/pet is in range
for (MapReference const& itr : instance->GetPlayers())
{
Player* player = itr.GetSource();
if (player->IsGameMaster())
continue;
if (player->IsWithinDist2d(gateTrapPos, 5.5f))
{
DoGateTrap(StratholmeGateTrapType(i), player);
break;
}
Pet* pet = player->GetPet();
if (pet && pet->IsWithinDist2d(gateTrapPos, 5.5f))
{
DoGateTrap(StratholmeGateTrapType(i), pet);
break;
}
}
}
//if you haven't already fallen into the trap, update it
if (std::any_of(TrapGates.begin(), TrapGates.end(), [](GateTrapData const& trap) { return !trap.Triggered; }))
events.ScheduleEvent(EVENT_RAT_TRAP_CLOSE, 1s);
break;
}
default:
break;
}
@@ -86,7 +86,10 @@ enum STRCreatureIds
NPC_CRIMSON_INITATE = 10420,
NPC_CRIMSON_GALLANT = 10424,
NPC_TIMMY_THE_CRUEL = 10808
NPC_TIMMY_THE_CRUEL = 10808,
// Rat trap
NPC_PLAGUED_RAT = 10441,
};
enum STRGameobjectIds
@@ -102,7 +105,11 @@ enum STRGameobjectIds
GO_PORT_GAUNTLET = 175374, // port from gauntlet to slaugther
GO_PORT_SLAUGTHER = 175373, // port at slaugther
GO_PORT_ELDERS = 175377, // port at elders square
GO_YSIDA_CAGE = 181071
GO_YSIDA_CAGE = 181071,
GO_PORT_TRAP_GATE_1 = 175351, // Portcullis used in the gate traps (rats trap)
GO_PORT_TRAP_GATE_2 = 175350, // Scarlet side
GO_PORT_TRAP_GATE_3 = 175355, // Undead side
GO_PORT_TRAP_GATE_4 = 175354,
};
enum STRQuestIds