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

summaryrefslogtreecommitdiff
path: root/source/game/StarCelestialCoordinate.cpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
commit6352e8e3196f78388b6c771073f9e03eaa612673 (patch)
treee23772f79a7fbc41bc9108951e9e136857484bf4 /source/game/StarCelestialCoordinate.cpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/game/StarCelestialCoordinate.cpp')
-rw-r--r--source/game/StarCelestialCoordinate.cpp184
1 files changed, 184 insertions, 0 deletions
diff --git a/source/game/StarCelestialCoordinate.cpp b/source/game/StarCelestialCoordinate.cpp
new file mode 100644
index 0000000..3652718
--- /dev/null
+++ b/source/game/StarCelestialCoordinate.cpp
@@ -0,0 +1,184 @@
+#include "StarCelestialCoordinate.hpp"
+#include "StarCelestialTypes.hpp"
+#include "StarJsonExtra.hpp"
+#include "StarLexicalCast.hpp"
+#include "StarStaticRandom.hpp"
+#include "StarDataStreamExtra.hpp"
+
+namespace Star {
+
+CelestialCoordinate::CelestialCoordinate() : m_planetaryOrbitNumber(0), m_satelliteOrbitNumber(0) {}
+
+CelestialCoordinate::CelestialCoordinate(Vec3I location, int planetaryOrbitNumber, int satelliteOrbitNumber)
+ : m_location(move(location)),
+ m_planetaryOrbitNumber(planetaryOrbitNumber),
+ m_satelliteOrbitNumber(satelliteOrbitNumber) {}
+
+CelestialCoordinate::CelestialCoordinate(Json const& variant) : CelestialCoordinate() {
+ if (variant.isType(Json::Type::String)) {
+ String id = variant.toString();
+ if (!id.empty() && !id.equalsIgnoreCase("null")) {
+ try {
+ auto plist = id.splitAny(" _:");
+
+ m_location[0] = lexicalCast<int>(plist.at(0));
+ m_location[1] = lexicalCast<int>(plist.at(1));
+ m_location[2] = lexicalCast<int>(plist.at(2));
+
+ if (plist.size() > 3)
+ m_planetaryOrbitNumber = lexicalCast<int>(plist.at(3));
+ if (plist.size() > 4)
+ m_satelliteOrbitNumber = lexicalCast<int>(plist.at(4));
+
+ if (m_planetaryOrbitNumber <= 0)
+ throw CelestialException(strf("Planetary body number out of range in '%s'", id));
+ if (m_satelliteOrbitNumber < 0)
+ throw CelestialException(strf("Satellite body number out of range in '%s'", id));
+ } catch (StarException const& e) {
+ throw CelestialException(strf("Error parsing CelestialCoordinate from '%s'", id), e);
+ }
+ }
+ } else if (variant.isType(Json::Type::Object)) {
+ m_location = jsonToVec3I(variant.get("location"));
+ m_planetaryOrbitNumber = variant.getInt("planet", 0);
+ m_satelliteOrbitNumber = variant.getInt("satellite", 0);
+ } else if (!variant.isNull()) {
+ throw CelestialException(
+ strf("Improper variant type %s trying to convert to SystemCoordinate", variant.typeName()));
+ }
+}
+
+bool CelestialCoordinate::isNull() const {
+ return m_location == Vec3I() && m_planetaryOrbitNumber == 0 && m_satelliteOrbitNumber == 0;
+}
+
+bool CelestialCoordinate::isSystem() const {
+ return !isNull() && m_planetaryOrbitNumber == 0;
+}
+
+bool CelestialCoordinate::isPlanetaryBody() const {
+ return !isNull() && m_planetaryOrbitNumber != 0 && m_satelliteOrbitNumber == 0;
+}
+
+bool CelestialCoordinate::isSatelliteBody() const {
+ return !isNull() && m_planetaryOrbitNumber != 0 && m_satelliteOrbitNumber != 0;
+}
+
+Vec3I CelestialCoordinate::location() const {
+ return m_location;
+}
+
+CelestialCoordinate CelestialCoordinate::system() const {
+ if (isNull())
+ throw CelestialException("CelestialCoordinate::system() called on null coordinate");
+ return CelestialCoordinate(m_location);
+}
+
+CelestialCoordinate CelestialCoordinate::planet() const {
+ if (isPlanetaryBody())
+ return *this;
+ if (isSatelliteBody())
+ return CelestialCoordinate(m_location, m_planetaryOrbitNumber);
+ throw CelestialException("CelestialCoordinate::planet() called on null or system coordinate type");
+}
+
+int CelestialCoordinate::orbitNumber() const {
+ if (isSatelliteBody())
+ return m_satelliteOrbitNumber;
+ if (isPlanetaryBody())
+ return m_planetaryOrbitNumber;
+ if (isSystem())
+ return 0;
+ throw CelestialException("CelestialCoordinate::orbitNumber() called on null coordinate");
+}
+
+CelestialCoordinate CelestialCoordinate::parent() const {
+ if (isSatelliteBody())
+ return CelestialCoordinate(m_location, m_planetaryOrbitNumber);
+ if (isPlanetaryBody())
+ return CelestialCoordinate(m_location);
+ throw CelestialException("CelestialCoordinate::parent() called on null or system coordinate");
+}
+
+CelestialCoordinate CelestialCoordinate::child(int orbitNumber) const {
+ if (isSystem())
+ return CelestialCoordinate(m_location, orbitNumber);
+ if (isPlanetaryBody())
+ return CelestialCoordinate(m_location, m_planetaryOrbitNumber, orbitNumber);
+ throw CelestialException("CelestialCoordinate::child called on null or satellite coordinate");
+}
+
+Json CelestialCoordinate::toJson() const {
+ if (isNull()) {
+ return Json();
+ } else {
+ return JsonObject{{"location", jsonFromVec3I(m_location)},
+ {"planet", m_planetaryOrbitNumber},
+ {"satellite", m_satelliteOrbitNumber}};
+ }
+}
+
+String CelestialCoordinate::id() const {
+ return toString(*this);
+}
+
+double CelestialCoordinate::distance(CelestialCoordinate const& rhs) const {
+ return Vec2D(m_location[0] - rhs.m_location[0], m_location[1] - rhs.m_location[1]).magnitude();
+}
+
+String CelestialCoordinate::filename() const {
+ return id().replace(":", "_");
+}
+
+CelestialCoordinate::operator bool() const {
+ return !isNull();
+}
+
+bool CelestialCoordinate::operator<(CelestialCoordinate const& rhs) const {
+ return tie(m_location, m_planetaryOrbitNumber, m_satelliteOrbitNumber)
+ < tie(rhs.m_location, rhs.m_planetaryOrbitNumber, rhs.m_satelliteOrbitNumber);
+}
+
+bool CelestialCoordinate::operator==(CelestialCoordinate const& rhs) const {
+ return tie(m_location, m_planetaryOrbitNumber, m_satelliteOrbitNumber)
+ == tie(rhs.m_location, rhs.m_planetaryOrbitNumber, rhs.m_satelliteOrbitNumber);
+}
+
+bool CelestialCoordinate::operator!=(CelestialCoordinate const& rhs) const {
+ return tie(m_location, m_planetaryOrbitNumber, m_satelliteOrbitNumber)
+ != tie(rhs.m_location, rhs.m_planetaryOrbitNumber, rhs.m_satelliteOrbitNumber);
+}
+
+std::ostream& operator<<(std::ostream& os, CelestialCoordinate const& coord) {
+ if (coord.isNull()) {
+ os << "null";
+ } else {
+ format(os, "%s:%s:%s", coord.m_location[0], coord.m_location[1], coord.m_location[2]);
+
+ if (coord.m_planetaryOrbitNumber) {
+ format(os, ":%s", coord.m_planetaryOrbitNumber);
+ if (coord.m_satelliteOrbitNumber)
+ format(os, ":%s", coord.m_satelliteOrbitNumber);
+ }
+ }
+
+ return os;
+}
+
+DataStream& operator>>(DataStream& ds, CelestialCoordinate& coordinate) {
+ ds.read(coordinate.m_location);
+ ds.read(coordinate.m_planetaryOrbitNumber);
+ ds.read(coordinate.m_satelliteOrbitNumber);
+
+ return ds;
+}
+
+DataStream& operator<<(DataStream& ds, CelestialCoordinate const& coordinate) {
+ ds.write(coordinate.m_location);
+ ds.write(coordinate.m_planetaryOrbitNumber);
+ ds.write(coordinate.m_satelliteOrbitNumber);
+
+ return ds;
+}
+
+}