93 lines
3.4 KiB
C++
93 lines
3.4 KiB
C++
#pragma once
|
|
#include "items/Item.h"
|
|
#include "quest/QuestJournal.h"
|
|
#include "LocationGameState.h"
|
|
#include "ISaveable.h"
|
|
#include "external/nlohmann/json.hpp"
|
|
#include <unordered_map>
|
|
#include <string>
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
namespace FRG {
|
|
|
|
// The tutorial is one linear sequence: each step shows its hint until the player
|
|
// performs the action, then moves on to the next step (GameState::completeTutorialStep).
|
|
// Values are saved; AdvanceDialogue..PickUpItem keep the numbers of the old Step0..Step4.
|
|
enum class TutorialStep {
|
|
AdvanceDialogue, // dorm: "click to advance the dialogue"
|
|
RotateCamera, // dorm
|
|
Walk, // dorm: tap the floor
|
|
Zoom, // dorm; interactive objects stay locked until this is done
|
|
PickUpItem, // dorm: take the phone or the journal
|
|
EnterDarklands, // uni_interior: press the darklands button (once the spell note is picked up)
|
|
DarklandsHealth, // uni_interior darklands: health bar hint, until the player walks
|
|
DarklandsExplore, // uni_interior darklands: no hint, until the ghost zone is reached
|
|
DarklandsAttack, // uni_interior darklands: attack hint, until an enemy is killed
|
|
Completed // no more hints; a new game starts here when the tutorial is disabled
|
|
};
|
|
|
|
struct StoredChatMessage {
|
|
std::string text;
|
|
bool incoming;
|
|
};
|
|
|
|
struct GameState : public ISaveable {
|
|
static constexpr int kSchemaVersion = 5;
|
|
|
|
// --- World ---
|
|
// Campaign being played (see CampaignRegistry).
|
|
std::string campaignId = "main";
|
|
// Pure authoritative location data. Live Location/render/script instances are
|
|
// private runtime storage in InternalGameServer and never enter GameState.
|
|
std::unordered_map<std::string, LocationGameState> locations;
|
|
// Players are campaign-level entities and remain stable across locations.
|
|
PlayerStateMap players;
|
|
std::string currentLocationName;
|
|
bool isDarklands = false;
|
|
bool isNight = false;
|
|
bool isDawn = false;
|
|
|
|
// --- Player resources ---
|
|
Inventory inventory;
|
|
//float playerHp = 200.f;
|
|
float playerMaxHp = 200.f;
|
|
int money = 5500;
|
|
|
|
// --- Script globals ---
|
|
std::unordered_map<std::string, int> globalInts;
|
|
std::unordered_map<std::string, float> globalFloats;
|
|
|
|
// --- Quest system ---
|
|
Quest::QuestJournal questJournal;
|
|
|
|
// --- Tutorial ---
|
|
TutorialStep tutorialStep = TutorialStep::AdvanceDialogue;
|
|
// Hints that run alongside the linear steps, until the tutorial is Completed.
|
|
bool tutorialPhoneChatScreenOpened = false; // "open the messenger" hint is done
|
|
bool tutorialJournalScreenOpened = false; // "open the journal" hint is done
|
|
bool tutorialNeedOpenTaxiScreen = false; // "call a taxi" hint is showing
|
|
bool tutorialTaxiHintDone = false; // a taxi was ordered; never show the hint again
|
|
|
|
bool isTutorialActive() const { return tutorialStep != TutorialStep::Completed; }
|
|
// Moves to the next step if `step` is the current one; returns whether it did.
|
|
bool completeTutorialStep(TutorialStep step);
|
|
|
|
CharacterState* findCharacter(
|
|
const std::string& locationId, const std::string& characterId);
|
|
const CharacterState* findCharacter(
|
|
const std::string& locationId, const std::string& characterId) const;
|
|
|
|
// --- Phone / chat ---
|
|
bool chatUnread[3] = { true, true, true };
|
|
std::string chatPreviewMsg[3];
|
|
std::vector<StoredChatMessage> chatHistory[3];
|
|
|
|
bool taxiIsCalled = false;
|
|
|
|
void save(nlohmann::json& out) const override;
|
|
void load(const nlohmann::json& in) override;
|
|
};
|
|
|
|
} // namespace FRG
|