From 38f265c0838050f4ff42ff539bb00475ac5d4872 Mon Sep 17 00:00:00 2001 From: frosch Date: Sun, 16 Sep 2012 16:31:53 +0000 Subject: [PATCH] (svn r24528) -Fix: [NewGRF] RandomAction 84 should interpret register 100 as signed. --- src/newgrf_engine.cpp | 12 ++++++++---- src/vehicle_base.h | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 219f2ae920..657adce3ee 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -349,12 +349,19 @@ static inline const Vehicle *GRV(const ResolverObject *object) case VSG_SCOPE_PARENT: return object->u.vehicle.parent; case VSG_SCOPE_RELATIVE: { if (object->u.vehicle.self == NULL) return NULL; + + int32 count = GB(object->count, 0, 4); + if (count == 0) count = GetRegister(0x100); + const Vehicle *v = NULL; switch (GB(object->count, 6, 2)) { default: NOT_REACHED(); case 0x00: // count back (away from the engine), starting at this vehicle + v = object->u.vehicle.self; + break; case 0x01: // count forward (toward the engine), starting at this vehicle v = object->u.vehicle.self; + count = -count; break; case 0x02: // count back, starting at the engine v = object->u.vehicle.parent; @@ -372,10 +379,7 @@ static inline const Vehicle *GRV(const ResolverObject *object) break; } } - uint32 count = GB(object->count, 0, 4); - if (count == 0) count = GetRegister(0x100); - while (v != NULL && count-- != 0) v = (GB(object->count, 6, 2) == 0x01) ? v->Previous() : v->Next(); - return v; + return v->Move(count); } } } diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 6c9ba195e8..ab06695e2b 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -533,6 +533,22 @@ public: return v; } + /** + * Get the vehicle at offset \a n of this vehicle chain. + * @param n Offset from the current vehicle. + * @return The new vehicle or NULL if the offset is out-of-bounds. + */ + inline const Vehicle *Move(int n) const + { + const Vehicle *v = this; + if (n < 0) { + for (int i = 0; i != n && v != NULL; i--) v = v->Previous(); + } else { + for (int i = 0; i != n && v != NULL; i++) v = v->Next(); + } + return v; + } + /** * Get the first order of the vehicles order list. * @return first order of order list.