summaryrefslogtreecommitdiff
path: root/train_cmd.c
diff options
context:
space:
mode:
authorhackykid <hackykid@openttd.org>2005-06-06 14:26:15 +0000
committerhackykid <hackykid@openttd.org>2005-06-06 14:26:15 +0000
commit16ab34615f6155ad01e6738226c1ab143e52c5ac (patch)
treebbbedcdcdca0f8c00a6c413b77c3deaf08307848 /train_cmd.c
parent871e21e991fb1f67e79f44e45e6d5eac4a1410dc (diff)
downloadopenttd-16ab34615f6155ad01e6738226c1ab143e52c5ac.tar.xz
(svn r2423) - CodeChange: Include first_engine in the train cache, instead of calculating it all over the place.
- Fix: Also recalculate the train cache values for 'wagon chains' (in the depot without an engine), to avoid possible desyncs later. - Fix: Make CmdMoveRailVehicle update the caches of the correct trains in all cases.
Diffstat (limited to 'train_cmd.c')
-rw-r--r--train_cmd.c93
1 files changed, 49 insertions, 44 deletions
diff --git a/train_cmd.c b/train_cmd.c
index 0096e43b4..a2d1aeda6 100644
--- a/train_cmd.c
+++ b/train_cmd.c
@@ -60,19 +60,31 @@ void TrainCargoChanged(Vehicle *v) {
}
/**
- * Recalculates the cached stuff of a train. Should be called each time a vehicle is added to/removed from
- * the consist, and when the game is loaded.
- * @param v First vehicle of the consist.
+ * Recalculates the cached stuff of a train. Should be called each time a vehicle is added
+ * to/removed from the chain, and when the game is loaded.
+ * Note: this needs to be called too for 'wagon chains' (in the depot, without an engine)
+ * @param v First vehicle of the chain.
*/
void TrainConsistChanged(Vehicle *v) {
- const RailVehicleInfo *rvi_v = RailVehInfo(v->engine_type);
+ const RailVehicleInfo *rvi_v;
Vehicle *u;
uint16 max_speed = 0xFFFF;
uint32 power = 0;
+ EngineID first_engine;
+
+ assert(v->type == VEH_Train);
+
+ assert(v->subtype == TS_Front_Engine || v->subtype == TS_Free_Car);
+
+ rvi_v = RailVehInfo(v->engine_type);
+ first_engine = (v->subtype == TS_Front_Engine) ? v->engine_type : INVALID_VEHICLE;
for (u = v; u != NULL; u = u->next) {
const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
+ // update the 'first engine'
+ u->u.rail.first_engine = (v == u) ? INVALID_VEHICLE : first_engine;
+
// power is the sum of the powers of all engines and powered wagons in the consist
power += rvi_u->power;
@@ -449,11 +461,6 @@ static int32 CmdBuildRailWagon(uint engine, uint tile, uint32 flags)
if (u != NULL) {
u->next = v;
v->subtype = TS_Not_First;
- v->u.rail.first_engine = u->u.rail.first_engine;
- if (v->u.rail.first_engine == 0xffff && u->subtype == TS_Front_Engine)
- v->u.rail.first_engine = u->engine_type;
- } else {
- v->u.rail.first_engine = 0xffff;
}
v->cargo_type = rvi->cargo_type;
@@ -471,6 +478,7 @@ static int32 CmdBuildRailWagon(uint engine, uint tile, uint32 flags)
_new_wagon_id = v->index;
VehiclePositionChanged(v);
+ TrainConsistChanged(GetFirstVehicleInChain(v));
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
}
@@ -547,7 +555,6 @@ void AddRearEngineToMultiheadedTrain(Vehicle *v, Vehicle *u, bool building)
u->z_pos = v->z_pos;
u->z_height = 6;
u->u.rail.track = 0x80;
- v->u.rail.first_engine = 0xffff;
u->vehstatus = v->vehstatus & ~VS_STOPPED;
u->subtype = TS_Not_First;
u->spritenum = v->spritenum + 1;
@@ -620,7 +627,6 @@ int32 CmdBuildRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
v->z_pos = GetSlopeZ(x,y);
v->z_height = 6;
v->u.rail.track = 0x80;
- v->u.rail.first_engine = 0xffff;
v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
v->spritenum = rvi->image_index;
v->cargo_type = rvi->cargo_type;
@@ -705,14 +711,11 @@ static Vehicle *UnlinkWagon(Vehicle *v, Vehicle *first)
{
Vehicle *u;
- v->u.rail.first_engine = INVALID_VEHICLE;
-
// unlinking the first vehicle of the chain?
if (v == first) {
v = v->next;
if (v == NULL) return NULL;
- for (u = v; u != NULL; u = u->next) u->u.rail.first_engine = v->engine_type;
v->subtype = TS_Free_Car;
return v;
}
@@ -838,10 +841,12 @@ int32 CmdMoveRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
Vehicle *v = src_head;
while (v->next != src) v=v->next;
v->next = NULL;
+ } else {
+ src_head = NULL;
}
} else {
// unlink single wagon from linked list
- UnlinkWagon(src, src_head);
+ src_head = UnlinkWagon(src, src_head);
src->next = NULL;
}
@@ -854,11 +859,10 @@ int32 CmdMoveRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
assert(src->orders == NULL);
src->num_orders = 0;
}
- dst_head = src;
} else {
src->subtype = TS_Free_Car;
}
- src->u.rail.first_engine = 0xffff;
+ dst_head = src;
} else {
if (src->subtype == TS_Front_Engine) {
// the vehicle was previously a loco. need to free the order list and delete vehicle windows etc.
@@ -869,44 +873,42 @@ int32 CmdMoveRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
src->subtype = TS_Not_First;
src->unitnumber = 0; // doesn't occupy a unitnumber anymore.
- // setup first_engine
- src->u.rail.first_engine = dst->u.rail.first_engine;
- if (src->u.rail.first_engine == 0xffff && dst->subtype == TS_Front_Engine)
- src->u.rail.first_engine = dst->engine_type;
-
// link in the wagon(s) in the chain.
{
Vehicle *v;
- for (v = src; v->next != NULL; v = v->next) {
- v->next->u.rail.first_engine = v->u.rail.first_engine;
- }
+ for (v = src; v->next != NULL; v = v->next) {};
v->next = dst->next;
}
dst->next = src;
}
- if (src_head->subtype == TS_Front_Engine) {
+ if (src_head) {
TrainConsistChanged(src_head);
- UpdateTrainAcceleration(src_head);
- }
- InvalidateWindow(WC_VEHICLE_DETAILS, src_head->index);
- InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
+ if (src_head->subtype == TS_Front_Engine) {
+ UpdateTrainAcceleration(src_head);
+ InvalidateWindow(WC_VEHICLE_DETAILS, src_head->index);
+ /* Update the refit button and window */
+ InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, 12);
+ }
+ /* Update the depot window */
+ InvalidateWindow(WC_VEHICLE_DEPOT, src_head->tile);
+ };
if (dst_head) {
+ TrainConsistChanged(dst_head);
if (dst_head->subtype == TS_Front_Engine) {
- TrainConsistChanged(dst_head);
UpdateTrainAcceleration(dst_head);
+ InvalidateWindow(WC_VEHICLE_DETAILS, dst_head->index);
+ /* Update the refit button and window */
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, dst_head->index, 12);
+ InvalidateWindow(WC_VEHICLE_REFIT, dst_head->index);
}
- InvalidateWindow(WC_VEHICLE_DETAILS, dst_head->index);
- /* Update the refit button and window */
- InvalidateWindowWidget(WC_VEHICLE_VIEW, dst_head->index, 12);
- InvalidateWindow(WC_VEHICLE_REFIT, dst_head->index);
+ /* Update the depot window */
+ InvalidateWindow(WC_VEHICLE_DEPOT, dst_head->tile);
}
- /* I added this to so that the refit buttons get updated */
- InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, 12);
- InvalidateWindow(WC_VEHICLE_DEPOT, src_head->tile);
RebuildVehicleLists();
}
@@ -1048,11 +1050,13 @@ int32 CmdSellRailWagon(int x, int y, uint32 flags, uint32 p1, uint32 p2)
if (switch_engine) first->subtype = TS_Front_Engine;
/* 5. If the train still exists, update its acceleration, window, etc. */
- if (first != NULL && first->subtype == TS_Front_Engine) {
- InvalidateWindow(WC_VEHICLE_DETAILS, first->index);
- InvalidateWindow(WC_VEHICLE_REFIT, first->index);
+ if (first != NULL) {
TrainConsistChanged(first);
- UpdateTrainAcceleration(first);
+ if (first->subtype == TS_Front_Engine) {
+ InvalidateWindow(WC_VEHICLE_DETAILS, first->index);
+ InvalidateWindow(WC_VEHICLE_REFIT, first->index);
+ UpdateTrainAcceleration(first);
+ }
}
@@ -1103,9 +1107,10 @@ int32 CmdSellRailWagon(int x, int y, uint32 flags, uint32 p1, uint32 p2)
}
/* 3. If it is still a valid train after selling, update its acceleration and cached values */
- if ((flags & DC_EXEC) && first != NULL && first->subtype == TS_Front_Engine) {
+ if ((flags & DC_EXEC) && first != NULL) {
TrainConsistChanged(first);
- UpdateTrainAcceleration(first);
+ if (first->subtype == TS_Front_Engine)
+ UpdateTrainAcceleration(first);
}
} break;
}