summaryrefslogtreecommitdiff
path: root/game
diff options
context:
space:
mode:
Diffstat (limited to 'game')
-rw-r--r--game/activities/go.h10
-rw-r--r--game/activities/idle.h10
-rw-r--r--game/activity.h38
-rw-r--r--game/objective.cpp8
-rw-r--r--game/objective.h23
-rw-r--r--game/objectives/freeroam.h18
-rw-r--r--game/orders.cpp16
-rw-r--r--game/orders.h16
-rw-r--r--game/vehicles/train.cpp19
-rw-r--r--game/vehicles/train.h7
-rw-r--r--game/vehicles/vehicle.cpp6
-rw-r--r--game/vehicles/vehicle.h7
12 files changed, 176 insertions, 2 deletions
diff --git a/game/activities/go.h b/game/activities/go.h
new file mode 100644
index 0000000..8727539
--- /dev/null
+++ b/game/activities/go.h
@@ -0,0 +1,10 @@
+#ifndef GO_H
+#define GO_H
+
+#include "../activity.h"
+
+class Go : public Activity::Of<Go> {
+public:
+};
+
+#endif
diff --git a/game/activities/idle.h b/game/activities/idle.h
new file mode 100644
index 0000000..04bc6e5
--- /dev/null
+++ b/game/activities/idle.h
@@ -0,0 +1,10 @@
+#ifndef IDLE_H
+#define IDLE_H
+
+#include "../activity.h"
+
+class Idle : public Activity::Of<Idle> {
+public:
+};
+
+#endif
diff --git a/game/activity.h b/game/activity.h
new file mode 100644
index 0000000..33c36fd
--- /dev/null
+++ b/game/activity.h
@@ -0,0 +1,38 @@
+#ifndef ACTIVITY_H
+#define ACTIVITY_H
+
+#include <game/worldobject.h>
+#include <memory>
+#include <special_members.hpp>
+
+class Vehicle;
+
+class Activity {
+public:
+ Activity() = default;
+ DEFAULT_MOVE_COPY(Activity);
+ virtual ~Activity() = default;
+
+ virtual void apply(Vehicle *, TickDuration) const = 0;
+
+ template<typename T> class Of;
+};
+using ActivityPtr = std::unique_ptr<Activity>;
+
+template<typename T> concept ActivityConcept = std::is_base_of_v<Activity, T>;
+template<ActivityConcept AC> class Can {
+public:
+ virtual void doActivity(const AC *, TickDuration) = 0;
+};
+
+template<typename T> class Activity::Of : public Activity {
+ void
+ apply(Vehicle * v, TickDuration dur) const override
+ {
+ if (auto tv = dynamic_cast<Can<T> *>(v)) {
+ tv->doActivity(static_cast<const T *>(this), dur);
+ }
+ }
+};
+
+#endif
diff --git a/game/objective.cpp b/game/objective.cpp
new file mode 100644
index 0000000..70f0ae9
--- /dev/null
+++ b/game/objective.cpp
@@ -0,0 +1,8 @@
+#include "objective.h"
+#include "orders.h"
+
+Objective *
+Objective::complete() const
+{
+ return orders->next();
+}
diff --git a/game/objective.h b/game/objective.h
new file mode 100644
index 0000000..e4fd6d4
--- /dev/null
+++ b/game/objective.h
@@ -0,0 +1,23 @@
+#ifndef OBJECTIVE_H
+#define OBJECTIVE_H
+
+#include "activity.h"
+#include <memory>
+#include <special_members.hpp>
+
+class Orders;
+
+class Objective {
+public:
+ explicit Objective(Orders * os) : orders(os) { }
+ DEFAULT_MOVE_COPY(Objective);
+ virtual ~Objective() = default;
+
+ [[nodiscard]] virtual Objective * complete() const;
+ [[nodiscard]] virtual ActivityPtr createActivity() const = 0;
+
+ Orders * orders;
+};
+using ObjectivePtr = std::unique_ptr<Objective>;
+
+#endif
diff --git a/game/objectives/freeroam.h b/game/objectives/freeroam.h
new file mode 100644
index 0000000..c97d9b4
--- /dev/null
+++ b/game/objectives/freeroam.h
@@ -0,0 +1,18 @@
+#ifndef FREEROAM_H
+#define FREEROAM_H
+
+#include "game/activities/go.h"
+#include "game/objective.h"
+
+class FreeRoam : public Objective {
+public:
+ using Objective::Objective;
+
+ [[nodiscard]] ActivityPtr
+ createActivity() const override
+ {
+ return std::make_unique<Go>();
+ }
+};
+
+#endif
diff --git a/game/orders.cpp b/game/orders.cpp
new file mode 100644
index 0000000..18fc889
--- /dev/null
+++ b/game/orders.cpp
@@ -0,0 +1,16 @@
+#include "orders.h"
+#include <algorithm>
+#include <vector>
+
+Objective *
+Orders::current() const
+{
+ return objects.front().get();
+}
+
+Objective *
+Orders::next()
+{
+ std::rotate(objects.begin(), objects.begin() + 1, objects.end());
+ return current();
+}
diff --git a/game/orders.h b/game/orders.h
new file mode 100644
index 0000000..cd72767
--- /dev/null
+++ b/game/orders.h
@@ -0,0 +1,16 @@
+#ifndef ORDERS_H
+#define ORDERS_H
+
+#include <collection.hpp>
+#include <memory>
+
+class Objective;
+
+class Orders : public Collection<Objective> {
+public:
+ [[nodiscard]] Objective * current() const;
+ Objective * next();
+};
+using OrdersPtr = std::shared_ptr<Orders>;
+
+#endif
diff --git a/game/vehicles/train.cpp b/game/vehicles/train.cpp
index e211f16..f7b5515 100644
--- a/game/vehicles/train.cpp
+++ b/game/vehicles/train.cpp
@@ -1,6 +1,7 @@
#include "train.h"
#include "game/vehicles/linkHistory.h"
#include "game/vehicles/railVehicle.h"
+#include "game/vehicles/railVehicleClass.h"
#include "gfx/renderable.h"
#include "location.hpp"
#include <algorithm>
@@ -53,8 +54,26 @@ Train::getBogiePosition(float linkDist, float dist) const
void
Train::tick(TickDuration dur)
{
+ currentActivity->apply(this, dur);
move(dur);
float trailBy {0.F};
apply(&RailVehicle::move, this, std::ref(trailBy));
}
+
+void
+Train::doActivity(const Go *, TickDuration dur)
+{
+ const auto maxSpeed = objects.front()->rvClass->maxSpeed;
+ if (speed != maxSpeed) {
+ speed += ((maxSpeed - speed) * dur.count());
+ }
+}
+
+void
+Train::doActivity(const Idle *, TickDuration dur)
+{
+ if (speed != 0.F) {
+ speed -= std::min(speed, 30.F * dur.count());
+ }
+}
diff --git a/game/vehicles/train.h b/game/vehicles/train.h
index 34a9d28..a7d4b1b 100644
--- a/game/vehicles/train.h
+++ b/game/vehicles/train.h
@@ -1,6 +1,9 @@
#ifndef TRAIN_H
#define TRAIN_H
+#include "game/activities/go.h" // IWYU pragma: keep
+#include "game/activities/idle.h" // IWYU pragma: keep
+#include "game/activity.h"
#include "game/network/link.h"
#include "game/worldobject.h"
#include "railVehicle.h"
@@ -12,7 +15,7 @@
class Shader;
-class Train : public Vehicle, public Collection<RailVehicle, false> {
+class Train : public Vehicle, public Collection<RailVehicle, false>, public Can<Go>, public Can<Idle> {
public:
explicit Train(const LinkPtr & link, float linkDist = 0) : Vehicle {link, linkDist} { }
@@ -25,6 +28,8 @@ public:
void render(const Shader & shader) const override;
void tick(TickDuration elapsed) override;
+ void doActivity(const Go *, TickDuration) override;
+ void doActivity(const Idle *, TickDuration) override;
void move(TickDuration dur);
[[nodiscard]] Location getBogiePosition(float linkDist, float dist) const;
diff --git a/game/vehicles/vehicle.cpp b/game/vehicles/vehicle.cpp
index d98533e..d3cae1d 100644
--- a/game/vehicles/vehicle.cpp
+++ b/game/vehicles/vehicle.cpp
@@ -1,8 +1,14 @@
#include "vehicle.h"
+#include "game/activity.h"
#include "game/network/link.h"
+#include "game/objective.h"
+#include "game/objectives/freeroam.h"
+#include "game/orders.h"
#include "game/vehicles/linkHistory.h"
Vehicle::Vehicle(const LinkPtr & l, float ld) : linkDist {ld}
{
linkHist.add(l, 0);
+ orders.create<FreeRoam>(&orders);
+ currentActivity = orders.current()->createActivity();
}
diff --git a/game/vehicles/vehicle.h b/game/vehicles/vehicle.h
index 659821f..c4c8beb 100644
--- a/game/vehicles/vehicle.h
+++ b/game/vehicles/vehicle.h
@@ -2,7 +2,9 @@
#define VEHICLE_H
#include "linkHistory.h"
+#include <game/activity.h>
#include <game/network/link.h>
+#include <game/orders.h>
#include <game/worldobject.h>
#include <gfx/renderable.h>
#include <memory>
@@ -13,9 +15,12 @@ class Vehicle : public WorldObject, public Renderable {
public:
explicit Vehicle(const LinkPtr & link, float linkDist = 0);
float linkDist; // distance along current link
- float speed {50}; // speed in m/s (~75 km/h)
+ float speed {}; // speed in m/s (~75 km/h)
[[nodiscard]] virtual const Location & getLocation() const = 0;
+ Orders orders;
+
+ ActivityPtr currentActivity;
protected:
LinkHistory linkHist;