diff options
author | truelight <truelight@openttd.org> | 2005-01-09 16:02:06 +0000 |
---|---|---|
committer | truelight <truelight@openttd.org> | 2005-01-09 16:02:06 +0000 |
commit | 32f480a4aebb85abc03dad56149c2d05bcf8a65b (patch) | |
tree | d8c14f455f5dc2cf54de21fd2c39f0f1bef4b4f4 | |
parent | 9853d4e0d428b3a6288c22804c6e34475f1bb0cb (diff) | |
download | openttd-32f480a4aebb85abc03dad56149c2d05bcf8a65b.tar.xz |
(svn r1445) -Fix: reversing a train also reverses the UP and DOWN status for the
realistic acceleration calculation
-Fix: there was a big bug in setting the UP and DOWN flags making it
easy possible for a overloaded train to go up a mountain. This is no
longer possible. They will hang at a certain height
-rw-r--r-- | macros.h | 7 | ||||
-rw-r--r-- | train_cmd.c | 55 | ||||
-rw-r--r-- | vehicle.h | 6 |
3 files changed, 50 insertions, 18 deletions
@@ -99,9 +99,10 @@ uint SafeTileAdd(uint x, int add, const char *exp, const char *file, int line); #define PACK_PPOINT(p) PACK_POINT((p).x, (p).y) -#define HASBIT(x,y) ((x) & (1 << (y))) -#define SETBIT(x,y) ((x) |= (1 << (y))) -#define CLRBIT(x,y) ((x) &= ~(1 << (y))) +#define HASBIT(x,y) ((x) & (1 << (y))) +#define SETBIT(x,y) ((x) |= (1 << (y))) +#define CLRBIT(x,y) ((x) &= ~(1 << (y))) +#define TOGGLEBIT(x,y) ((x) ^= (1 << (y))) // checking more bits. Maybe unneccessary, but easy to use #define HASBITS(x,y) ((x) & (y)) diff --git a/train_cmd.c b/train_cmd.c index a1ff5150c..e11656e2d 100644 --- a/train_cmd.c +++ b/train_cmd.c @@ -102,9 +102,9 @@ static int GetRealisticAcceleration(Vehicle *v) uint mass = rvi->weight + ((_cargoc.weights[u->cargo_type] * u->cargo_count) >> 4); if (rvi->power) emass += mass; - if (u->u.rail.flags & VRF_GOINGUP) { + if (HASBIT(u->u.rail.flags, VRF_GOINGUP)) { f += (float)mass * ( -F_GRAV * F_THETA); - } else if (u->u.rail.flags & VRF_GOINGDOWN) { + } else if (HASBIT(u->u.rail.flags, VRF_GOINGDOWN)) { f += (float)mass * ( F_GRAV * F_THETA); } @@ -914,6 +914,32 @@ static void SetLastSpeed(Vehicle *v, int spd) { } } +static void SwapTrainFlags(byte *swap_flag1, byte *swap_flag2) +{ + byte flag1, flag2; + + flag1 = *swap_flag1; + flag2 = *swap_flag2; + + /* Clear the flags */ + CLRBIT(*swap_flag1, VRF_GOINGUP); + CLRBIT(*swap_flag1, VRF_GOINGDOWN); + CLRBIT(*swap_flag2, VRF_GOINGUP); + CLRBIT(*swap_flag2, VRF_GOINGDOWN); + + /* Reverse the rail-flags (if needed) */ + if (HASBIT(flag1, VRF_GOINGUP)) { + SETBIT(*swap_flag2, VRF_GOINGDOWN); + } else if (HASBIT(flag1, VRF_GOINGDOWN)) { + SETBIT(*swap_flag2, VRF_GOINGUP); + } + if (HASBIT(flag2, VRF_GOINGUP)) { + SETBIT(*swap_flag1, VRF_GOINGDOWN); + } else if (HASBIT(flag2, VRF_GOINGDOWN)) { + SETBIT(*swap_flag1, VRF_GOINGUP); + } +} + static void ReverseTrainSwapVeh(Vehicle *v, int l, int r) { Vehicle *a, *b; @@ -944,6 +970,8 @@ static void ReverseTrainSwapVeh(Vehicle *v, int l, int r) swap_tile(&a->tile, &b->tile); swap_byte(&a->z_pos, &b->z_pos); + SwapTrainFlags(&a->u.rail.flags, &b->u.rail.flags); + /* update other vars */ UpdateVarsAfterSwap(a); UpdateVarsAfterSwap(b); @@ -1006,7 +1034,7 @@ static void ReverseTrainDirection(Vehicle *v) if (IsTrainDepotTile(v->tile)) InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); - v->u.rail.flags &= ~VRF_REVERSING; + CLRBIT(v->u.rail.flags, VRF_REVERSING); } /* p1 = vehicle */ @@ -1029,7 +1057,7 @@ int32 CmdReverseTrainDirection(int x, int y, uint32 flags, uint32 p1, uint32 p2) if (flags & DC_EXEC) { if (_patches.realistic_acceleration && v->cur_speed != 0) { - v->u.rail.flags ^= VRF_REVERSING; + TOGGLEBIT(v->u.rail.flags, VRF_REVERSING); } else { v->cur_speed = 0; SetLastSpeed(v, 0); @@ -1751,7 +1779,7 @@ static int UpdateTrainSpeed(Vehicle *v) uint spd; uint accel; - if (v->vehstatus & VS_STOPPED || v->u.rail.flags & VRF_REVERSING) { + if (v->vehstatus & VS_STOPPED || HASBIT(v->u.rail.flags, VRF_REVERSING)) { accel = -v->acceleration * 2; } else { accel = v->acceleration; @@ -1815,7 +1843,7 @@ static void TrainEnterStation(Vehicle *v, int station) InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); } -static byte AfterSetTrainPos(Vehicle *v) +static byte AfterSetTrainPos(Vehicle *v, bool new_tile) { byte new_z, old_z; @@ -1827,10 +1855,13 @@ static byte AfterSetTrainPos(Vehicle *v) old_z = v->z_pos; v->z_pos = new_z; - v->u.rail.flags &= ~(VRF_GOINGUP | VRF_GOINGDOWN); + if (new_tile) { + CLRBIT(v->u.rail.flags, VRF_GOINGUP); + CLRBIT(v->u.rail.flags, VRF_GOINGDOWN); - if (new_z != old_z) { - v->u.rail.flags |= (new_z > old_z) ? VRF_GOINGUP : VRF_GOINGDOWN; + if (new_z != old_z) { + SETBIT(v->u.rail.flags, (new_z > old_z) ? VRF_GOINGUP : VRF_GOINGDOWN); + } } VehiclePositionChanged(v); @@ -2228,7 +2259,7 @@ common:; v->y_pos = gp.y; /* update the Z position of the vehicle */ - old_z = AfterSetTrainPos(v); + old_z = AfterSetTrainPos(v, (gp.new_tile != gp.old_tile)); if (prev == NULL) { /* This is the first vehicle in the train */ @@ -2333,7 +2364,7 @@ static void ChangeTrainDirRandomly(Vehicle *v) BeginVehicleMove(v); UpdateTrainDeltaXY(v, v->direction); v->cur_image = GetTrainImage(v, v->direction); - AfterSetTrainPos(v); + AfterSetTrainPos(v, false); } } while ( (v=v->next) != NULL); } @@ -2536,7 +2567,7 @@ static void TrainLocoHandler(Vehicle *v, bool mode) v->breakdown_ctr--; } - if (v->u.rail.flags & VRF_REVERSING && v->cur_speed == 0) { + if (HASBIT(v->u.rail.flags, VRF_REVERSING) && v->cur_speed == 0) { ReverseTrainDirection(v); } @@ -55,11 +55,11 @@ typedef struct VehicleRail { } VehicleRail; enum { - VRF_REVERSING = 1, + VRF_REVERSING = 0, // used to calculate if train is going up or down - VRF_GOINGUP = 2, - VRF_GOINGDOWN = 4, + VRF_GOINGUP = 1, + VRF_GOINGDOWN = 2, }; typedef struct VehicleAir { |