mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
Ported from the live server scripts that ship with the client: - scripts\ai\LS\ForceFieldEffect.lua (LEGO Club and Starbase 3001 force fields): plays effect 3671 "cast" on whatever touches the phantom. - scripts\ai\NP\L_NPC_NP_JETPACK_GUY.lua (jetpack ambient NPCs): plays the object's "launch" effect when used. - scripts\02_server\Map\AM\L_SKELETON_SPAWNER_VOLUME.lua (Crux Prime Skullkin area): with 10 or more players in the volume the Skullkin engineer, miner and patroller networks maintain 2/6/6 instead of 1/4/4, with a 60 second cooldown between changes and a catch-up check when it ends. Only players are counted, and the count never goes below zero. WBL_Enemy_Grabbler.lua only sets wander variables for the old Lua movement AI, so it joins the other alpha wander scripts in the excluded list instead of logging as missing. Refs #746 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
76 lines
2.5 KiB
C++
76 lines
2.5 KiB
C++
#include "AmSkeletonSpawnerVolume.h"
|
|
|
|
#include "Entity.h"
|
|
#include "dZoneManager.h"
|
|
#include "Spawner.h"
|
|
|
|
namespace {
|
|
const std::u16string TotalPlayers = u"TotalPlayers";
|
|
const std::u16string SpawnStateMax = u"SpawnStateMax";
|
|
const std::u16string JustChanged = u"JustChanged";
|
|
|
|
void SetNumAndReset(const std::string& spawnerName, const int32_t num) {
|
|
for (auto* const spawner : Game::zoneManager->GetSpawnersByName(spawnerName)) {
|
|
spawner->SetNumToMaintain(num);
|
|
spawner->Reset();
|
|
}
|
|
}
|
|
}
|
|
|
|
void AmSkeletonSpawnerVolume::OnStartup(Entity* self) {
|
|
self->SetVar<int32_t>(TotalPlayers, 0);
|
|
self->SetVar<bool>(SpawnStateMax, false);
|
|
self->SetVar<bool>(JustChanged, false);
|
|
}
|
|
|
|
void AmSkeletonSpawnerVolume::OnCollisionPhantom(Entity* self, Entity* target) {
|
|
if (!target || !target->IsPlayer()) return;
|
|
|
|
const auto totalPlayers = self->GetVar<int32_t>(TotalPlayers) + 1;
|
|
self->SetVar<int32_t>(TotalPlayers, totalPlayers);
|
|
|
|
if (totalPlayers >= ChangeNum && !self->GetVar<bool>(JustChanged) && !self->GetVar<bool>(SpawnStateMax)) {
|
|
SetSpawnCounts(self, true);
|
|
}
|
|
}
|
|
|
|
void AmSkeletonSpawnerVolume::OnOffCollisionPhantom(Entity* self, Entity* target) {
|
|
if (!target || !target->IsPlayer()) return;
|
|
|
|
const auto totalPlayers = std::max(self->GetVar<int32_t>(TotalPlayers) - 1, 0);
|
|
self->SetVar<int32_t>(TotalPlayers, totalPlayers);
|
|
|
|
if (totalPlayers < ChangeNum && !self->GetVar<bool>(JustChanged) && self->GetVar<bool>(SpawnStateMax)) {
|
|
SetSpawnCounts(self, false);
|
|
}
|
|
}
|
|
|
|
void AmSkeletonSpawnerVolume::OnTimerDone(Entity* self, std::string timerName) {
|
|
if (timerName != "StateChange") return;
|
|
|
|
self->SetVar<bool>(JustChanged, false);
|
|
|
|
// Catch up on any change that was held back while the counts were cooling down.
|
|
const auto totalPlayers = self->GetVar<int32_t>(TotalPlayers);
|
|
const auto isMax = self->GetVar<bool>(SpawnStateMax);
|
|
if (!isMax && totalPlayers >= ChangeNum) {
|
|
SetSpawnCounts(self, true);
|
|
} else if (isMax && totalPlayers < ChangeNum) {
|
|
SetSpawnCounts(self, false);
|
|
}
|
|
}
|
|
|
|
void AmSkeletonSpawnerVolume::SetSpawnCounts(Entity* self, const bool max) {
|
|
self->SetVar<bool>(SpawnStateMax, max);
|
|
self->SetVar<bool>(JustChanged, true);
|
|
self->AddTimer("StateChange", ChangeCooldown);
|
|
|
|
// There are 6 engineer and 6 miner spawner networks.
|
|
for (int32_t i = 1; i <= 6; i++) {
|
|
SetNumAndReset("Skullkin_Engineer_" + std::to_string(i), max ? 2 : 1);
|
|
SetNumAndReset("Skullkin_Miner_" + std::to_string(i), max ? 6 : 4);
|
|
}
|
|
|
|
SetNumAndReset("Skullkin_Patrollers", max ? 6 : 4);
|
|
}
|