diff options
Diffstat (limited to 'src/server/game/Instances/InstanceScript.cpp')
-rw-r--r-- | src/server/game/Instances/InstanceScript.cpp | 88 |
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() |