#include "BaseRandomServer.h" #include "EntityManager.h" #include "dZoneManager.h" #include "DestroyableComponent.h" #include "Spawner.h" #include "dLogger.h" void BaseRandomServer::BaseStartup(Entity* self) { self->SetVar(u"SpawnState", "min"); self->SetVar(u"JustChanged", false); CheckEvents(self); SpawnMapZones(self); } void BaseRandomServer::CheckEvents(Entity* self) { // TODO: Add events? } void BaseRandomServer::SpawnMapZones(Entity* self) { for (const auto& pair : sectionMultipliers) { const auto sectionName = zonePrefix + "_" + zoneName + "_" + pair.first; SpawnSection(self, sectionName, pair.second); } if (zoneName == "str") { SpawnNamedEnemy(self); } self->SetVar(u"bInit", true); } void BaseRandomServer::SpawnSection(Entity* self, const std::string& sectionName, float iMultiplier) { Zone* spawnLoad = GetRandomLoad(self, sectionName); if (spawnLoad == nullptr) { Game::logger->Log("BaseRandomServer", "Failed to find section: %s\n", sectionName.c_str()); return; } for (const auto& spawnerData : spawnLoad->entries) { if (spawnerData.name.empty()) { continue; } const auto spawnNum = std::floor(spawnerData.num * iMultiplier); const auto spawnerName = sectionName + "_" + spawnerData.name; SetSpawnerNetwork(self, spawnerName, spawnNum, spawnerData.lot); } } void BaseRandomServer::SetSpawnerNetwork(Entity* self, const std::string& spawnerName, int32_t spawnNum, LOT spawnLOT) { const auto& spawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName); if (spawnLOT == 11217 && spawnNum > 1) { spawnNum = 1; } if (spawners.empty()) { Game::logger->Log("BaseRandomServer", "Failed to find spawner: %s\n", spawnerName.c_str()); return; } auto* spawner = spawners[0]; if (spawnLOT != 0) { spawner->SetSpawnLot(spawnLOT); spawner->SetRespawnTime(respawnTime); } if (spawnNum != 0) { spawner->SetNumToMaintain(spawnNum); } if (spawnerName == "Named_Enemies") { spawner->SoftReset(); } spawner->Activate(); if (std::find(spawnersWatched.begin(), spawnersWatched.end(), spawner) != spawnersWatched.end()) { return; } spawner->AddSpawnedEntityDieCallback([this, self, spawner] () { NotifySpawnerOfDeath(self, spawner); }); spawnersWatched.push_back(spawner); } BaseRandomServer::Zone* BaseRandomServer::GetRandomLoad(Entity* self, const std::string& sectionName) { const auto zoneInfo = GeneralUtils::SplitString(sectionName, '_'); int32_t totalWeight = 0; for (const auto& load : zones) { totalWeight += load.iChance; } const auto randWeight = GeneralUtils::GenerateRandomNumber(0, totalWeight); int32_t weight = 0; for (auto& zone : zones) { weight += zone.iChance; if (randWeight <= weight) { return &zone; } } return nullptr; } void BaseRandomServer::NotifySpawnerOfDeath(Entity* self, Spawner* spawner) { const auto& spawnerName = spawner->GetName(); if (spawnerName == "Named_Enemies") { NamedEnemyDeath(self, spawner); return; } const auto& sectionName = spawnerName.substr(0, spawnerName.size() - 7); const auto variableName = u"mobsDead" + GeneralUtils::ASCIIToUTF16(sectionName); auto mobDeathCount = self->GetVar(variableName); mobDeathCount++; if (mobDeathCount >= mobDeathResetNumber) { const auto& zoneInfo = GeneralUtils::SplitString(sectionName, '_'); SpawnSection(self, sectionName, sectionMultipliers[zoneInfo[sectionIDConst - 1]]); } self->SetVar(variableName, mobDeathCount); } void BaseRandomServer::NamedEnemyDeath(Entity* self, Spawner* spawner) { const auto spawnDelay = GeneralUtils::GenerateRandomNumber(1, 2) * 450; self->AddTimer("SpawnNewEnemy", spawnDelay); } void BaseRandomServer::SpawnersUp(Entity* self) { } void BaseRandomServer::SpawnersDown(Entity* self) { } void BaseRandomServer::BaseOnTimerDone(Entity* self, const std::string& timerName) { NamedTimerDone(self, timerName); } void BaseRandomServer::SpawnNamedEnemy(Entity* self) { const auto enemy = namedMobs[GeneralUtils::GenerateRandomNumber(0, namedMobs.size() - 1)]; SetSpawnerNetwork(self, "Named_Enemies", 1, enemy); } void BaseRandomServer::NamedTimerDone(Entity* self, const std::string& timerName) { if (timerName == "SpawnNewEnemy") { SpawnNamedEnemy(self); } }