mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Scripts/InstanceScript: Implement database framework for managing spawn groups based on boss state. (#20103)
(cherry picked from commit 84590be26d)
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user