Major refactoring - internal server state machine implemented
This commit is contained in:
1 parent
71c654e5b6
commit
66e93d46f4
48 files changed
+3948
-3696
No files matched your search
+37
-42
@@ -16,13 +16,15 @@
|
||||
#include "TeleportZone.h"
|
||||
#include "LocationEditor.h"
|
||||
#include "LocationState.h"
|
||||
#include "ISaveable.h"
|
||||
#include "LocationGameState.h"
|
||||
#include <functional>
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include "Character.h"
|
||||
|
||||
namespace FRG
|
||||
{
|
||||
class IGameServer;
|
||||
|
||||
struct PointLight
|
||||
{
|
||||
@@ -35,7 +37,7 @@ namespace FRG
|
||||
// Rectangular limits — keep light confined to a room-sized AABB centred on the light
|
||||
float limitX = 99999.f; // shader fragment limit: half-width in world X
|
||||
float limitY = 99999.f; // shader fragment limit: half-width in world Z
|
||||
float autoLightLimitX = -1.0f; // activation rect half-width X; <0 = use legacy nearest-light logic
|
||||
float autoLightLimitX = -1.0f; // activation rect half-width X; <0 = use nearest-light logic
|
||||
float autoLightLimitY = -1.0f; // activation rect half-width Z
|
||||
};
|
||||
|
||||
@@ -55,7 +57,7 @@ namespace FRG
|
||||
std::string interactiveObjectsJsonPath;
|
||||
std::string npcsJsonPath;
|
||||
std::string dialoguesJsonPath;
|
||||
std::vector<std::string> navigationJsonPaths;
|
||||
//std::vector<std::string> navigationJsonPaths;
|
||||
std::string scriptPath;
|
||||
std::string teleportsJsonPath;
|
||||
std::string triggerZonesJsonPath;
|
||||
@@ -64,17 +66,17 @@ namespace FRG
|
||||
// Player shared by all locations of a campaign (see Location::createPlayer);
|
||||
// setup() creates a private one when this is null.
|
||||
std::shared_ptr<Character> player;
|
||||
LocationGameState* gameState = nullptr;
|
||||
};
|
||||
|
||||
class Location : public ISaveable
|
||||
class Location
|
||||
{
|
||||
public:
|
||||
Location(Renderer& iRenderer, Inventory& iInventory);
|
||||
Location(Renderer& iRenderer, Inventory& iInventory, LocationState& state, IGameServer& server,
|
||||
std::string locationId);
|
||||
// Detaches the (shared, longer-lived) player from this location.
|
||||
~Location();
|
||||
|
||||
// ---- All serialisable runtime state ----
|
||||
LocationState state;
|
||||
const std::string& locationId() const { return locationId_; }
|
||||
|
||||
std::unordered_map<std::string, LoadedGameObject> gameObjects;
|
||||
|
||||
@@ -88,10 +90,11 @@ namespace FRG
|
||||
std::vector<std::unique_ptr<Character>> npcs;
|
||||
|
||||
// Builds the player character (models, animations, weapon, textures).
|
||||
static std::shared_ptr<Character> createPlayer(Renderer& renderer, AudioPlayerAsync* audioPlayer);
|
||||
static std::shared_ptr<Character> createPlayer(Renderer& renderer, AudioPlayerAsync* audioPlayer,
|
||||
CharacterState& state, IGameServer& server);
|
||||
|
||||
std::vector<PathFinder> navigationMaps;
|
||||
PathFinder* navigation = nullptr;
|
||||
//std::vector<PathFinder> navigationMaps;
|
||||
//int state.activeNavigationIndex = 0;
|
||||
|
||||
std::shared_ptr<ShadowMap> shadowMap;
|
||||
Eigen::Matrix4f cameraViewMatrix = Eigen::Matrix4f::Identity();
|
||||
@@ -114,10 +117,6 @@ namespace FRG
|
||||
|
||||
std::function<void()> onPlayerTaxiRequired;
|
||||
|
||||
// Optional, set by Game. While it returns true the player can't pick up /
|
||||
// use interactive objects (the dorm tutorial unlocks them step by step).
|
||||
std::function<bool()> areInteractiveObjectsLocked;
|
||||
|
||||
// Set by Game after setup(). Lua and onDeathAnimComplete call this to
|
||||
// request the transition without coupling Location to Game directly.
|
||||
std::function<bool()> requestDarklandsTransition;
|
||||
@@ -140,7 +139,7 @@ namespace FRG
|
||||
EditorMode editorMode = EditorMode::None;
|
||||
LocationEditor editor;
|
||||
|
||||
std::vector<std::string> navigationMapPaths;
|
||||
//std::vector<std::string> navigationMapPaths;
|
||||
|
||||
// Set by Game when the user's primary pointer (left mouse / single touch)
|
||||
// has crossed the tap-vs-drag threshold and is now rotating the camera.
|
||||
@@ -162,8 +161,20 @@ namespace FRG
|
||||
|
||||
|
||||
void setup(const LocationSetup& params, Quest::QuestJournal* journal, AudioPlayerAsync* audioPlayer);
|
||||
void setupNavigation(const std::vector<std::string>& paths);
|
||||
//void setupNavigation(const std::vector<std::string>& paths);
|
||||
bool switchNavigation(int index);
|
||||
void setCharacterTarget(Character& character, const Eigen::Vector3f& target,
|
||||
std::string callbackName = "");
|
||||
void updateCharacterState(
|
||||
Character& character,
|
||||
const std::function<void(CharacterState&)>& mutation);
|
||||
void clearCharacterAttackTarget(Character& character);
|
||||
void stopCharacter(Character& character);
|
||||
void faceCharacter(Character& character, std::string targetId);
|
||||
void replanCharacter(Character& character);
|
||||
void resetCharacterAfterDeath(Character& character);
|
||||
void tryCharacterAttackCombo(Character& character);
|
||||
void setCharacterHp(Character& character, float hp);
|
||||
InteractiveObject* raycastInteractiveObjects(const Eigen::Vector3f& rayOrigin, const Eigen::Vector3f& rayDir);
|
||||
Character* raycastNpcs(const Eigen::Vector3f& rayOrigin, const Eigen::Vector3f& rayDir, float maxDistance = 100.0f);
|
||||
|
||||
@@ -177,8 +188,7 @@ namespace FRG
|
||||
|
||||
bool setNavigationAreaAvailable(const std::string& areaName, bool available);
|
||||
|
||||
void update(int64_t deltaMs);
|
||||
void updateNpcCar(int64_t deltaMs);
|
||||
void update(int64_t deltaMs, const LocationSimulationEvents& events);
|
||||
// Purely visual feedback for click-triggered player routes. Disabling it
|
||||
// also cancels an animation that is currently playing.
|
||||
void setPathVisualizationEnabled(bool enabled);
|
||||
@@ -194,26 +204,21 @@ namespace FRG
|
||||
void setDialogueFlag(const std::string& flag, int value);
|
||||
int getDialogueFlag(const std::string& flag) const;
|
||||
|
||||
void onTaxiCalled();
|
||||
|
||||
// ---- Save / Load ----
|
||||
// Serialises LocationState + all Character/InteractiveObject sub-states + Lua globals.
|
||||
void save(nlohmann::json& out) const override;
|
||||
// Restores state from JSON written by save.
|
||||
// Navigation pointer and triggerZone.playerInside are re-synced automatically.
|
||||
void load(const nlohmann::json& in) override;
|
||||
protected:
|
||||
friend class LocationEditor;
|
||||
friend class Game;
|
||||
friend class ScriptEngine;
|
||||
friend class InternalGameServer;
|
||||
Renderer& renderer;
|
||||
Inventory& inventory;
|
||||
AudioPlayerAsync* audioPlayer;
|
||||
|
||||
private:
|
||||
LocationState& state; // non-owning binding to LocationGameState
|
||||
IGameServer& gameServer_;
|
||||
std::string locationId_;
|
||||
// ---- Pointer-to-index helpers ----
|
||||
InteractiveObject* getTargetInteractiveObject();
|
||||
TeleportZone* getTargetTeleportZone();
|
||||
int findInteractiveObjectIndex(const InteractiveObject* obj) const;
|
||||
int findTeleportZoneIndex(const TeleportZone* tz) const;
|
||||
|
||||
enum class InstancedTexture { None, Color, Darklands };
|
||||
|
||||
@@ -223,26 +228,16 @@ namespace FRG
|
||||
void drawInstancedStatics(const std::string& instancedShaderName, InstancedTexture textureKind,
|
||||
const std::function<void()>& setUniforms = {});
|
||||
|
||||
void resolveCharacterCollisions();
|
||||
void updateDynamicReplans(int64_t deltaMs);
|
||||
void loadTeleportZones(const std::string& jsonPath, const char* zipFile);
|
||||
void loadTriggerZones(const std::string& jsonPath, const char* zipFile);
|
||||
void loadPointLights(const std::string& jsonPath, const char* zipFile);
|
||||
void updateTriggerZones(const Eigen::Vector3f& playerPos);
|
||||
void nudgeCharacterAside(Character* standing, const Eigen::Vector3f& awayFrom);
|
||||
int findNpcIndex(const Character* npc) const;
|
||||
void fireBumpCallbacks(Character* mover, Character* standing);
|
||||
void captureAuxiliaryState(LocationGameState& out) const;
|
||||
void applyAuxiliaryState(const LocationGameState& in);
|
||||
|
||||
PathVisualization pathVisualization;
|
||||
|
||||
std::unordered_map<Character*, Eigen::Vector3f> lastCharacterPositions;
|
||||
std::unordered_map<Character*, int64_t> replanCooldownRemainingMs;
|
||||
std::unordered_map<Character*, int> stuckFrameCounts;
|
||||
std::unordered_map<Character*, float> stuckPauseRemainingS;
|
||||
|
||||
static constexpr float NPC_BUMP_CALLBACK_COOLDOWN = 5.0f;
|
||||
std::unordered_map<int, float> npcBumpedByPlayerCooldown;
|
||||
std::unordered_map<int, float> npcBumpsPlayerCooldown;
|
||||
};
|
||||
|
||||
} // namespace FRG
|
||||
Reference in new issue
Block a user