diff options
-rw-r--r-- | application/main.cpp | 18 | ||||
-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 |
13 files changed, 193 insertions, 3 deletions
diff --git a/application/main.cpp b/application/main.cpp index c9caf74..1d961a0 100644 --- a/application/main.cpp +++ b/application/main.cpp @@ -2,6 +2,9 @@ #include <array> #include <chrono> #include <collection.hpp> +#include <game/activities/go.h> +#include <game/activities/idle.h> +#include <game/activity.h> #include <game/network/link.h> #include <game/network/rail.h> #include <game/terrain.h> @@ -49,6 +52,7 @@ public: NO_COPY(SDL_Application); NO_MOVE(SDL_Application); + std::shared_ptr<Train> train; bool handleInput(SDL_Event & e) override { @@ -56,6 +60,18 @@ public: case SDL_QUIT: isRunning = false; return true; + case SDL_KEYUP: + switch (e.key.keysym.scancode) { + case SDL_SCANCODE_G: + train->currentActivity = std::make_unique<Go>(); + break; + case SDL_SCANCODE_I: + train->currentActivity = std::make_unique<Idle>(); + break; + default: + return false; + } + return true; } return false; } @@ -81,7 +97,7 @@ public: rl->addLinksBetween(e1, j); auto e2 = rl->addLinksBetween(e, {-925, 10, -1075})->ends[0].first->pos; rl->addLinksBetween(e2, j); - const auto & train = world.create<Train>(l3); + train = world.create<Train>(l3); auto b47 = std::make_shared<RailVehicleClass>("brush47"); for (int n = 0; n < 6; n++) { train->create<RailVehicle>(b47); 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; |