working on campaign

This commit is contained in:
Vladislav Khorev committed 2026-10-23 22:47:55 +06:00
1 parent 9fa120d4ad
commit d38a75ea72
24 files changed
+929 -410

No files matched your search

+112
View File
@@ -0,0 +1,112 @@
#include "Campaign.h"
#include "utils/Utils.h"
#include "external/nlohmann/json.hpp"
#include <iostream>
namespace FRG {
using json = nlohmann::json;
static bool parseJsonFile(const std::string& path, const std::string& zipFile, json& out) {
const std::string content = readLocalizedConfigFile(path, zipFile);
if (content.empty()) {
std::cerr << "[Campaign] Failed to read " << path << "\n";
return false;
}
try {
out = json::parse(content);
} catch (const std::exception& e) {
std::cerr << "[Campaign] JSON parse error in " << path << ": " << e.what() << "\n";
return false;
}
return true;
}
static Eigen::Vector3f readVec3(const json& j) {
if (!j.is_array() || j.size() != 3) return Eigen::Vector3f::Zero();
return Eigen::Vector3f(j[0].get<float>(), j[1].get<float>(), j[2].get<float>());
}
bool LocationConfig::fromFile(const std::string& path, const std::string& zipFile, LocationConfig& out) {
json j;
if (!parseJsonFile(path, zipFile, j)) return false;
out = LocationConfig{};
out.id = j.value("id", "");
out.gameObjectsJsonPath = j.value("gameObjects", "");
out.interactiveObjectsJsonPath = j.value("interactiveObjects", "");
out.npcsJsonPath = j.value("npcs", "");
out.dialoguesJsonPath = j.value("dialogues", "");
out.navigationJsonPaths = j.value("navigation", std::vector<std::string>{});
out.scriptPath = j.value("script", "");
out.teleportsJsonPath = j.value("teleports", "");
out.triggerZonesJsonPath = j.value("triggerZones", "");
out.lightsJsonPath = j.value("lights", "");
if (j.contains("playerPosition")) out.playerPosition = readVec3(j["playerPosition"]);
out.lockInteractiveObjectsDuringTutorial = j.value("lockInteractiveObjectsDuringTutorial", false);
if (j.contains("taxi") && j["taxi"].is_object()) {
const json& t = j["taxi"];
Taxi taxi;
if (t.contains("triggerPosition")) taxi.triggerPosition = readVec3(t["triggerPosition"]);
if (t.contains("initialPosition")) taxi.initialPosition = readVec3(t["initialPosition"]);
if (t.contains("waypoints") && t["waypoints"].is_array()) {
for (const auto& w : t["waypoints"]) taxi.waypoints.push_back(readVec3(w));
}
taxi.initialRotation = t.value("initialRotation", taxi.initialRotation);
taxi.waypointReachRadius = t.value("waypointReachRadius", taxi.waypointReachRadius);
out.taxi = taxi;
}
if (out.id.empty()) {
std::cerr << "[Campaign] Location config without an id: " << path << "\n";
return false;
}
return true;
}
std::string CampaignConfig::title(Language lang) const {
auto it = titles.find(languageToCode(lang));
if (it != titles.end()) return it->second;
return titles.empty() ? id : titles.begin()->second;
}
CampaignRegistry& CampaignRegistry::instance() {
static CampaignRegistry reg;
return reg;
}
void CampaignRegistry::loadFromJson(const std::string& jsonPath, const std::string& zipFile) {
json j;
if (!parseJsonFile(jsonPath, zipFile, j)) return;
if (!j.contains("campaigns") || !j["campaigns"].is_array()) {
std::cerr << "[Campaign] No 'campaigns' array in " << jsonPath << "\n";
return;
}
campaigns_.clear();
for (const auto& entry : j["campaigns"]) {
CampaignConfig c;
c.id = entry.value("id", "");
if (c.id.empty()) continue;
c.titles = entry.value("title", std::map<std::string, std::string>{});
c.locationConfigPaths = entry.value("locations", std::vector<std::string>{});
c.startLocation = entry.value("startLocation", "");
c.startMusic = entry.value("startMusic", "");
c.startStatePath = entry.value("startState", "");
c.questsPath = entry.value("quests", "");
c.tutorial = entry.value("tutorial", false);
campaigns_.push_back(std::move(c));
}
logger() << "[Campaign] Loaded " << campaigns_.size() << " campaigns from " << jsonPath << "\n";
}
const CampaignConfig* CampaignRegistry::find(const std::string& id) const {
for (const auto& c : campaigns_) {
if (c.id == id) return &c;
}
return nullptr;
}
} // namespace FRG