Separating state out of the location

This commit is contained in:
Vladislav Khorev committed 2026-10-30 14:56:24 +06:00
1 parent 5e9a663812
commit 297bd7377f
45 files changed
+2114 -778

No files matched your search

+63 -13
View File
@@ -320,6 +320,8 @@ namespace FRG
void Location::setup(const LocationSetup& params, AudioPlayerAsync* audioPlayer)
{
if (!params.gameState) throw std::runtime_error("Location requires authoritative state binding");
if (!params.definition) throw std::runtime_error("Location requires prepared content definition");
const LocationDefinition& definition = *params.definition;
this->audioPlayer = audioPlayer;
pathVisualization.initialize();
@@ -330,16 +332,18 @@ namespace FRG
// Load static game objects
{
StaticObjectSet staticObjects = GameObjectLoader::loadAndCreateGameObjects(params.gameObjectsJsonPath, renderer, CONST_ZIP_FILE);
StaticObjectSet staticObjects =
GameObjectLoader::createGameObjects(
definition.staticObjects, renderer, CONST_ZIP_FILE);
gameObjects = std::move(staticObjects.single);
instancedBatches = std::move(staticObjects.batches);
}
SDL_PumpEvents();
// Load interactive objects
interactiveObjects = GameObjectLoader::loadAndCreateInteractiveObjects(
params.interactiveObjectsJsonPath, renderer, params.gameState->interactiveObjects,
CONST_ZIP_FILE);
interactiveObjects = GameObjectLoader::createInteractiveObjects(
definition.interactiveObjects, renderer,
params.gameState->interactiveObjects, CONST_ZIP_FILE);
SDL_PumpEvents();
auto sparkTexture = renderer.textureManager.LoadFromPng("resources/w/spark.png", CONST_ZIP_FILE);
@@ -347,10 +351,6 @@ namespace FRG
if (!params.player) throw std::runtime_error("Location requires game-level player binding");
player = params.player;
player->bindToLocation(locationId_);
updateCharacterState(*player, [&params](CharacterState& workingState) {
workingState.position = params.playerPosition;
});
setCharacterTarget(*player, params.playerPosition);
synchronizeRemotePlayers();
logger() << "Load resurces step 9" << std::endl;
SDL_PumpEvents();
@@ -358,8 +358,9 @@ namespace FRG
// Load NPCs from JSON. Aggressive (canAttack) NPCs need a player target
// and hit sparks; peaceful NPCs don't take damage from the player so
// they don't need either.
npcs = GameObjectLoader::loadAndCreate_Npcs(
params.npcsJsonPath, renderer, params.gameState->npcs, gameServer_, locationId_, CONST_ZIP_FILE);
npcs = GameObjectLoader::createNpcs(
definition.npcs, renderer, params.gameState->npcs,
gameServer_, locationId_, CONST_ZIP_FILE);
for (auto& npc : npcs) {
if (!npc) continue;
auto state = npc->stateSnapshot();
@@ -371,9 +372,58 @@ namespace FRG
SDL_PumpEvents();
loadTeleportZones(params.teleportsJsonPath, CONST_ZIP_FILE);
loadTriggerZones(params.triggerZonesJsonPath, CONST_ZIP_FILE);
loadPointLights(params.lightsJsonPath, CONST_ZIP_FILE);
auto activeTeleportTexture =
renderer.textureManager.LoadFromPng(
"resources/w/star.png", CONST_ZIP_FILE);
auto inactiveTeleportTexture =
renderer.textureManager.LoadFromPng(
"resources/w/star_red.png", CONST_ZIP_FILE);
for (const TeleportDefinition& data : definition.teleports) {
TeleportZone zone;
zone.id = data.id;
zone.position = data.position;
zone.radius = data.radius;
zone.destinationLocation = data.destinationLocation;
zone.destinationPosition = data.destinationPosition;
zone.destinationRotationY = data.destinationRotationY;
zone.automatic = data.automatic;
zone.automaticRadius = data.automaticRadius;
auto active = params.gameState->teleportZones.find(data.id);
zone.active = active != params.gameState->teleportZones.end()
? active->second : data.active;
zone.initSparks(
activeTeleportTexture, inactiveTeleportTexture);
teleportZones.push_back(std::move(zone));
}
for (const TriggerZoneDefinition& data : definition.triggerZones) {
TriggerZone zone;
zone.id = data.id;
zone.position = data.position;
zone.radius = data.radius;
zone.hysteresis = data.hysteresis;
auto state = params.gameState->triggerZones.find(data.id);
if (state != params.gameState->triggerZones.end()) {
zone.enabled = state->second.enabled;
zone.playerInside = state->second.playerInside;
} else {
zone.enabled = data.enabled;
}
triggerZones.push_back(std::move(zone));
}
for (const PointLightDefinition& data : definition.pointLights) {
PointLight light;
light.id = data.id;
light.position = data.position;
light.direction = data.direction;
light.color = data.color;
light.autoLight = data.autoLight;
light.autoLightDistance = data.autoLightDistance;
light.limitX = data.limitX;
light.limitY = data.limitY;
light.autoLightLimitX = data.autoLightLimitX;
light.autoLightLimitY = data.autoLightLimitY;
pointLights.push_back(std::move(light));
}
SDL_PumpEvents();