# HG changeset patch # User truelight # Date 1105286526 0 # Node ID 4d052517a9938db5b143d7cb42c6e0b369c78db1 # Parent 4e4f7354943782dc472fe6f32297cd26b9a96b86 (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 diff -r 4e4f73549437 -r 4d052517a993 macros.h --- a/macros.h Sun Jan 09 14:45:19 2005 +0000 +++ b/macros.h Sun Jan 09 16:02:06 2005 +0000 @@ -99,9 +99,10 @@ #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 -r 4e4f73549437 -r 4d052517a993 train_cmd.c --- a/train_cmd.c Sun Jan 09 14:45:19 2005 +0000 +++ b/train_cmd.c Sun Jan 09 16:02:06 2005 +0000 @@ -102,9 +102,9 @@ 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 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ old_z = v->z_pos; v->z_pos = new_z; - v->u.rail.flags &= ~(VRF_GOINGUP | VRF_GOINGDOWN); - - if (new_z != old_z) { - v->u.rail.flags |= (new_z > old_z) ? 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) { + SETBIT(v->u.rail.flags, (new_z > old_z) ? VRF_GOINGUP : VRF_GOINGDOWN); + } } VehiclePositionChanged(v); @@ -2228,7 +2259,7 @@ 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 @@ 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 @@ 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); } diff -r 4e4f73549437 -r 4d052517a993 vehicle.h --- a/vehicle.h Sun Jan 09 14:45:19 2005 +0000 +++ b/vehicle.h Sun Jan 09 16:02:06 2005 +0000 @@ -55,11 +55,11 @@ } 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 {