Scripts/InstanceScript: Implement database framework for managing spawn groups based on boss state. (#20103)

(cherry picked from commit 84590be26d)
This commit is contained in:
Treeston
2017-08-04 00:23:40 +02:00
committed by Shauren
parent acb4934f76
commit 608c9aaabf
7 changed files with 169 additions and 27 deletions

View File

@@ -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()