aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author ClarkeCode <33846391+ClarkeCode@users.noreply.github.com>2023-04-14 22:16:23 +0200
committer GitHub <noreply@github.com>2023-04-14 22:16:23 +0200
commitf168c91ff266beda8066014257a30d93704882ee (patch)
tree2c49198c3cbbbb575dc14795132a20c7b9267a2c
parent436b038c1806e326ff6458f1692e9009d3a54346 (diff)
parent48558fdfec509942515b0e2d92e3f1357b201400 (diff)
Merge pull request #73 from OpenVic2Project/in-game-date
Added in-game date
-rw-r--r--.gitignore3
-rw-r--r--extension/src/Simulation.cpp64
-rw-r--r--extension/src/Simulation.hpp30
-rw-r--r--extension/src/openvic2/Date.cpp108
-rw-r--r--extension/src/openvic2/Date.hpp83
5 files changed, 283 insertions, 5 deletions
diff --git a/.gitignore b/.gitignore
index 125f143..596bc88 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,6 +39,9 @@
!.vscode/launch.json
!.vscode/tasks.json
+# Visual Studio
+.vs/
+
# Godot 4+ specific ignores
.godot/
game/bin/openvic2/*
diff --git a/extension/src/Simulation.cpp b/extension/src/Simulation.cpp
new file mode 100644
index 0000000..5ea99c5
--- /dev/null
+++ b/extension/src/Simulation.cpp
@@ -0,0 +1,64 @@
+#include "Simulation.hpp"
+
+namespace OpenVic2 {
+ void Simulation::togglePauseState() {
+ this->isPaused = !isPaused;
+ }
+
+ bool Simulation::getPauseState() {
+ return this->isPaused;
+ }
+
+ void Simulation::increaseSimulationSpeed() {
+ switch (this->currentSpeed) {
+ case(Speed::Speed1):
+ this->currentSpeed = Speed::Speed2;
+ break;
+ case(Speed::Speed2):
+ this->currentSpeed = Speed::Speed3;
+ break;
+ case(Speed::Speed3):
+ this->currentSpeed = Speed::Speed4;
+ break;
+ case(Speed::Speed4):
+ this->currentSpeed = Speed::Speed5;
+ break;
+ }
+ }
+
+ void Simulation::decreaseSimulationSpeed() {
+ switch (this->currentSpeed) {
+ case(Speed::Speed2):
+ this->currentSpeed = Speed::Speed1;
+ break;
+ case(Speed::Speed3):
+ this->currentSpeed = Speed::Speed2;
+ break;
+ case(Speed::Speed4):
+ this->currentSpeed = Speed::Speed3;
+ break;
+ case(Speed::Speed5):
+ this->currentSpeed = Speed::Speed4;
+ break;
+ }
+ }
+
+ void Simulation::setSimulationSpeed(Speed speed) {
+ this->currentSpeed = speed;
+ }
+
+ int Simulation::getSimulationSpeed() {
+ return static_cast<int>(this->currentSpeed);
+ }
+
+ void Simulation::conditionallyAdvanceSimulation() {
+ if (!(this->isPaused)) {
+ std::chrono::time_point<std::chrono::high_resolution_clock> previousTime = this->lastPolledTime;
+ std::chrono::time_point<std::chrono::high_resolution_clock> currentTime = std::chrono::high_resolution_clock::now();
+ if (std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - previousTime).count() >= this->getSimulationSpeed()) {
+ this->lastPolledTime = currentTime;
+ this->inGameDate++;
+ }
+ }
+ }
+}
diff --git a/extension/src/Simulation.hpp b/extension/src/Simulation.hpp
index b84016b..58ba7c7 100644
--- a/extension/src/Simulation.hpp
+++ b/extension/src/Simulation.hpp
@@ -2,28 +2,39 @@
#include <godot_cpp/core/class_db.hpp>
#include <vector>
+#include <chrono>
+#include "openvic2/Date.hpp"
namespace OpenVic2 {
class Simulation : public godot::Object {
GDCLASS(Simulation, godot::Object)
std::vector<uint64_t> exampleProvinces;
+ enum class Speed { Speed1 = 4000, Speed2 = 3000, Speed3 = 2000, Speed4 = 1000, Speed5 = 100, Speed6 = 1 };
+
+ std::chrono::time_point<std::chrono::high_resolution_clock> lastPolledTime;
+ bool isPaused;
+ Speed currentSpeed;
+ Date inGameDate;
+
//BEGIN BOILERPLATE
inline static Simulation* _simulation = nullptr;
- protected:
+ protected:
static void _bind_methods() {
godot::ClassDB::bind_method(godot::D_METHOD("conductSimulationStep"), &Simulation::conductSimulationStep);
godot::ClassDB::bind_method(godot::D_METHOD("queryProvinceSize"), &Simulation::queryProvinceSize);
}
- public:
+ public:
inline static Simulation* get_singleton() { return _simulation; }
- inline Simulation() {
+ inline Simulation() : inGameDate(1836, 1, 1) {
ERR_FAIL_COND(_simulation != nullptr);
_simulation = this;
-
+ this->lastPolledTime = std::chrono::high_resolution_clock::now();
+ this->isPaused = false;
+ this->currentSpeed = Speed::Speed1;
exampleProvinces.resize(10, 1);
}
inline ~Simulation() {
@@ -32,6 +43,13 @@ namespace OpenVic2 {
}
//END BOILERPLATE
+ void togglePauseState();
+ bool getPauseState();
+ void increaseSimulationSpeed();
+ void decreaseSimulationSpeed();
+ void setSimulationSpeed(Speed speed);
+ int getSimulationSpeed();
+
inline void conductSimulationStep() {
for (uint64_t x = 0; x < exampleProvinces.size(); x++) {
exampleProvinces[x] += (x + 1);
@@ -44,5 +62,7 @@ namespace OpenVic2 {
}
return exampleProvinces[provinceID];
}
+
+ void conditionallyAdvanceSimulation();
};
-}
+} \ No newline at end of file
diff --git a/extension/src/openvic2/Date.cpp b/extension/src/openvic2/Date.cpp
new file mode 100644
index 0000000..3c5b8d8
--- /dev/null
+++ b/extension/src/openvic2/Date.cpp
@@ -0,0 +1,108 @@
+#include <sstream>
+#include "Date.hpp"
+
+namespace OpenVic2 {
+ bool Timespan::operator< (Timespan const& other) const { return days < other.days; }
+ bool Timespan::operator> (Timespan const& other) const { return days > other.days; }
+ bool Timespan::operator<= (Timespan const& other) const { return days <= other.days; }
+ bool Timespan::operator>= (Timespan const& other) const { return days >= other.days; }
+ bool Timespan::operator== (Timespan const& other) const { return days == other.days; }
+ bool Timespan::operator!= (Timespan const& other) const { return days != other.days; }
+
+ Timespan Timespan::operator+ (Timespan const& other) const { return Timespan(days + other.days); }
+ Timespan Timespan::operator- (Timespan const& other) const { return Timespan(days - other.days); }
+ Timespan Timespan::operator* (int64_t const& factor) const { return Timespan(days * factor); }
+ Timespan Timespan::operator/ (int64_t const& factor) const { return Timespan(days / factor); }
+
+ Timespan& Timespan::operator+= (Timespan const& other) {
+ days += other.days;
+ return *this;
+ }
+ Timespan& Timespan::operator-= (Timespan const& other) {
+ days -= other.days;
+ return *this;
+ }
+
+ Timespan fromYearZero(year_t year, month_t month, date_t day) {
+ int64_t daysElapsed = year * DAYS_IN_YEAR;
+ size_t daysSinceMonthStart = (day == 0) ? 0 : day - 1; //Underflow protection
+ for (size_t x = 0; x < month && x < MONTHS_IN_YEAR; x++) {
+ daysElapsed += DAYS_IN_MONTH[x];
+ }
+ daysElapsed += daysSinceMonthStart;
+ return Timespan(daysElapsed);
+ }
+
+ //This function is not set up to handle dates before Year 0
+ YearMonthDayBundle toGregorianDate(Timespan const& timespan) {
+ year_t year = 0;
+ month_t month = 0;
+ date_t day = 0;
+
+ if (timespan >= 0) {
+ year = timespan.days / DAYS_IN_YEAR;
+ int64_t remainingDays = timespan.days % DAYS_IN_YEAR;
+
+ for (size_t x = 0; x < MONTHS_IN_YEAR && remainingDays >= DAYS_IN_MONTH[x]; x++) {
+ remainingDays -= DAYS_IN_MONTH[x];
+ month++;
+ }
+
+ //Corrects month and day to be 1-indexed
+ month++;
+ day++;
+ }
+ return std::make_tuple(year, month, day);
+ }
+
+
+ Date::Date(Timespan const& timespan) : ts(timespan) { updateDate(ts); }
+
+ Date::Date(year_t year, month_t month, date_t day) {
+ ts = fromYearZero(year, month, day);
+ updateDate(ts);
+ }
+
+ void Date::updateDate(Timespan const& timespan) {
+ gregorianDate = toGregorianDate(timespan);
+ }
+
+ size_t Date::getDay() const { return std::get<2>(gregorianDate); }
+ size_t Date::getMonth() const { return std::get<1>(gregorianDate); }
+ size_t Date::getYear() const { return std::get<0>(gregorianDate); }
+
+ bool Date::operator< (Date const& other) const { return ts < other.ts; }
+ bool Date::operator> (Date const& other) const { return ts > other.ts; }
+ bool Date::operator<= (Date const& other) const { return ts <= other.ts; }
+ bool Date::operator>= (Date const& other) const { return ts >= other.ts; }
+ bool Date::operator== (Date const& other) const { return ts == other.ts; }
+ bool Date::operator!= (Date const& other) const { return ts != other.ts; }
+
+ Date Date::operator+ (Timespan timespan) const { return Date(ts + timespan); }
+ Timespan Date::operator- (Date const& other) const { return ts - other.ts; }
+
+ Date& Date::operator+= (Timespan const& timespan) {
+ ts += timespan;
+ updateDate(ts);
+ return *this;
+ }
+ Date& Date::operator-= (Timespan const& timespan) {
+ ts -= timespan;
+ updateDate(ts);
+ return *this;
+ }
+ Date Date::operator++ (int) {
+ Date oldCopy = *this;
+ (*this) += 1;
+ return oldCopy;
+ }
+
+ Date::operator std::string() const {
+ std::stringstream ss;
+ ss << getYear() << '.' << getMonth() << '.' << getDay();
+ return ss.str();
+ }
+ std::ostream &operator<<(std::ostream &out, Date const& date) {
+ return out << static_cast<std::string>(date);
+ }
+}
diff --git a/extension/src/openvic2/Date.hpp b/extension/src/openvic2/Date.hpp
new file mode 100644
index 0000000..841b118
--- /dev/null
+++ b/extension/src/openvic2/Date.hpp
@@ -0,0 +1,83 @@
+#pragma once
+
+#include <cstdint>
+#include <cstddef>
+#include <tuple>
+#include <string>
+#include <iostream>
+
+namespace OpenVic2 {
+ //A relative period between points in time, measured in days
+ struct Timespan {
+ int64_t days;
+
+ Timespan() : days(0) {}
+ Timespan(int64_t const& value) : days(value) {}
+
+ bool operator< (Timespan const& other) const;
+ bool operator> (Timespan const& other) const;
+ bool operator<= (Timespan const& other) const;
+ bool operator>= (Timespan const& other) const;
+ bool operator== (Timespan const& other) const;
+ bool operator!= (Timespan const& other) const;
+
+ Timespan operator+ (Timespan const& other) const;
+ Timespan operator- (Timespan const& other) const;
+ Timespan operator* (int64_t const& factor) const;
+ Timespan operator/ (int64_t const& factor) const;
+
+ Timespan& operator+= (Timespan const& other);
+ Timespan& operator-= (Timespan const& other);
+ };
+
+ static constexpr size_t MONTHS_IN_YEAR = 12;
+ static constexpr size_t DAYS_IN_YEAR = 365;
+ static constexpr size_t DAYS_IN_MONTH[MONTHS_IN_YEAR] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+ using date_t = uint8_t;
+ using month_t = uint8_t;
+ using year_t = uint16_t;
+ using YearMonthDayBundle = std::tuple<year_t, month_t, date_t>;
+
+ //Represents an in-game date
+ //Note: Current implementation does not account for leap-years, or dates before Year 0
+ struct Date {
+ private:
+ YearMonthDayBundle gregorianDate;
+ //Number of days since Jan 1st, Year 0
+ Timespan ts;
+
+ public:
+ //The Timespan is considered to be the number of days since Jan 1st, Year 0
+ Date(Timespan const& timespan);
+
+ //Year month day specification
+ Date(year_t year = 1836, month_t month = 1, date_t day = 1);
+
+ private:
+ void updateDate(Timespan const& timespan);
+
+ public:
+ size_t getDay() const;
+ size_t getMonth() const;
+ size_t getYear() const;
+
+ bool operator< (Date const& other) const;
+ bool operator> (Date const& other) const;
+ bool operator<= (Date const& other) const;
+ bool operator>= (Date const& other) const;
+ bool operator== (Date const& other) const;
+ bool operator!= (Date const& other) const;
+
+ Date operator+ (Timespan timespan) const;
+ Timespan operator- (Date const& other) const;
+
+ Date& operator+= (Timespan const& timespan);
+ Date& operator-= (Timespan const& timespan);
+ //Postfix increment
+ Date operator++ (int);
+
+ explicit operator std::string() const;
+ friend std::ostream& operator<< (std::ostream& out, Date const& date);
+ };
+}