diff options
Diffstat (limited to 'game')
-rw-r--r-- | game/activities/go.h | 10 | ||||
-rw-r--r-- | game/activities/idle.h | 10 | ||||
-rw-r--r-- | game/activity.h | 38 | ||||
-rw-r--r-- | game/objective.cpp | 8 | ||||
-rw-r--r-- | game/objective.h | 23 | ||||
-rw-r--r-- | game/objectives/freeroam.h | 18 | ||||
-rw-r--r-- | game/orders.cpp | 16 | ||||
-rw-r--r-- | game/orders.h | 16 | ||||
-rw-r--r-- | game/vehicles/train.cpp | 19 | ||||
-rw-r--r-- | game/vehicles/train.h | 7 | ||||
-rw-r--r-- | game/vehicles/vehicle.cpp | 6 | ||||
-rw-r--r-- | game/vehicles/vehicle.h | 7 |
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; |