From 4ff5b6189dc55854609985bdb52d9e8c7180a2a9 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Mon, 16 Nov 2020 18:55:27 +0100 Subject: [PATCH] Core/Maps: implement new flags for instance spawn groups to allow to restrict spawn groups to horde or alliance only *use the new flags to restrict the Scarlet Monastery Alliance spawns to alliance players only --- .../world/4.3.4/2020_11_16_00_world.sql | 13 ++++++ src/server/game/Globals/ObjectMgr.cpp | 6 +++ src/server/game/Globals/ObjectMgr.h | 5 +- src/server/game/Instances/InstanceScript.cpp | 46 +++++++------------ .../instance_scarlet_monastery.cpp | 4 +- 5 files changed, 41 insertions(+), 33 deletions(-) create mode 100644 sql/updates/world/4.3.4/2020_11_16_00_world.sql diff --git a/sql/updates/world/4.3.4/2020_11_16_00_world.sql b/sql/updates/world/4.3.4/2020_11_16_00_world.sql new file mode 100644 index 0000000000..1048ed2b96 --- /dev/null +++ b/sql/updates/world/4.3.4/2020_11_16_00_world.sql @@ -0,0 +1,13 @@ +SET @CGUID := 396548; +SET @GROUPID := 453; +DELETE FROM `spawn_group_template` WHERE `groupId`= @GROUPID; +INSERT INTO `spawn_group_template` (`groupId`, `groupName`, `groupFlags`) VALUES +(@GROUPID, 'Scarlet Monastery - Alliance Spawns', 4); + +DELETE FROM `spawn_group` WHERE `groupId`= @GROUPID; +INSERT INTO `spawn_group` (`groupId`, `spawnType`, `spawnId`) +SELECT @GROUPID, 0, `guid` FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+20 AND `guid` NOT IN (@CGUID+5, @CGUID+15, @CGUID+16); + +DELETE FROM `instance_spawn_groups` WHERE `spawnGroupId`= @GROUPID; +INSERT INTO `instance_spawn_groups` (`instanceMapId`, `bossStateId`, `bossStates`, `spawnGroupId`, `flags`) VALUES +(189, 0, 0, @GROUPID, 0x1 | 0x4); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 2b17c5cadf..df4c884f7f 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2680,6 +2680,12 @@ void ObjectMgr::LoadInstanceSpawnGroups() TC_LOG_ERROR("sql.sql", "Instance spawn group (%u,%u) FLAG_ACTIVATE_SPAWN and FLAG_BLOCK_SPAWN may not be used together in a single entry - truncated to %u.", instanceMapId, spawnGroupId, info.Flags); } + if ((flags & InstanceSpawnGroupInfo::FLAG_ALLIANCE_ONLY) && (flags & InstanceSpawnGroupInfo::FLAG_HORDE_ONLY)) + { + info.Flags = flags & ~(InstanceSpawnGroupInfo::FLAG_ALLIANCE_ONLY | InstanceSpawnGroupInfo::FLAG_HORDE_ONLY); + TC_LOG_ERROR("sql.sql", "Instance spawn group (%u,%u) FLAG_ALLIANCE_ONLY and FLAG_HORDE_ONLY may not be used together in a single entry - truncated to %u.", instanceMapId, spawnGroupId, info.Flags); + } + if (flags & ~InstanceSpawnGroupInfo::FLAG_ALL) { info.Flags = flags & InstanceSpawnGroupInfo::FLAG_ALL; diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 4ace9e8be1..8f8a6c6a90 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -436,9 +436,10 @@ struct TC_GAME_API InstanceSpawnGroupInfo { FLAG_ACTIVATE_SPAWN = 0x01, FLAG_BLOCK_SPAWN = 0x02, - FLAG_FORCE_DESPAWN = 0x04, + FLAG_ALLIANCE_ONLY = 0x04, + FLAG_HORDE_ONLY = 0x08, - FLAG_ALL = (FLAG_ACTIVATE_SPAWN | FLAG_BLOCK_SPAWN | FLAG_FORCE_DESPAWN) + FLAG_ALL = (FLAG_ACTIVATE_SPAWN | FLAG_BLOCK_SPAWN | FLAG_ALLIANCE_ONLY | FLAG_HORDE_ONLY) }; uint8 BossStateId; uint8 BossStates; diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index 3cd8506072..3e922d398f 100644 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -242,49 +242,35 @@ void InstanceScript::UpdateSpawnGroups() { if (!_instanceSpawnGroups) return; - enum states : uint8 - { - BLOCK = 0x0, - SPAWN = 0x1, - FORCEBLOCK = 0x2, - FORCEDESPAWN = 0x4 - }; - - std::unordered_map newStates; + enum states { BLOCK, SPAWN, FORCEBLOCK }; + std::unordered_map newStates; for (auto it = _instanceSpawnGroups->begin(), end = _instanceSpawnGroups->end(); it != end; ++it) { InstanceSpawnGroupInfo const& info = *it; - uint8& curValue = newStates[info.SpawnGroupId]; // makes sure there's a BLOCK value in the map + states& curValue = newStates[info.SpawnGroupId]; // makes sure there's a BLOCK value in the map if (curValue == FORCEBLOCK) // nothing will change this continue; - if (!((1 << GetBossState(info.BossStateId)) & info.BossStates)) + if (info.BossStates && !((1 << GetBossState(info.BossStateId)) & info.BossStates)) // allow boss state 0 to always bypass this check + continue; + if (instance->GetTeamIdInInstance() == TEAM_ALLIANCE && (info.Flags & InstanceSpawnGroupInfo::FLAG_HORDE_ONLY) + || instance->GetTeamIdInInstance() == TEAM_HORDE && (info.Flags & InstanceSpawnGroupInfo::FLAG_ALLIANCE_ONLY)) continue; if (info.Flags & InstanceSpawnGroupInfo::FLAG_BLOCK_SPAWN) - curValue |= FORCEBLOCK; - if (info.Flags & InstanceSpawnGroupInfo::FLAG_ACTIVATE_SPAWN) - curValue |= SPAWN; - if (info.Flags & InstanceSpawnGroupInfo::FLAG_FORCE_DESPAWN) - curValue |= FORCEDESPAWN; + curValue = FORCEBLOCK; + else if (info.Flags & InstanceSpawnGroupInfo::FLAG_ACTIVATE_SPAWN) + curValue = SPAWN; } for (auto const& pair : newStates) { uint32 const groupId = pair.first; - uint8 state = pair.second; - // Spawn group is already active, skip - if (instance->IsSpawnGroupActive(groupId) == (state & SPAWN)) - continue; - - // Spawn group shall be spawned, spawn it - if (state & SPAWN) + bool const doSpawn = (pair.second == SPAWN); + if (instance->IsSpawnGroupActive(groupId) == doSpawn) + continue; // nothing to do here + // if we should spawn group, then spawn it... + if (doSpawn) instance->SpawnGroupSpawn(groupId); - - // Spawn group shall be disabled, disable it - if (state & FORCEBLOCK) + else // otherwise, set it as inactive so it no longer respawns (but don't despawn it) instance->SetSpawnGroupInactive(groupId); - - // Spawn group shall be despawned, despawn it - if (state & FORCEDESPAWN) - instance->SpawnGroupDespawn(groupId); } } diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp index 9a202beec0..55f0cfe6e4 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp @@ -66,11 +66,13 @@ class instance_scarlet_monastery : public InstanceMapScript void Create() override { + InstanceScript::Create(); instance->SpawnGroupSpawn(SPAWN_GROUP_ID_WHITEMANE_AND_MOGRAINE, true); } - void Load(char const* /*data*/) override + void Load(char const* data) override { + InstanceScript::Load(data); if (GetBossState(DATA_MOGRAINE_AND_WHITEMANE) != DONE) instance->SpawnGroupSpawn(SPAWN_GROUP_ID_WHITEMANE_AND_MOGRAINE, true, true); }