fix(scripts): Spider Queen rain of fire hits two spots in each outer ring (issue 2016)

The live boss script's rain of fire takes every target of the first ROF target group and ROFImpactCnt (2) different
random targets of each other group. The server took one per group, so the rain was sparser than live. The impacts are
now picked like the live script (without repeats inside a group).

Check in game: AG Spider Queen stage 3; the rain of fire lands on the centre ring and on two spots in each outer ring.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-29 10:43:06 -05:00
parent 300932c657
commit 5dba7d5136
3 changed files with 39 additions and 19 deletions

View File

@@ -352,31 +352,20 @@ void BossSpiderQueenEnemyServer::RunRainOfFire(Entity* self) {
ToggleForSpecial(self, true);
SetRainOfFireStun(self, true);
impactList.clear();
auto index = 0u;
std::vector<std::vector<LWOOBJID>> targetGroups;
for (const auto& rofGroup : ROFTargetGroupIDTable) {
const auto spawners = Game::zoneManager->GetSpawnersInGroup(rofGroup);
std::vector<LWOOBJID> spawned;
for (auto* spawner : spawners) {
auto& spawned = targetGroups.emplace_back();
for (auto* spawner : Game::zoneManager->GetSpawnersInGroup(rofGroup)) {
for (const auto* node : spawner->m_Info.nodes) {
spawned.insert(spawned.end(), node->entities.begin(), node->entities.end());
}
}
if (index == 0) {
impactList.insert(impactList.end(), spawned.begin(), spawned.end());
} else if (!spawned.empty()) {
const auto randomIndex = GeneralUtils::GenerateRandomNumber<int32_t>(0, spawned.size() - 1);
impactList.push_back(spawned[randomIndex]);
}
index++;
}
impactList = PickRainOfFireImpacts(targetGroups, [](const size_t count) {
return GeneralUtils::GenerateRandomNumber<size_t>(0, count - 1);
});
const auto animTime = PlayAnimAndReturnTime(self, spiderROFAnim);
self->AddTimer("StartROF", animTime);
@@ -504,6 +493,25 @@ std::vector<LWOOBJID> BossSpiderQueenEnemyServer::BuildRapidFireTargets(const st
return attackTargets;
}
std::vector<LWOOBJID> BossSpiderQueenEnemyServer::PickRainOfFireImpacts(const std::vector<std::vector<LWOOBJID>>& groups,
const std::function<size_t(size_t count)>& randomIndex) {
std::vector<LWOOBJID> impacts;
for (size_t i = 0; i < groups.size(); i++) {
if (i == 0) {
impacts.insert(impacts.end(), groups[i].begin(), groups[i].end());
continue;
}
auto remaining = groups[i];
for (size_t picked = 0; picked < ROFImpactCnt && !remaining.empty(); picked++) {
const auto index = randomIndex(remaining.size());
impacts.push_back(remaining[index]);
remaining.erase(remaining.begin() + static_cast<std::ptrdiff_t>(index));
}
}
return impacts;
}
void BossSpiderQueenEnemyServer::OnZoneVolumeEntered(Entity* self, Entity* player, const std::string& volumeGroup) {
if (!player || !player->IsPlayer()) return;