diff options
author | Darkvater <Darkvater@openttd.org> | 2005-04-08 22:44:06 +0000 |
---|---|---|
committer | Darkvater <Darkvater@openttd.org> | 2005-04-08 22:44:06 +0000 |
commit | 8f4583b1610dcf848cc45b2714964d9217c60611 (patch) | |
tree | 03255e464a7b6b59f6adf9af778478eb33638e18 | |
parent | 4a1d9a4775a217f343efcc53f179c23af93960fb (diff) | |
download | openttd-8f4583b1610dcf848cc45b2714964d9217c60611.tar.xz |
(svn r2168) - Fix: Various stages of invisible trains, and wrong v->u.rail.track combinations. When a vehicle was sold its (possibly) assigned road slot for multislot was not cleared, thus resulting in a bug confusion. This should fix [ 1178520 ] Assertion failure in ai.c (invalid v->u.rail.track). With big thanks to TrueLight for the demo-recording patch, BJH for the wonderful savegame, Hackykid for his brilliant suggestions of the problem and Celestar for... ehm, making it all possible ;p
-rw-r--r-- | roadveh_cmd.c | 18 | ||||
-rw-r--r-- | station_cmd.c | 73 |
2 files changed, 37 insertions, 54 deletions
diff --git a/roadveh_cmd.c b/roadveh_cmd.c index d868624c7..591bd8879 100644 --- a/roadveh_cmd.c +++ b/roadveh_cmd.c @@ -229,6 +229,15 @@ int32 CmdStartStopRoadVeh(int x, int y, uint32 flags, uint32 p1, uint32 p2) return 0; } +static inline void ClearSlot(Vehicle *v, RoadStop *rs) +{ + DEBUG(ms, 3) ("Multistop: Clearing slot %d at 0x%x", v->u.road.slotindex, rs->xy); + v->u.road.slot = NULL; + v->u.road.slot_age = 0; + if (rs != NULL) + rs->slot[v->u.road.slotindex] = INVALID_SLOT; +} + // p1 = vehicle index in GetVehicle() // p2 not used int32 CmdSellRoadVeh(int x, int y, uint32 flags, uint32 p1, uint32 p2) @@ -253,6 +262,7 @@ int32 CmdSellRoadVeh(int x, int y, uint32 flags, uint32 p1, uint32 p2) RebuildVehicleLists(); InvalidateWindow(WC_COMPANY, v->owner); DeleteWindowById(WC_VEHICLE_VIEW, v->index); + ClearSlot(v, v->u.road.slot); DeleteVehicle(v); } InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Road); // updates the replace Road window @@ -1177,14 +1187,6 @@ static const byte _road_veh_data_1[] = { static const byte _roadveh_data_2[4] = { 0,1,8,9 }; -static inline void ClearSlot(Vehicle *v, RoadStop *rs) -{ - DEBUG(ms, 3) ("Multistop: Clearing slot %d at 0x%x", v->u.road.slotindex, rs->xy); - v->u.road.slot = NULL; - v->u.road.slot_age = 0; - rs->slot[v->u.road.slotindex] = INVALID_SLOT; -} - static void RoadVehController(Vehicle *v) { GetNewVehiclePosResult gp; diff --git a/station_cmd.c b/station_cmd.c index 05c560eb4..06745044d 100644 --- a/station_cmd.c +++ b/station_cmd.c @@ -2418,6 +2418,30 @@ void DeleteAllPlayerStations(void) } } +static void CheckOrphanedSlots(const Station *st, RoadStopType rst) +{ + RoadStop *rs; + int k; + + for (rs = GetPrimaryRoadStop(st, rst); rs != NULL; rs = rs->next) { + for (k = 0; k < NUM_SLOTS; k++) { + if (rs->slot[k] != INVALID_SLOT) { + Vehicle *v = GetVehicle(rs->slot[k]); + + assert(v->type == VEH_Road); + if (v->u.road.slot != rs) { + DEBUG(ms, 1) ("Multistop: %s slot desync between stop at 0x%X of station %d " + "and Vehicle %d at going to 0x%X! (don't panic)", (v->cargo_type == CT_PASSENGERS) ? "Bus" : "Truck", + rs->xy, st->index, v->unitnumber, v->dest_tile); + v->u.road.slot = NULL; + v->u.road.slot_age = 0; + rs->slot[k] = INVALID_SLOT; + } + } + } + } +} + /* this function is called for one station each tick */ static void StationHandleBigTick(Station *st) { @@ -2428,52 +2452,9 @@ static void StationHandleBigTick(Station *st) DeleteStation(st); } - //Here we saveguard against orphaned slots - { - RoadStop *rs; - - for (rs = GetPrimaryRoadStop(st, RS_BUS); rs != NULL; rs = rs->next) { - int k; - for (k = 0; k < NUM_SLOTS; k++) { - if (rs->slot[k] != INVALID_SLOT) { - Vehicle *v = GetVehicle(rs->slot[k]); - - if (v->u.road.slot != rs) { - DEBUG(ms, 1) ("Multistop: Truck Slot Desync between stop at " - "0x%x of station %d (at 0x%x) and Vehicle %d at 0x%x, " - "going to 0x%x! " - "cleaning up (Don't panic)", - rs->xy, st->index, st->xy, v->unitnumber, v->tile, - v->dest_tile); - v->u.road.slot = NULL; - v->u.road.slot_age = 0; - rs->slot[k] = INVALID_SLOT; - } - } - } - } - - for (rs = GetPrimaryRoadStop(st, RS_TRUCK); rs != NULL; rs = rs->next) { - int k; - for (k = 0; k < NUM_SLOTS; k++) { - if (rs->slot[k] != INVALID_SLOT) { - Vehicle *v = GetVehicle(rs->slot[k]); - - if (v->u.road.slot != rs) { - DEBUG(ms, 1) ("Multistop: Truck Slot Desync between stop at " - "0x%x of station %d (at 0x%x) and Vehicle %d at 0x%x, " - "going to 0x%x! " - "cleaning up (Don't panic)", - rs->xy, st->index, st->xy, v->unitnumber, v->tile, - v->dest_tile); - v->u.road.slot = NULL; - v->u.road.slot_age = 0; - rs->slot[k] = INVALID_SLOT; - } - } - } - } - } + // Here we saveguard against orphaned slots + CheckOrphanedSlots(st, RS_BUS); + CheckOrphanedSlots(st, RS_TRUCK); } static inline void byte_inc_sat(byte *p) { byte b = *p + 1; if (b != 0) *p = b; } |