mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-22 18:15:31 +01:00
Scripts/InstanceScript: Implement database framework for managing spawn groups based on boss state. (#20103)
This commit is contained in:
@@ -46,7 +46,7 @@ BossBoundaryData::~BossBoundaryData()
|
||||
delete it->Boundary;
|
||||
}
|
||||
|
||||
InstanceScript::InstanceScript(Map* map) : instance(map), completedEncounters(0)
|
||||
InstanceScript::InstanceScript(Map* map) : instance(map), completedEncounters(0), _instanceSpawnGroups(sObjectMgr->GetSpawnGroupsForInstance(map->GetId()))
|
||||
{
|
||||
#ifdef TRINITY_API_USE_DYNAMIC_LINKING
|
||||
uint32 scriptId = sObjectMgr->GetInstanceTemplate(map->GetId())->ScriptId;
|
||||
@@ -186,27 +186,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());
|
||||
@@ -236,6 +215,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());
|
||||
@@ -310,7 +343,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
|
||||
@@ -337,6 +370,7 @@ bool InstanceScript::SetBossState(uint32 id, EncounterState state)
|
||||
if (Creature* minion = instance->GetCreature(*i))
|
||||
UpdateMinionState(minion, state);
|
||||
|
||||
UpdateSpawnGroups();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -347,6 +381,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)
|
||||
@@ -397,6 +438,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