Files
shadow-over-bishkek001/src/GameState.h
T

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