From 0e2c4c36d6207c25f031aa52d086d8502d90e720 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sat, 13 Jun 2009 22:46:45 +0100 Subject: [PATCH] Make waggons follow the train --- maps/points.xml | 2 +- src/Train.cpp | 48 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/maps/points.xml b/maps/points.xml index c3633eb..6bdf5f9 100644 --- a/maps/points.xml +++ b/maps/points.xml @@ -2,7 +2,7 @@ No Name - + maps/points.bin diff --git a/src/Train.cpp b/src/Train.cpp index 99c251a..631121f 100644 --- a/src/Train.cpp +++ b/src/Train.cpp @@ -23,6 +23,7 @@ #include #include +#include #include @@ -44,8 +45,8 @@ public: private: // The different parts of the train are on different track segments struct Part { - explicit Part(IRollingStockPtr aVehicle) - : vehicle(aVehicle), segmentDelta(0.0) + explicit Part(IRollingStockPtr aVehicle, bool amDriving = false) + : vehicle(aVehicle), segmentDelta(0.0), isDriving(amDriving) {} IRollingStockPtr vehicle; @@ -58,7 +59,13 @@ private: track::TravelToken travelToken; // Direction train part is travelling along the track - Vector direction; + Vector direction; + + // Turns to take if this is not the engine + queue followQueue; + + // True if this is driving the train + bool isDriving; }; list myParts; @@ -68,6 +75,7 @@ private: void addPart(IRollingStockPtr aVehicle); Vector partPosition(const Part& aPart) const; void updateSmokePosition(int aDelta); + void makeFollow(track::Choice aChoice); IMapPtr myMap; ISmokeTrailPtr mySmokeTrail; @@ -86,7 +94,7 @@ const double Train::SEPARATION(0.1); Train::Train(IMapPtr aMap) : myMap(aMap), myVelocityVector(makeVector(0.0f, 0.0f, 0.0f)) { - myParts.push_front(Part(makeEngine())); + myParts.push_front(Part(makeEngine(), true)); enterSegment(engine(), aMap->startLocation()); @@ -110,6 +118,14 @@ void Train::addPart(IRollingStockPtr aVehicle) myParts.push_back(part); } +// Make everything that's not the engine follow its choice +void Train::makeFollow(track::Choice aChoice) +{ + for (list::iterator it = ++(myParts.begin()); + it != myParts.end(); ++it) + (*it).followQueue.push(aChoice); +} + Train::Part& Train::engine() { assert(myParts.size() > 0); @@ -205,8 +221,8 @@ void Train::enterSegment(Part& aPart, const track::Connection& aConnection) Point pos; tie(pos, aPart.direction) = aConnection; - debug() << "Train part entered segment at " << pos - << " moving " << aPart.direction; + //debug() << "Train part entered segment at " << pos + // << " moving " << aPart.direction; if (!myMap->isValidTrack(pos)) throw runtime_error("Train fell off end of track!"); @@ -216,11 +232,21 @@ void Train::enterSegment(Part& aPart, const track::Connection& aConnection) aPart.travelToken = aPart.segment->getTravelToken(pos, aPart.direction); if (aPart.travelToken.choices.size() > 1) { - // Need to make a choice: see what the controller has pre-set - track::Choice choice = engine().vehicle->controller()->consumeChoice(); - - debug() << "Choice: " << choice; - + track::Choice choice; + + if (aPart.isDriving) { + // Need to make a choice: see what the controller has pre-set + choice = engine().vehicle->controller()->consumeChoice(); + makeFollow(choice); + } + else { + // We're following another part so look in the follow queue + assert(!aPart.followQueue.empty()); + + choice = aPart.followQueue.front(); + aPart.followQueue.pop(); + } + aPart.travelToken.activeChoice = choice; } } -- 2.39.2