aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Instances/InstanceScript.cpp
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2017-08-04 00:23:40 +0200
committerShauren <shauren.trinity@gmail.com>2020-08-22 13:48:44 +0200
commit608c9aaabfcdbaf09edd11cdf268c243b3e69478 (patch)
tree11acd56239005fb5d9c96b733976830cf4365e7e /src/server/game/Instances/InstanceScript.cpp
parentacb4934f766321efbf90d0c6716f2df44c47ef16 (diff)
Scripts/InstanceScript: Implement database framework for managing spawn groups based on boss state. (#20103)
(cherry picked from commit 84590be26d6b3c56b95a804cbe889826186dd8a2)
Diffstat (limited to 'src/server/game/Instances/InstanceScript.cpp')
-rw-r--r--src/server/game/Instances/InstanceScript.cpp88
1 files changed, 65 insertions, 23 deletions
diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp
index 3b85c3dcac9..c3cccd75d63 100644
--- a/src/server/game/Instances/InstanceScript.cpp
+++ b/src/server/game/Instances/InstanceScript.cpp
@@ -48,7 +48,7 @@ BossBoundaryData::~BossBoundaryData()
delete it->Boundary;
}
-InstanceScript::InstanceScript(InstanceMap* map) : instance(map), completedEncounters(0),
+InstanceScript::InstanceScript(InstanceMap* map) : instance(map), completedEncounters(0), _instanceSpawnGroups(sObjectMgr->GetSpawnGroupsForInstance(map->GetId())),
_entranceId(0), _temporaryEntranceId(0), _combatResurrectionTimer(0), _combatResurrectionCharges(0), _combatResurrectionTimerStarted(false)
{
#ifdef TRINITY_API_USE_DYNAMIC_LINKING
@@ -193,27 +193,6 @@ void InstanceScript::LoadObjectData(ObjectData const* data, ObjectInfoMap& objec
}
}
-void InstanceScript::UpdateMinionState(Creature* minion, EncounterState state)
-{
- switch (state)
- {
- case NOT_STARTED:
- if (!minion->IsAlive())
- minion->Respawn();
- else if (minion->IsInCombat())
- minion->AI()->EnterEvadeMode();
- break;
- case IN_PROGRESS:
- if (!minion->IsAlive())
- minion->Respawn();
- else if (!minion->GetVictim())
- minion->AI()->DoZoneInCombat();
- break;
- default:
- break;
- }
-}
-
void InstanceScript::UpdateDoorState(GameObject* door)
{
DoorInfoMapBounds range = doors.equal_range(door->GetEntry());
@@ -243,6 +222,60 @@ void InstanceScript::UpdateDoorState(GameObject* door)
door->SetGoState(open ? GO_STATE_ACTIVE : GO_STATE_READY);
}
+void InstanceScript::UpdateMinionState(Creature* minion, EncounterState state)
+{
+ switch (state)
+ {
+ case NOT_STARTED:
+ if (!minion->IsAlive())
+ minion->Respawn();
+ else if (minion->IsInCombat())
+ minion->AI()->EnterEvadeMode();
+ break;
+ case IN_PROGRESS:
+ if (!minion->IsAlive())
+ minion->Respawn();
+ else if (!minion->GetVictim())
+ minion->AI()->DoZoneInCombat();
+ break;
+ default:
+ break;
+ }
+}
+
+void InstanceScript::UpdateSpawnGroups()
+{
+ if (!_instanceSpawnGroups)
+ return;
+ enum states { BLOCK, SPAWN, FORCEBLOCK };
+ std::unordered_map<uint32, states> newStates;
+ for (auto it = _instanceSpawnGroups->begin(), end = _instanceSpawnGroups->end(); it != end; ++it)
+ {
+ InstanceSpawnGroupInfo const& info = *it;
+ 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))
+ continue;
+ if (info.Flags & InstanceSpawnGroupInfo::FLAG_BLOCK_SPAWN)
+ curValue = FORCEBLOCK;
+ else if (info.Flags & InstanceSpawnGroupInfo::FLAG_ACTIVATE_SPAWN)
+ curValue = SPAWN;
+ }
+ for (auto const& pair : newStates)
+ {
+ uint32 const groupId = pair.first;
+ bool const doSpawn = (pair.second == SPAWN);
+ if (sObjectMgr->IsSpawnGroupActive(groupId) == doSpawn)
+ continue; // nothing to do here
+ // if we should spawn group, then spawn it...
+ if (doSpawn)
+ sObjectMgr->SpawnGroupSpawn(groupId, instance);
+ else // otherwise, set it as inactive so it no longer respawns (but don't despawn it)
+ sObjectMgr->SetSpawnGroupActive(groupId, false);
+ }
+}
+
BossInfo* InstanceScript::GetBossInfo(uint32 id)
{
ASSERT(id < bosses.size());
@@ -317,7 +350,7 @@ bool InstanceScript::SetBossState(uint32 id, EncounterState state)
if (bossInfo->state == TO_BE_DECIDED) // loading
{
bossInfo->state = state;
- //TC_LOG_ERROR("misc", "Inialize boss %u state as %u.", id, (uint32)state);
+ TC_LOG_DEBUG("scripts", "InstanceScript: Initialize boss %u state as %u.", id, (uint32)state);
return false;
}
else
@@ -370,6 +403,7 @@ bool InstanceScript::SetBossState(uint32 id, EncounterState state)
if (Creature* minion = instance->GetCreature(*i))
UpdateMinionState(minion, state);
+ UpdateSpawnGroups();
return true;
}
return false;
@@ -380,6 +414,13 @@ bool InstanceScript::_SkipCheckRequiredBosses(Player const* player /*= nullptr*/
return player && player->GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES);
}
+void InstanceScript::Create()
+{
+ for (size_t i = 0; i < bosses.size(); ++i)
+ SetBossState(i, NOT_STARTED);
+ UpdateSpawnGroups();
+}
+
void InstanceScript::Load(char const* data)
{
if (!data)
@@ -430,6 +471,7 @@ void InstanceScript::ReadSaveDataBossStates(std::istringstream& data)
if (buff < TO_BE_DECIDED)
SetBossState(bossId, EncounterState(buff));
}
+ UpdateSpawnGroups();
}
std::string InstanceScript::GetSaveData()