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
@@ -0,0 +1,227 @@
|
||||
#pragma once
|
||||
|
||||
#include "../GameState.h"
|
||||
#include "../external/nlohmann/json.hpp"
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace FRG {
|
||||
|
||||
// Value-only view of authoritative state. It deliberately contains no runtime
|
||||
// pointers, callbacks, renderer objects, or mutable references, so the same
|
||||
// contract can later be transported over a network.
|
||||
struct ChatMessageSnapshot {
|
||||
std::string text;
|
||||
bool incoming = false;
|
||||
};
|
||||
|
||||
struct CharacterSnapshot {
|
||||
std::string id;
|
||||
CharacterState state;
|
||||
};
|
||||
|
||||
struct InteractiveObjectSnapshot {
|
||||
std::string id;
|
||||
InteractiveObjectState state;
|
||||
};
|
||||
|
||||
struct LocationSnapshot {
|
||||
std::string id;
|
||||
LocationState state;
|
||||
std::unordered_map<std::string, CharacterSnapshot> npcs;
|
||||
std::unordered_map<std::string, InteractiveObjectSnapshot> interactiveObjects;
|
||||
std::unordered_map<std::string, TriggerZoneGameState> triggerZones;
|
||||
std::unordered_map<std::string, bool> teleportZones;
|
||||
nlohmann::json dialogue;
|
||||
nlohmann::json scriptGlobals;
|
||||
};
|
||||
|
||||
struct GameSnapshot {
|
||||
std::uint64_t revision = 0;
|
||||
std::string campaignId;
|
||||
std::string currentLocationId;
|
||||
bool isDarklands = false;
|
||||
bool isNight = false;
|
||||
bool isDawn = false;
|
||||
float playerHp = 0.f;
|
||||
float playerMaxHp = 0.f;
|
||||
int money = 0;
|
||||
TutorialStep tutorialStep = TutorialStep::Completed;
|
||||
bool tutorialPhoneChatScreenOpened = false;
|
||||
bool tutorialJournalScreenOpened = false;
|
||||
bool tutorialNeedOpenTaxiScreen = false;
|
||||
bool tutorialTaxiHintDone = false;
|
||||
bool taxiIsCalled = false;
|
||||
bool chatUnread[3] = {};
|
||||
std::string chatPreview[3];
|
||||
std::vector<ChatMessageSnapshot> chatHistory[3];
|
||||
std::vector<std::string> inventoryItemIds;
|
||||
nlohmann::json questJournal;
|
||||
std::unordered_map<std::string, int> globalInts;
|
||||
std::unordered_map<std::string, float> globalFloats;
|
||||
std::unordered_map<std::string, CharacterSnapshot> players;
|
||||
std::unordered_map<std::string, LocationSnapshot> locations;
|
||||
std::vector<Quest::QuestState> quests;
|
||||
|
||||
bool isTutorialActive() const { return tutorialStep != TutorialStep::Completed; }
|
||||
};
|
||||
|
||||
struct SetWorldModeCommand { bool darklands; bool night; bool dawn; };
|
||||
struct SetCurrentLocationCommand { std::string locationId; };
|
||||
struct SetPlayerHealthCommand { float hp; float maxHp; };
|
||||
struct SetMoneyCommand { int amount; };
|
||||
struct SpendMoneyCommand { int amount; };
|
||||
struct CompleteTutorialStepCommand { TutorialStep step; };
|
||||
struct SetTutorialStepCommand { TutorialStep step; };
|
||||
struct SetTutorialFlagsCommand {
|
||||
bool phoneChatOpened;
|
||||
bool journalOpened;
|
||||
bool needTaxiHint;
|
||||
bool taxiHintDone;
|
||||
};
|
||||
struct SetChatCommand {
|
||||
int index;
|
||||
bool unread;
|
||||
std::string preview;
|
||||
};
|
||||
struct AppendChatMessageCommand {
|
||||
int index;
|
||||
std::string text;
|
||||
bool incoming;
|
||||
};
|
||||
struct SetTaxiCalledCommand { bool called; };
|
||||
struct StartTaxiCommand { std::string locationId; };
|
||||
struct AddInventoryItemCommand { std::string itemId; };
|
||||
struct RemoveInventoryItemCommand { std::string itemId; };
|
||||
struct SetGlobalIntCommand { std::string key; int value; };
|
||||
struct SetGlobalFloatCommand { std::string key; float value; };
|
||||
struct SetCharacterTransformCommand {
|
||||
std::string locationId;
|
||||
std::string characterId;
|
||||
Eigen::Vector3f position;
|
||||
float facingAngle;
|
||||
};
|
||||
struct SetCharacterTargetCommand {
|
||||
std::string locationId;
|
||||
std::string characterId;
|
||||
std::string targetId;
|
||||
};
|
||||
struct ClearCharacterAttackTargetCommand {
|
||||
std::string locationId;
|
||||
std::string characterId;
|
||||
};
|
||||
struct SetCharacterDestinationCommand {
|
||||
std::string locationId;
|
||||
std::string characterId;
|
||||
Eigen::Vector3f target;
|
||||
std::string callbackName;
|
||||
};
|
||||
struct StopCharacterCommand {
|
||||
std::string locationId;
|
||||
std::string characterId;
|
||||
};
|
||||
struct FaceCharacterCommand {
|
||||
std::string locationId;
|
||||
std::string characterId;
|
||||
std::string targetId;
|
||||
};
|
||||
struct ReplanCharacterCommand {
|
||||
std::string locationId;
|
||||
std::string characterId;
|
||||
};
|
||||
struct ResetCharacterAfterDeathCommand {
|
||||
std::string locationId;
|
||||
std::string characterId;
|
||||
};
|
||||
struct TryCharacterAttackComboCommand {
|
||||
std::string locationId;
|
||||
std::string characterId;
|
||||
};
|
||||
struct SetCharacterHealthCommand {
|
||||
std::string locationId;
|
||||
std::string characterId;
|
||||
float hp;
|
||||
};
|
||||
struct SetCharacterAnimationMetadataCommand {
|
||||
std::string locationId;
|
||||
std::string characterId;
|
||||
AnimationState animationState;
|
||||
int startFrame;
|
||||
int frameCount;
|
||||
};
|
||||
struct DamageCharacterCommand {
|
||||
std::string locationId;
|
||||
std::string characterId;
|
||||
float amount;
|
||||
std::string attackerId;
|
||||
};
|
||||
struct CommitCharacterStateCommand {
|
||||
std::string locationId;
|
||||
std::string characterId;
|
||||
CharacterState state;
|
||||
};
|
||||
struct SetInteractiveObjectActiveCommand {
|
||||
std::string locationId;
|
||||
std::string objectId;
|
||||
bool active;
|
||||
};
|
||||
struct SetTriggerZoneEnabledCommand {
|
||||
std::string locationId;
|
||||
std::string zoneId;
|
||||
bool enabled;
|
||||
};
|
||||
struct ReloadQuestDefinitionsCommand { std::string path; std::string zipFile; };
|
||||
|
||||
using GameCommand = std::variant<
|
||||
SetWorldModeCommand,
|
||||
SetCurrentLocationCommand,
|
||||
SetPlayerHealthCommand,
|
||||
SetMoneyCommand,
|
||||
SpendMoneyCommand,
|
||||
CompleteTutorialStepCommand,
|
||||
SetTutorialStepCommand,
|
||||
SetTutorialFlagsCommand,
|
||||
SetChatCommand,
|
||||
AppendChatMessageCommand,
|
||||
SetTaxiCalledCommand,
|
||||
StartTaxiCommand,
|
||||
AddInventoryItemCommand,
|
||||
RemoveInventoryItemCommand,
|
||||
SetGlobalIntCommand,
|
||||
SetGlobalFloatCommand,
|
||||
SetCharacterTransformCommand,
|
||||
SetCharacterTargetCommand,
|
||||
ClearCharacterAttackTargetCommand,
|
||||
SetCharacterDestinationCommand,
|
||||
StopCharacterCommand,
|
||||
FaceCharacterCommand,
|
||||
ReplanCharacterCommand,
|
||||
ResetCharacterAfterDeathCommand,
|
||||
TryCharacterAttackComboCommand,
|
||||
SetCharacterHealthCommand,
|
||||
SetCharacterAnimationMetadataCommand,
|
||||
DamageCharacterCommand,
|
||||
CommitCharacterStateCommand,
|
||||
SetInteractiveObjectActiveCommand,
|
||||
SetTriggerZoneEnabledCommand,
|
||||
ReloadQuestDefinitionsCommand>;
|
||||
|
||||
class IGameServer {
|
||||
public:
|
||||
virtual ~IGameServer() = default;
|
||||
|
||||
// Each returned object is immutable and remains valid after later commands.
|
||||
virtual std::shared_ptr<const GameSnapshot> snapshot() const = 0;
|
||||
virtual void submit(const GameCommand& command) = 0;
|
||||
virtual void update(std::int64_t deltaMs) = 0;
|
||||
|
||||
// Persistence stays server-side. The JSON shape is GameState's established
|
||||
// save schema and is intentionally not the wire snapshot shape.
|
||||
virtual void save(nlohmann::json& out) const = 0;
|
||||
virtual void load(const nlohmann::json& in) = 0;
|
||||
};
|
||||
|
||||
} // namespace FRG
|
||||
Reference in new issue
Block a user