mirror of
https://gitcode.com/GitHub_Trending/az/azerothcore-wotlk.git
synced 2026-10-10 07:06:38 +08:00
fix(Scripts/BlackrockDepths): script the Black Vault warder event (#26973)
Co-authored-by: Claude Fable 5 <[email protected]> Co-authored-by: sudlud <[email protected]> Co-authored-by: Xfurry <[email protected]> Co-authored-by: Tobschinski <[email protected]>
This commit is contained in:
co-authored by
Claude Fable 5
sudlud
Xfurry
Tobschinski
parent
4d4ae4f957
commit
a7ba226a68
@@ -0,0 +1,6 @@
|
||||
--
|
||||
-- The four Warbringer Constructs in the Black Vault's Relic Coffer room must not
|
||||
-- re-apply Stoned (10255) from creature_addon on every evade (CreatureAI::_EnterEvadeMode
|
||||
-- reloads addon auras), or they would turn back into statues after the vault event has
|
||||
-- awakened them. The instance script casts the aura once on spawn instead.
|
||||
UPDATE `creature_addon` SET `auras` = NULL WHERE `guid` IN (46608, 46610, 46611, 46612);
|
||||
@@ -0,0 +1,10 @@
|
||||
-- Watchman Doomgrip: the vault event completion (Secret Door + Secret Safe) is handled by the
|
||||
-- instance script when all four vault warders and Doomgrip are dead, so drop the old on-death
|
||||
-- shortcut that opened both on his death alone. The on-aggro unfreeze of nearby Warbringer
|
||||
-- Constructs is dead code too: the instance script awakens them when the 12th Relic Coffer
|
||||
-- door opens, before Doomgrip spawns. Keep his combat spells and his aggro yell.
|
||||
DELETE FROM `smart_scripts` WHERE `entryorguid` = 9476 AND `source_type` = 0;
|
||||
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||
(9476,0,0,0,0,0,100,0,1000,1000,6000,8000,0,0,11,11971,0,0,0,0,0,2,0,0,0,0,0,0,0,0,'Watchman Doomgrip - In Combat - Cast Sunder Armor'),
|
||||
(9476,0,1,0,2,0,100,0,0,60,30000,30000,0,0,11,15504,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Watchman Doomgrip - Between 0-60% Health - Cast Drink Healing Potion'),
|
||||
(9476,0,2,0,4,0,100,513,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Watchman Doomgrip - On Aggro - Say Line 0');
|
||||
+1
@@ -106,6 +106,7 @@ enum Creatures
|
||||
NPC_RAGEREAVER_GOLEM = 8906,
|
||||
NPC_WRATH_HAMMER_CONSTRUCT = 8907,
|
||||
NPC_GOLEM_LORD_ARGELMACH = 8983,
|
||||
NPC_WARBRINGER_CONSTRUCT = 8905,
|
||||
|
||||
NPC_COREN_DIREBREW = 23872,
|
||||
|
||||
|
||||
+90
-5
@@ -33,7 +33,8 @@ enum Timers
|
||||
enum Distances
|
||||
{
|
||||
RADIUS_RING_OF_LAW = 80,
|
||||
DISTANCE_EMPEROR_ROOM = 125
|
||||
DISTANCE_EMPEROR_ROOM = 125,
|
||||
DISTANCE_VAULT_WARDER = 15
|
||||
};
|
||||
|
||||
enum PrincessQuests
|
||||
@@ -65,6 +66,8 @@ enum GameObjects
|
||||
GO_THRONE_ROOM = 170575, // Throne door
|
||||
GO_SPECTRAL_CHALICE = 164869,
|
||||
GO_CHEST_SEVEN = 169243,
|
||||
GO_SECRET_DOOR = 174553,
|
||||
GO_SECRET_SAFE = 161495,
|
||||
};
|
||||
|
||||
enum MiscData
|
||||
@@ -147,6 +150,12 @@ struct instance_blackrock_depths : public InstanceScript
|
||||
GuidList ArgelmachAdds;
|
||||
ObjectGuid ArgelmachGUID;
|
||||
|
||||
// The four Warbringer Constructs in the Relic Coffer room and Watchman Doomgrip
|
||||
GuidList VaultWarderGUIDs;
|
||||
ObjectGuid GoSecretDoorGUID;
|
||||
ObjectGuid GoSecretSafeGUID;
|
||||
Position VaultWarderCenter = Position(813.5f, -348.0f);
|
||||
|
||||
TempSummon* TempSummonGrimstone = nullptr;
|
||||
Position GrimstonePositon = Position(625.559f, -205.618f, -52.735f, 2.609f);
|
||||
time_t timeRingFail = 0;
|
||||
@@ -280,7 +289,9 @@ struct instance_blackrock_depths : public InstanceScript
|
||||
break;
|
||||
case NPC_ARENA_SPECTATOR:
|
||||
ArenaSpectators.push_back(creature->GetGUID());
|
||||
if (encounter[TYPE_RING_OF_LAW] == DONE) // added for crashes
|
||||
// note: reads GetData, not encounter[TYPE_RING_OF_LAW]: the types are 1-based
|
||||
// while the array is 0-based, so the raw index would hit the vault slot
|
||||
if (GetData(TYPE_RING_OF_LAW) == DONE) // added for crashes
|
||||
{
|
||||
creature->SetFaction(FACTION_NEUTRAL);
|
||||
creature->SetReactState(REACT_DEFENSIVE);
|
||||
@@ -290,7 +301,9 @@ struct instance_blackrock_depths : public InstanceScript
|
||||
case NPC_SHADOWFORCE_CITIZEN: // both do the same
|
||||
if (creature->GetDistance2d(CenterOfRingOfLaw.GetPositionX(), CenterOfRingOfLaw.GetPositionY()) < (float)RADIUS_RING_OF_LAW)
|
||||
ArenaSpectators.push_back(creature->GetGUID());
|
||||
if (encounter[TYPE_RING_OF_LAW] == DONE) // added for crashes
|
||||
// note: reads GetData, not encounter[TYPE_RING_OF_LAW]: the types are 1-based
|
||||
// while the array is 0-based, so the raw index would hit the vault slot
|
||||
if (GetData(TYPE_RING_OF_LAW) == DONE) // added for crashes
|
||||
{
|
||||
creature->SetFaction(FACTION_NEUTRAL);
|
||||
creature->SetReactState(REACT_DEFENSIVE);
|
||||
@@ -302,6 +315,32 @@ struct instance_blackrock_depths : public InstanceScript
|
||||
if (creature->GetDistance2d(EmperorSpawnPos.GetPositionX(), EmperorSpawnPos.GetPositionY()) < (float)DISTANCE_EMPEROR_ROOM)
|
||||
EmperorSenatorsVector.push_back(creature->GetGUID());
|
||||
break;
|
||||
case NPC_WARBRINGER_CONSTRUCT:
|
||||
// only the four constructs in the Relic Coffer room belong to the vault event,
|
||||
// the rest of the Black Vault spawns are regular trash
|
||||
if (creature->GetDistance2d(VaultWarderCenter.GetPositionX(), VaultWarderCenter.GetPositionY()) > (float)DISTANCE_VAULT_WARDER)
|
||||
break;
|
||||
// dead spawns with a pending respawn are loaded too: a corpse must not be frozen or
|
||||
// counted, or the restarted event could not complete until its respawn timer expires
|
||||
if (!creature->IsAlive())
|
||||
break;
|
||||
// frozen until all 12 Relic Coffers have been opened. Stoned (statue visual) is cast
|
||||
// here instead of creature_addon on purpose: addon auras get re-applied on every
|
||||
// evade, which would turn the constructs back into statues after the event has started.
|
||||
if (GetData(TYPE_VAULT) == NOT_STARTED)
|
||||
{
|
||||
creature->CastSpell(creature, SPELL_STONED, true);
|
||||
creature->SetImmuneToPC(true);
|
||||
// untargetable while inert: the reference video (https://youtu.be/KE1nElNN1YY)
|
||||
// shows the statues cannot be targeted until activated; vmangos likewise clears
|
||||
// UNIT_FLAG_NOT_SELECTABLE on them when Doomgrip aggroes
|
||||
creature->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
creature->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
[[fallthrough]];
|
||||
case NPC_WATCHMAN_DOOMGRIP:
|
||||
VaultWarderGUIDs.push_back(creature->GetGUID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -378,6 +417,17 @@ struct instance_blackrock_depths : public InstanceScript
|
||||
case GO_SPECTRAL_CHALICE:
|
||||
GoSpectralChaliceGUID = go->GetGUID();
|
||||
break;
|
||||
case GO_SECRET_DOOR:
|
||||
GoSecretDoorGUID = go->GetGUID();
|
||||
if (GetData(TYPE_VAULT) == DONE)
|
||||
HandleGameObject(ObjectGuid::Empty, true, go);
|
||||
break;
|
||||
case GO_SECRET_SAFE:
|
||||
GoSecretSafeGUID = go->GetGUID();
|
||||
// non-interactable via gameobject_template_addon flags until the vault event is done
|
||||
if (GetData(TYPE_VAULT) == DONE)
|
||||
go->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,6 +445,17 @@ struct instance_blackrock_depths : public InstanceScript
|
||||
case NPC_MAGMUS:
|
||||
SetData(TYPE_IRON_HALL, DONE);
|
||||
break;
|
||||
case NPC_WARBRINGER_CONSTRUCT:
|
||||
case NPC_WATCHMAN_DOOMGRIP:
|
||||
if (GetData(TYPE_VAULT) == IN_PROGRESS)
|
||||
{
|
||||
// regular Black Vault trash shares the entry but is not in the list,
|
||||
// remove() is a no-op for it
|
||||
VaultWarderGUIDs.remove(unit->GetGUID());
|
||||
if (VaultWarderGUIDs.empty())
|
||||
SetData(TYPE_VAULT, DONE);
|
||||
}
|
||||
break;
|
||||
case NPC_SHADOWFORGE_SENATOR:
|
||||
deadSenators = 1; //hacky, but we cannot count the unit that just died through its state because OnUnitDeath() is called before the state is set.
|
||||
for (auto const& senatorGUID: EmperorSenatorsVector)
|
||||
@@ -458,6 +519,13 @@ struct instance_blackrock_depths : public InstanceScript
|
||||
break;
|
||||
case TYPE_VAULT:
|
||||
encounter[1] = data;
|
||||
if (data == DONE)
|
||||
{
|
||||
// vault cleared: open the secret door and make the Secret Safe lootable
|
||||
HandleGameObject(GoSecretDoorGUID, true);
|
||||
if (GameObject* safe = instance->GetGameObject(GoSecretSafeGUID))
|
||||
safe->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
break;
|
||||
case TYPE_BAR:
|
||||
if (data == SPECIAL)
|
||||
@@ -510,9 +578,26 @@ struct instance_blackrock_depths : public InstanceScript
|
||||
break;
|
||||
case DATA_OPEN_COFFER_DOORS:
|
||||
OpenedCoofers += 1;
|
||||
if (OpenedCoofers == 12)
|
||||
// the coffer doors reset on every map load while the vault state persists: reopening
|
||||
// them after the event has started must not restart it or summon a second Doomgrip
|
||||
if (OpenedCoofers == 12 && GetData(TYPE_VAULT) == NOT_STARTED)
|
||||
{
|
||||
Position pos = {812.15f, -348.91f, -50.579f, 0.7f};
|
||||
SetData(TYPE_VAULT, IN_PROGRESS);
|
||||
|
||||
// awaken the Warbringer Constructs guarding the vault
|
||||
for (ObjectGuid const& warderGUID : VaultWarderGUIDs)
|
||||
{
|
||||
if (Creature* warder = instance->GetCreature(warderGUID))
|
||||
{
|
||||
warder->RemoveAurasDueToSpell(SPELL_STONED);
|
||||
warder->SetImmuneToPC(false);
|
||||
warder->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
warder->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
// spawns at the room entrance, not amidst the constructs (position from cmangos)
|
||||
Position pos = {821.905f, -338.382f, -50.134f, 3.78736f};
|
||||
if (TempSummon* summon = instance->SummonCreature(NPC_WATCHMAN_DOOMGRIP, pos))
|
||||
summon->SetTempSummonType(TEMPSUMMON_MANUAL_DESPAWN);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user