Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/game/StarPlayerUniverseMap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/game/StarPlayerUniverseMap.cpp')
-rw-r--r--source/game/StarPlayerUniverseMap.cpp287
1 files changed, 287 insertions, 0 deletions
diff --git a/source/game/StarPlayerUniverseMap.cpp b/source/game/StarPlayerUniverseMap.cpp
new file mode 100644
index 0000000..42167db
--- /dev/null
+++ b/source/game/StarPlayerUniverseMap.cpp
@@ -0,0 +1,287 @@
+#include "StarPlayerUniverseMap.hpp"
+#include "StarLexicalCast.hpp"
+#include "StarJsonExtra.hpp"
+
+namespace Star {
+
+template<> Json jsonFromBookmarkTarget<OrbitTarget>(OrbitTarget const& target) {
+ if (auto uuid = target.maybe<Uuid>())
+ return uuid->hex();
+ else
+ return target.get<CelestialCoordinate>().toJson();
+};
+template<> OrbitTarget jsonToBookmarkTarget<OrbitTarget>(Json const& json) {
+ if (json.type() == Json::Type::String)
+ return Uuid(json.toString());
+ else
+ return CelestialCoordinate(json);
+};
+
+template<> Json jsonFromBookmarkTarget<TeleportTarget>(TeleportTarget const& target) {
+ return JsonArray{printWorldId(target.first), spawnTargetToJson(target.second)};
+}
+template<> TeleportTarget jsonToBookmarkTarget<TeleportTarget>(Json const& target) {
+ return {parseWorldId(target.get(0).toString()), spawnTargetFromJson(target.get(1))};
+}
+
+template <typename T>
+Bookmark<T> Bookmark<T>::fromJson(Json const& json) {
+ Bookmark<T> bookmark;
+ bookmark.target = jsonToBookmarkTarget<T>(json.get("target"));
+ bookmark.targetName = json.getString("targetName");
+ bookmark.bookmarkName = json.getString("bookmarkName");
+ bookmark.icon = json.getString("icon");
+ return bookmark;
+}
+
+template <typename T>
+Json Bookmark<T>::toJson() const {
+ JsonObject result;
+ result["target"] = jsonFromBookmarkTarget<T>(target);
+ result["targetName"] = targetName;
+ result["bookmarkName"] = bookmarkName;
+ result["icon"] = icon;
+ return result;
+}
+
+PlayerUniverseMap::PlayerUniverseMap(Json const& json) {
+ if (auto maps = json.optObject()) {
+ for (auto p : *maps)
+ m_universeMaps.set(Uuid(p.first), UniverseMap::fromJson(p.second));
+ }
+}
+
+Json PlayerUniverseMap::toJson() const {
+ JsonObject json;
+ for (auto p : m_universeMaps)
+ json.set(p.first.hex(), p.second.toJson());
+ return json;
+}
+
+List<pair<Vec3I, OrbitBookmark>> PlayerUniverseMap::orbitBookmarks() const {
+ if (m_serverUuid.isNothing())
+ return {};
+
+ List<pair<Vec3I, OrbitBookmark>> bookmarks;
+ for (auto p : universeMap().systems) {
+ bookmarks.appendAll(p.second.bookmarks.values().transformed([&p](OrbitBookmark const& b) {
+ return pair<Vec3I, OrbitBookmark>(p.first, b);
+ }));
+ }
+ return bookmarks;
+}
+
+void PlayerUniverseMap::addOrbitBookmark(CelestialCoordinate const& system, OrbitBookmark const& bookmark) {
+ if (system.isNull())
+ throw StarException("Cannot add orbit bookmark to null system");
+
+ m_universeMaps[*m_serverUuid].systems[system.location()].bookmarks.add(move(bookmark));
+}
+
+void PlayerUniverseMap::removeOrbitBookmark(CelestialCoordinate const& system, OrbitBookmark const& bookmark) {
+ if (system.isNull())
+ throw StarException("Cannot remove orbit bookmark from null system");
+
+ m_universeMaps[*m_serverUuid].systems[system.location()].bookmarks.remove(bookmark);
+}
+
+List<TeleportBookmark> PlayerUniverseMap::teleportBookmarks() const {
+ return universeMap().teleportBookmarks.values();
+}
+
+void PlayerUniverseMap::addTeleportBookmark(TeleportBookmark bookmark) {
+ m_universeMaps[*m_serverUuid].teleportBookmarks.add(move(bookmark));
+}
+
+void PlayerUniverseMap::removeTeleportBookmark(TeleportBookmark const& bookmark) {
+ m_universeMaps[*m_serverUuid].teleportBookmarks.remove(bookmark);
+}
+
+void PlayerUniverseMap::invalidateWarpAction(WarpAction const& warpAction) {
+ if (auto warpToWorld = warpAction.maybe<WarpToWorld>())
+ removeTeleportBookmark({ {warpToWorld->world, warpToWorld->target}, "", "", ""});
+}
+
+Maybe<OrbitBookmark> PlayerUniverseMap::worldBookmark(CelestialCoordinate const& world) const {
+ for (auto bookmark : universeMap().systems.get(world.location()).bookmarks) {
+ if (bookmark.target == world)
+ return bookmark;
+ }
+ return {};
+}
+
+List<OrbitBookmark> PlayerUniverseMap::systemBookmarks(CelestialCoordinate const& system) const {
+ return universeMap().systems.get(system.location()).bookmarks.values();
+}
+
+List<OrbitBookmark> PlayerUniverseMap::planetBookmarks(CelestialCoordinate const& planet) const {
+ return universeMap().systems.get(planet.location()).bookmarks.values().filtered([planet] (OrbitBookmark const& bookmark) {
+ if (auto coordinate = bookmark.target.maybe<CelestialCoordinate>())
+ return coordinate->planet().orbitNumber() == planet.planet().orbitNumber();
+ return false;
+ });
+}
+
+bool PlayerUniverseMap::isMapped(CelestialCoordinate const& coordinate) {
+ if (coordinate.isNull())
+ return false;
+
+ auto& universeMap = m_universeMaps[*m_serverUuid];
+ if (!universeMap.systems.contains(coordinate.location()))
+ return false;
+
+ if (coordinate.isSystem())
+ return true;
+
+ return universeMap.systems[coordinate.location()].mappedPlanets.contains(coordinate.planet());
+}
+
+HashMap<Uuid, PlayerUniverseMap::MappedObject> PlayerUniverseMap::mappedObjects(CelestialCoordinate const& system) {
+ auto& universeMap = m_universeMaps[*m_serverUuid];
+ if (!universeMap.systems.contains(system.location()))
+ return {};
+
+ return universeMap.systems[system.location()].mappedObjects;
+}
+
+void PlayerUniverseMap::addMappedCoordinate(CelestialCoordinate const& coordinate) {
+ if (coordinate.isNull())
+ return;
+
+ auto& universeMap = m_universeMaps[*m_serverUuid];
+ if (!universeMap.systems.contains(coordinate.location()))
+ universeMap.systems.set(coordinate.location(), SystemMap());
+
+ if (coordinate.isSystem())
+ return;
+
+ universeMap.systems[coordinate.location()].mappedPlanets.add(coordinate.planet());
+}
+
+void PlayerUniverseMap::addMappedObject(CelestialCoordinate const& system, Uuid const& uuid, String const& typeName, Maybe<CelestialOrbit> const& orbit, JsonObject parameters) {
+ auto& universeMap = m_universeMaps[*m_serverUuid];
+ if (!universeMap.systems.contains(system.location()))
+ universeMap.systems.set(system.location(), SystemMap());
+
+ MappedObject object {
+ typeName,
+ orbit,
+ parameters
+ };
+ universeMap.systems[system.location()].mappedObjects.set(uuid, object);
+}
+
+void PlayerUniverseMap::removeMappedObject(CelestialCoordinate const& system, Uuid const& uuid) {
+ auto& universeMap = m_universeMaps[*m_serverUuid];
+ if (!universeMap.systems.contains(system.location()))
+ return;
+
+ universeMap.systems[system.location()].mappedObjects.remove(uuid);
+}
+
+void PlayerUniverseMap::filterMappedObjects(CelestialCoordinate const& system, List<Uuid> const& allowed) {
+ auto& universeMap = m_universeMaps[*m_serverUuid];
+ if (!universeMap.systems.contains(system.location()))
+ return;
+
+ auto& objects = universeMap.systems[system.location()].mappedObjects;
+ for (auto uuid : objects.keys()) {
+ if (!allowed.contains(uuid))
+ objects.remove(uuid);
+ }
+}
+
+void PlayerUniverseMap::setServerUuid(Maybe<Uuid> serverUuid) {
+ m_serverUuid = move(serverUuid);
+ if (m_serverUuid && !m_universeMaps.contains(*m_serverUuid))
+ m_universeMaps.set(*m_serverUuid, UniverseMap());
+}
+
+PlayerUniverseMap::SystemMap PlayerUniverseMap::SystemMap::fromJson(Json const& json) {
+ SystemMap map;
+
+ for (auto m : json.getArray("mappedPlanets"))
+ map.mappedPlanets.add(CelestialCoordinate(m));
+
+ for (auto o : json.getObject("mappedObjects")) {
+ MappedObject object;
+ object.typeName = o.second.getString("typeName");
+ object.orbit = jsonToMaybe<CelestialOrbit>(o.second.get("orbit"), [](Json const& o ) {
+ return CelestialOrbit::fromJson(o);
+ });
+ object.parameters = o.second.getObject("parameters", {});
+ map.mappedObjects.set(Uuid(o.first), object);
+ }
+
+ for (auto b : json.getArray("bookmarks"))
+ map.bookmarks.add(OrbitBookmark::fromJson(b));
+
+ return map;
+}
+
+Json PlayerUniverseMap::SystemMap::toJson() const {
+ JsonObject json;
+
+ JsonArray planets;
+ for (auto m : mappedPlanets)
+ planets.append(m.toJson());
+ json.set("mappedPlanets", planets);
+
+ JsonObject objects;
+ for (auto o : mappedObjects) {
+ JsonObject object;
+ objects.set(o.first.hex(), JsonObject{
+ {"typeName", o.second.typeName},
+ {"orbit", jsonFromMaybe<CelestialOrbit>(
+ o.second.orbit, [](CelestialOrbit const& orbit){ return orbit.toJson(); })},
+ {"parameters", o.second.parameters}
+ });
+ }
+ json.set("mappedObjects", objects);
+
+ json.set("bookmarks", bookmarks.values().transformed([](OrbitBookmark const& b) {
+ return b.toJson();
+ }));
+
+ return json;
+}
+
+PlayerUniverseMap::UniverseMap PlayerUniverseMap::UniverseMap::fromJson(Json const& json) {
+ UniverseMap map;
+
+ for (auto s : json.getArray("systems")) {
+ Vec3I location = jsonToVec3I(s.get(0));
+ map.systems.set(location, SystemMap::fromJson(s.get(1)));
+ }
+
+ for (auto bookmark : json.getArray("teleportBookmarks").transformed(&TeleportBookmark::fromJson))
+ map.teleportBookmarks.add(bookmark);
+
+ return map;
+}
+
+Json PlayerUniverseMap::UniverseMap::toJson() const {
+ JsonObject json;
+
+ JsonArray s;
+ for (auto p : systems) {
+ s.append(JsonArray{jsonFromVec3I(p.first), p.second.toJson()});
+ }
+ json.set("systems", s);
+
+ JsonArray bookmarks = teleportBookmarks.values().transformed([](TeleportBookmark const& b) {
+ return b.toJson();
+ });
+ json.set("teleportBookmarks", bookmarks);
+
+ return json;
+}
+
+PlayerUniverseMap::UniverseMap const& PlayerUniverseMap::universeMap() const {
+ if (m_serverUuid.isNothing())
+ throw StarException("Cannot get universe map of null server uuid");
+
+ return m_universeMaps.get(*m_serverUuid);
+}
+
+}