aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Dove <1695733+jasongdove@users.noreply.github.com>2025-07-08 22:26:37 +0000
committerGitHub <noreply@github.com>2025-07-09 00:26:37 +0200
commitc7f5696479bb85c8fc7ee0d9fdaeb92e2b32213f (patch)
tree5eb2e7ad82f88dd089a58aad31f54c996d9edba3
parent04d44bd3a081fdf1b13ff20cd97a399f0fdfc477 (diff)
Core/Scenarios: Allow scripts to set instance scenario by id (#31104)
* add example at Stratholme service entrance
-rw-r--r--sql/updates/world/master/2025_07_08_00_world.sql3
-rw-r--r--src/server/game/Maps/Map.cpp20
-rw-r--r--src/server/game/Maps/Map.h8
-rw-r--r--src/server/game/Maps/MapManager.cpp2
-rw-r--r--src/server/game/Scenarios/InstanceScenario.cpp9
-rw-r--r--src/server/game/Scenarios/ScenarioMgr.cpp9
-rw-r--r--src/server/game/Scenarios/ScenarioMgr.h3
-rw-r--r--src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp22
8 files changed, 58 insertions, 18 deletions
diff --git a/sql/updates/world/master/2025_07_08_00_world.sql b/sql/updates/world/master/2025_07_08_00_world.sql
new file mode 100644
index 00000000000..106e98b1120
--- /dev/null
+++ b/sql/updates/world/master/2025_07_08_00_world.sql
@@ -0,0 +1,3 @@
+DELETE FROM `areatrigger_scripts` WHERE `entry` IN (10107);
+INSERT INTO `areatrigger_scripts` (`entry`, `ScriptName`) VALUES
+(10107, 'at_stratholme_service_entrance');
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 41d19ba4e4c..2382850e9f8 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -2809,7 +2809,7 @@ template TC_GAME_API void Map::RemoveFromMap(Conversation*, bool);
InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, Difficulty SpawnMode, TeamId InstanceTeam, InstanceLock* instanceLock,
Optional<uint32> lfgDungeonsId)
: Map(id, expiry, InstanceId, SpawnMode),
- i_data(nullptr), i_script_id(0), i_scenario(nullptr), i_instanceLock(instanceLock), i_lfgDungeonsId(lfgDungeonsId)
+ i_data(nullptr), i_script_id(0), i_instanceLock(instanceLock), i_lfgDungeonsId(lfgDungeonsId)
{
//lets initialize visibility distance for dungeons
InstanceMap::InitVisibilityDistance();
@@ -2834,7 +2834,6 @@ InstanceMap::~InstanceMap()
i_instanceLock->SetInUse(false);
delete i_data;
- delete i_scenario;
}
void InstanceMap::InitVisibilityDistance()
@@ -3081,6 +3080,23 @@ std::string const& InstanceMap::GetScriptName() const
return sObjectMgr->GetScriptName(i_script_id);
}
+void InstanceMap::SetInstanceScenario(InstanceScenario* scenario)
+{
+ i_scenario.reset(); // sends exit packets to all players
+
+ if (scenario)
+ {
+ i_scenario.reset(scenario);
+
+ scenario->LoadInstanceData();
+
+ DoOnPlayers([scenario](Player* player)
+ {
+ scenario->OnPlayerEnter(player);
+ });
+ }
+}
+
void InstanceMap::UpdateInstanceLock(UpdateBossStateSaveDataEvent const& updateSaveDataEvent)
{
if (i_instanceLock)
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index f16d95e5687..af10a1850a8 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -904,9 +904,9 @@ class TC_GAME_API InstanceMap : public Map
std::string const& GetScriptName() const;
InstanceScript* GetInstanceScript() { return i_data; }
InstanceScript const* GetInstanceScript() const { return i_data; }
- InstanceScenario* GetInstanceScenario() { return i_scenario; }
- InstanceScenario const* GetInstanceScenario() const { return i_scenario; }
- void SetInstanceScenario(InstanceScenario* scenario) { i_scenario = scenario; }
+ InstanceScenario* GetInstanceScenario() { return i_scenario.get(); }
+ InstanceScenario const* GetInstanceScenario() const { return i_scenario.get(); }
+ void SetInstanceScenario(InstanceScenario* scenario);
InstanceLock const* GetInstanceLock() const { return i_instanceLock; }
void UpdateInstanceLock(UpdateBossStateSaveDataEvent const& updateSaveDataEvent);
void UpdateInstanceLock(UpdateAdditionalSaveDataEvent const& updateSaveDataEvent);
@@ -928,7 +928,7 @@ class TC_GAME_API InstanceMap : public Map
Optional<SystemTimePoint> i_instanceExpireEvent;
InstanceScript* i_data;
uint32 i_script_id;
- InstanceScenario* i_scenario;
+ std::unique_ptr<InstanceScenario> i_scenario;
InstanceLock* i_instanceLock;
GroupInstanceReference i_owningGroupRef;
Optional<uint32> i_lfgDungeonsId;
diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp
index 4332c5a52e2..7d06b19153e 100644
--- a/src/server/game/Maps/MapManager.cpp
+++ b/src/server/game/Maps/MapManager.cpp
@@ -114,7 +114,7 @@ InstanceMap* MapManager::CreateInstance(uint32 mapId, uint32 instanceId, Instanc
map->TrySetOwningGroup(group);
map->CreateInstanceData();
- map->SetInstanceScenario(sScenarioMgr->CreateInstanceScenario(map, team));
+ map->SetInstanceScenario(sScenarioMgr->CreateInstanceScenarioForTeam(map, team));
map->InitSpawnGroupState();
if (sWorld->getBoolConfig(CONFIG_INSTANCEMAP_LOAD_GRIDS))
diff --git a/src/server/game/Scenarios/InstanceScenario.cpp b/src/server/game/Scenarios/InstanceScenario.cpp
index c477cf69fb7..a40a17ecc77 100644
--- a/src/server/game/Scenarios/InstanceScenario.cpp
+++ b/src/server/game/Scenarios/InstanceScenario.cpp
@@ -28,13 +28,6 @@
InstanceScenario::InstanceScenario(InstanceMap* map, ScenarioData const* scenarioData) : Scenario(map, scenarioData)
{
- ASSERT(_map);
- LoadInstanceData();
-
- Map::PlayerList const& players = map->GetPlayers();
- for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
- if (Player* player = itr->GetSource()->ToPlayer())
- SendScenarioState(player);
}
void InstanceScenario::LoadInstanceData()
@@ -60,7 +53,7 @@ void InstanceScenario::LoadInstanceData()
if (isDespawned)
for (auto const& [spawnGroupId, spawn] : sObjectMgr->GetSpawnMetadataForGroup(spawnGroup.SpawnGroupId))
if (SpawnData const* spawnData = spawn->ToSpawnData())
- ++despawnedCreatureCountsById[spawnData->id];
+ ++despawnedCreatureCountsById[spawnData->id];
}
for (Criteria const* criteria : killCreatureCriteria)
diff --git a/src/server/game/Scenarios/ScenarioMgr.cpp b/src/server/game/Scenarios/ScenarioMgr.cpp
index 15bee12f12d..9f4cabbab66 100644
--- a/src/server/game/Scenarios/ScenarioMgr.cpp
+++ b/src/server/game/Scenarios/ScenarioMgr.cpp
@@ -33,7 +33,7 @@ ScenarioMgr* ScenarioMgr::Instance()
return &instance;
}
-InstanceScenario* ScenarioMgr::CreateInstanceScenario(InstanceMap* map, TeamId team) const
+InstanceScenario* ScenarioMgr::CreateInstanceScenarioForTeam(InstanceMap* map, TeamId team) const
{
auto dbDataItr = _scenarioDBData.find(std::make_pair(map->GetId(), map->GetDifficultyID()));
// No scenario registered for this map and difficulty in the database
@@ -53,10 +53,15 @@ InstanceScenario* ScenarioMgr::CreateInstanceScenario(InstanceMap* map, TeamId t
break;
}
+ return CreateInstanceScenario(map, scenarioID);
+}
+
+InstanceScenario* ScenarioMgr::CreateInstanceScenario(InstanceMap* map, uint32 scenarioID) const
+{
auto itr = _scenarioData.find(scenarioID);
if (itr == _scenarioData.end())
{
- TC_LOG_ERROR("scenario", "Table `scenarios` contained data linking scenario (Id: {}) to map (Id: {}), difficulty (Id: {}) but no scenario data was found related to that scenario Id.", scenarioID, map->GetId(), map->GetDifficultyID());
+ TC_LOG_ERROR("scenario", "No scenario data was found related to scenario (Id: {}) for map (Id: {}), difficulty (Id: {}).", scenarioID, map->GetId(), map->GetDifficultyID());
return nullptr;
}
diff --git a/src/server/game/Scenarios/ScenarioMgr.h b/src/server/game/Scenarios/ScenarioMgr.h
index 96711a998e2..644ad9e4d67 100644
--- a/src/server/game/Scenarios/ScenarioMgr.h
+++ b/src/server/game/Scenarios/ScenarioMgr.h
@@ -110,7 +110,8 @@ public:
static ScenarioMgr* Instance();
- InstanceScenario* CreateInstanceScenario(InstanceMap* map, TeamId team) const;
+ InstanceScenario* CreateInstanceScenarioForTeam(InstanceMap* map, TeamId team) const;
+ InstanceScenario* CreateInstanceScenario(InstanceMap* map, uint32 scenarioID) const;
void LoadDBData();
void LoadDB2Data();
diff --git a/src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp b/src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp
index 0d092af1082..920d2f1d0b2 100644
--- a/src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp
+++ b/src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp
@@ -33,7 +33,9 @@ EndContentData */
#include "GameObject.h"
#include "GameObjectAI.h"
#include "Group.h"
+#include "ScenarioMgr.h"
#include "InstanceScript.h"
+#include "Map.h"
#include "MotionMaster.h"
#include "ObjectAccessor.h"
#include "Player.h"
@@ -388,6 +390,25 @@ class spell_stratholme_haunting_phantoms : public AuraScript
}
};
+static constexpr uint32 StratholmeLfgDungeonServiceEntrance = 274;
+static constexpr uint32 StratholmeScenarioServiceEntrance = 637;
+
+// 10107 - Areatrigger
+class at_stratholme_service_entrance : public OnlyOnceAreaTriggerScript
+{
+public:
+ at_stratholme_service_entrance() : OnlyOnceAreaTriggerScript("at_stratholme_service_entrance") { }
+
+ bool TryHandleOnce(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
+ {
+ if (InstanceMap* map = player->GetMap()->ToInstanceMap())
+ if (map->GetLfgDungeonsId() == StratholmeLfgDungeonServiceEntrance)
+ map->SetInstanceScenario(sScenarioMgr->CreateInstanceScenario(map, StratholmeScenarioServiceEntrance));
+
+ return true;
+ }
+};
+
void AddSC_stratholme()
{
new go_gauntlet_gate();
@@ -395,4 +416,5 @@ void AddSC_stratholme()
new npc_spectral_ghostly_citizen();
RegisterSpellScript(spell_ysida_saved_credit);
RegisterSpellScript(spell_stratholme_haunting_phantoms);
+ new at_stratholme_service_entrance();
}