Files
shadow-over-bishkek001/src/LocationState.cpp
T

178 lines
5.2 KiB
C++

#include "LocationState.h"
#include <stdexcept>
namespace FRG {
std::shared_ptr<LocationLocalState> ClientLocationState::getOrCreate(
const std::string& locationId)
{
auto& state = locations[locationId];
if (!state) state = std::make_shared<LocationLocalState>();
return state;
}
void ClientLocationState::clear()
{
locations.clear();
}
void LocationLocalState::save(nlohmann::json& out) const
{
out = {
{"cameraAzimuth", cameraAzimuth},
{"cameraInclination", cameraInclination}
};
}
void LocationLocalState::load(const nlohmann::json& in)
{
cameraAzimuth = in.at("cameraAzimuth").get<float>();
cameraInclination = in.at("cameraInclination").get<float>();
}
void ClientLocationState::save(nlohmann::json& out) const
{
out["locations"] = nlohmann::json::object();
for (const auto& [id, state] : locations) {
if (!state) continue;
nlohmann::json value;
state->save(value);
out["locations"][id] = std::move(value);
}
}
void ClientLocationState::load(const nlohmann::json& in)
{
const auto& values = in.at("locations");
if (!values.is_object())
throw std::runtime_error("Client location state locations must be an object");
for (auto& [id, state] : locations)
if (state) *state = LocationLocalState{};
for (const auto& [id, value] : values.items())
getOrCreate(id)->load(value);
}
void saveSinglePlayerPersistence(
const nlohmann::json& networkState,
const ClientLocationState& localState,
nlohmann::json& out)
{
nlohmann::json savedLocalState;
localState.save(savedLocalState);
out = {
{"persistenceVersion", kSinglePlayerPersistenceVersion},
{"networkState", networkState},
{"localState", std::move(savedLocalState)}
};
}
void loadSinglePlayerPersistence(
const nlohmann::json& in,
nlohmann::json& networkState,
ClientLocationState& localState)
{
const int version = in.value("persistenceVersion", -1);
if (version != kSinglePlayerPersistenceVersion)
throw std::runtime_error(
"Unsupported single-player persistence version: " +
std::to_string(version));
networkState = in.at("networkState");
localState.load(in.at("localState"));
}
namespace {
nlohmann::json saveCar(const NpcCar& car)
{
nlohmann::json waypoints = nlohmann::json::array();
for (const auto& waypoint : car.waypoints)
waypoints.push_back(
{{"x", waypoint.x()}, {"y", waypoint.y()}, {"z", waypoint.z()}});
return {
{"position", {car.position.x(), car.position.y(), car.position.z()}},
{"rotation", car.rotation},
{"velocity", car.velocity},
{"steeringAngle", car.steeringAngle},
{"wheelAngle", car.wheelAngle},
{"mode", static_cast<int>(car.mode)},
{"waypoints", std::move(waypoints)},
{"currentWaypoint", car.currentWaypoint}
};
}
void loadCar(NpcCar& car, const nlohmann::json& value)
{
const auto& position = value.at("position");
car.position = {
position.at(0).get<float>(),
position.at(1).get<float>(),
position.at(2).get<float>()};
car.rotation = value.at("rotation").get<float>();
car.velocity = value.at("velocity").get<float>();
car.steeringAngle = value.at("steeringAngle").get<float>();
car.wheelAngle = value.at("wheelAngle").get<float>();
car.mode = static_cast<NpcCar::Mode>(value.at("mode").get<int>());
car.waypoints.clear();
for (const auto& waypoint : value.at("waypoints"))
car.waypoints.push_back({
waypoint.at("x").get<float>(),
waypoint.at("y").get<float>(),
waypoint.at("z").get<float>()});
car.currentWaypoint = value.at("currentWaypoint").get<std::size_t>();
}
}
std::vector<Eigen::Vector3f> LocationNetworkState::planPathExceptMyself(const Eigen::Vector3f& start, const Eigen::Vector3f& end, const std::string& entityId) const
{
return navigationMaps[activeNavigationIndex].findPathToNearest(start, end, {});
}
void LocationNetworkState::initNavigation(
const std::vector<std::string>& paths, const std::string& zipFile)
{
const int savedActiveNavigationIndex = activeNavigationIndex;
//navigationMapPaths = paths;
navigationMaps.clear();
navigationMaps.resize(paths.size());
for (size_t i = 0; i < paths.size(); ++i) {
navigationMaps[i].build(paths[i], zipFile);
}
activeNavigationIndex =
savedActiveNavigationIndex >= 0 &&
savedActiveNavigationIndex < static_cast<int>(navigationMaps.size())
? savedActiveNavigationIndex
: 0;
}
void LocationNetworkState::save(nlohmann::json& out) const
{
out["activeNavigationIndex"] = activeNavigationIndex;
out["targetInteractiveObjectId"] = targetInteractiveObjectId;
out["targetInteractNpcId"] = targetInteractNpcId;
out["targetTeleportZoneId"] = targetTeleportZoneId;
out["taxi"] = {
{"car", saveCar(taxiCar)},
{"arrivedCallbackCalled", taxiArrivedCallbackCalled}
};
}
void LocationNetworkState::load(const nlohmann::json& in)
{
activeNavigationIndex = in.value("activeNavigationIndex", activeNavigationIndex);
targetInteractiveObjectId = in.value("targetInteractiveObjectId", std::string());
targetInteractNpcId = in.value("targetInteractNpcId", std::string());
targetTeleportZoneId = in.value("targetTeleportZoneId", std::string());
const auto& taxi = in.at("taxi");
loadCar(taxiCar, taxi.at("car"));
taxiArrivedCallbackCalled =
taxi.at("arrivedCallbackCalled").get<bool>();
}
} // namespace FRG