fix(Scripts/Stratholme): Restore Scarlet Threads (#27342)

Co-authored-by: sudlud <[email protected]>
Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
moostigre
2026-09-06 16:53:20 +02:00
committed by GitHub
co-authored by sudlud Claude Opus 5
parent 54f1e6db2e
commit 13cb5db8e7
3 changed files with 101 additions and 1 deletions
@@ -0,0 +1,12 @@
-- Enchanted Scarlet Thread (175966) appears at four locations in a random,
-- non-repeating order. The Stratholme instance script summons one at a time.
DELETE FROM `gameobject` WHERE `guid` = 20872 AND `id` = 175966;
DELETE FROM `gameobject_summon_groups` WHERE `summonerId` = 329 AND `summonerType` = 2 AND `groupId` IN (0, 1, 2, 3);
INSERT INTO `gameobject_summon_groups` (`summonerId`, `summonerType`, `groupId`, `entry`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `respawnTime`, `Comment`) VALUES
(329, 2, 0, 175966, 3458.015, -3111.456, 137.434, 5.358161926269531, 0, 0, -0.4462, 0.8949, 604800, 'Enchanted Scarlet Thread - Archivist Galford room'),
(329, 2, 1, 175966, 3593.515, -3060.397, 136.482, 1.5358895063400269, 0, 0, 0.6947, 0.7193, 604800, 'Enchanted Scarlet Thread - Hall opposite Malor room'),
(329, 2, 2, 175966, 3614.640, -3124.924, 137.012, 3.438302755355835, 0, 0, -0.9890, 0.1478, 604800, 'Enchanted Scarlet Thread - Malor room table'),
(329, 2, 3, 175966, 3625.627, -3123.886, 135.665, 5.777040958404541, 0, 0, -0.2504, 0.9681, 604800, 'Enchanted Scarlet Thread - Malor room back-left crate');
UPDATE `gameobject_template` SET `ScriptName` = 'go_enchanted_scarlet_thread' WHERE `entry` = 175966;
@@ -15,12 +15,16 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "GameObjectScript.h"
#include "InstanceMapScript.h"
#include "InstanceScript.h"
#include "Player.h"
#include "ScriptedCreature.h"
#include "stratholme.h"
#include <array>
#include <list>
const Position BlackGuardPos[10] =
{
{4032.73f + 0.0f, -3378.26f + 0.0f, 119.76f, 4.67f},
@@ -53,6 +57,9 @@ Position const MindlessUndeadPos = { 3941.75f, -3393.06f, 119.70f, 0.0f };
Position const BarthilasPos = { 4068.74f, -3535.97f, 122.825f, 2.478367567062377929f };
Position const SlaughterPos = { 4032.20f, -3378.06f, 119.75f, 4.67f };
static constexpr uint8 ScarletThreadSpawnCount = 4;
static constexpr uint8 AllScarletThreadLocations = (1 << ScarletThreadSpawnCount) - 1;
// uint32 m_uiGateTrapTimers[2][3] = { {0,0,0}, {0,0,0} };
class instance_stratholme : public InstanceMapScript
@@ -78,6 +85,10 @@ public:
_slaughterNPCs = 0;
_postboxesOpened = 0;
_scarletThreadUsedLocations = 0;
_scarletThreadLocation = 0;
_scarletThreadGUID.Clear();
_gateTrapsCooldown[0] = false;
_gateTrapsCooldown[1] = false;
@@ -89,6 +100,8 @@ public:
if (_baronRunTime > 0)
if (Aura* aura = player->AddAura(SPELL_BARON_ULTIMATUM, player))
aura->SetDuration(_baronRunTime * MINUTE * IN_MILLISECONDS);
SpawnScarletThread();
}
void OnCreatureCreate(Creature* creature) override
@@ -367,6 +380,17 @@ public:
SaveToDB();
}
void SetGuidData(uint32 type, ObjectGuid data) override
{
if (type != DATA_SCARLET_THREAD_LOOTED || data != _scarletThreadGUID)
return;
_scarletThreadUsedLocations |= 1 << _scarletThreadLocation;
_scarletThreadGUID.Clear();
SpawnScarletThread();
SaveToDB();
}
void ReadSaveDataMore(std::istringstream& data) override
{
data >> _baronRunProgress;
@@ -377,6 +401,11 @@ public:
data >> _slaughterProgress;
data >> _postboxesOpened;
data >> _barthilasrunProgress;
uint32 scarletThreadUsedLocations;
if (data >> scarletThreadUsedLocations && scarletThreadUsedLocations <= AllScarletThreadLocations)
_scarletThreadUsedLocations = scarletThreadUsedLocations;
if (_baronRunTime)
{
events.ScheduleEvent(EVENT_BARON_TIME, 60s);
@@ -397,7 +426,8 @@ public:
<< _zigguratState3 << ' '
<< _slaughterProgress << ' '
<< _postboxesOpened << ' '
<< _barthilasrunProgress;
<< _barthilasrunProgress << ' '
<< uint32(_scarletThreadUsedLocations);
}
uint32 GetData(uint32 type) const override
@@ -612,6 +642,35 @@ public:
ObjectGuid _trappedPlayerGUID;
ObjectGuid _trapGatesGUIDs[4];
uint8 _scarletThreadUsedLocations;
uint8 _scarletThreadLocation;
ObjectGuid _scarletThreadGUID;
void SpawnScarletThread()
{
if (_scarletThreadGUID || _scarletThreadUsedLocations == AllScarletThreadLocations)
return;
std::array<uint8, ScarletThreadSpawnCount> availableLocations{};
uint8 availableLocationCount = 0;
for (uint8 location = 0; location < ScarletThreadSpawnCount; ++location)
if (!(_scarletThreadUsedLocations & (1 << location)))
availableLocations[availableLocationCount++] = location;
if (!availableLocationCount)
return;
_scarletThreadLocation = availableLocations[urand(0, availableLocationCount - 1)];
std::list<GameObject*> threads;
instance->SummonGameObjectGroup(_scarletThreadLocation, &threads);
if (threads.empty())
return;
_scarletThreadGUID = threads.front()->GetGUID();
threads.front()->setActive(true);
}
void gate_delay(int gate)
{
if (_trapGatesGUIDs[2 * gate])
@@ -642,7 +701,33 @@ public:
}
};
class go_enchanted_scarlet_thread : public GameObjectScript
{
public:
go_enchanted_scarlet_thread() : GameObjectScript("go_enchanted_scarlet_thread") { }
void OnLootStateChanged(GameObject* go, uint32 state, Unit* /*unit*/) override
{
if (state != GO_JUST_DEACTIVATED)
return;
for (LootItem const& item : go->loot.quest_items)
{
if (item.itemid != ITEM_ENCHANTED_SCARLET_THREAD || !item.is_looted)
continue;
if (InstanceScript* instance = go->GetInstanceScript())
instance->SetGuidData(DATA_SCARLET_THREAD_LOOTED, go->GetGUID());
return;
}
go->SetLootState(GO_READY);
}
};
void AddSC_instance_stratholme()
{
new instance_stratholme();
new go_enchanted_scarlet_thread();
}
@@ -30,6 +30,7 @@ enum DataTypes
TYPE_BARON_FIGHT = 4,
TYPE_MALLOW = 5,
TYPE_BARTHILAS_RUN = 6,
DATA_SCARLET_THREAD_LOOTED = 7,
DATA_BARON_RUN_NONE = 0,
DATA_BARON_RUN_GATE = 1,
@@ -81,6 +82,8 @@ enum GameobjectIds
enum MiscIds
{
ITEM_ENCHANTED_SCARLET_THREAD = 12734,
SAY_BLACK_GUARD_INIT = 0,
SAY_BARON_INIT_YELL = 0,
SAY_BRAON_ZIGGURAT_FALL_YELL = 1,