4 |
4 |
5 #include "stdafx.h" |
5 #include "stdafx.h" |
6 #include "openttd.h" |
6 #include "openttd.h" |
7 #include "bridge_map.h" |
7 #include "bridge_map.h" |
8 #include "debug.h" |
8 #include "debug.h" |
9 #include "functions.h" |
9 #include "tile_cmd.h" |
10 #include "landscape.h" |
10 #include "landscape.h" |
11 #include "gui.h" |
11 #include "gui.h" |
12 #include "station_map.h" |
12 #include "station_map.h" |
13 #include "table/strings.h" |
13 #include "table/strings.h" |
14 #include "strings.h" |
|
15 #include "map.h" |
|
16 #include "tile.h" |
|
17 #include "tunnel_map.h" |
14 #include "tunnel_map.h" |
18 #include "vehicle.h" |
|
19 #include "timetable.h" |
15 #include "timetable.h" |
20 #include "articulated_vehicles.h" |
16 #include "articulated_vehicles.h" |
21 #include "command.h" |
17 #include "command_func.h" |
22 #include "pathfind.h" |
18 #include "pathfind.h" |
23 #include "npf.h" |
19 #include "npf.h" |
24 #include "station.h" |
20 #include "station.h" |
25 #include "table/train_cmd.h" |
21 #include "table/train_cmd.h" |
26 #include "news.h" |
22 #include "news.h" |
27 #include "engine.h" |
23 #include "engine.h" |
28 #include "player.h" |
24 #include "player.h" |
29 #include "sound.h" |
|
30 #include "depot.h" |
25 #include "depot.h" |
31 #include "waypoint.h" |
26 #include "waypoint.h" |
32 #include "vehicle_gui.h" |
27 #include "vehicle_gui.h" |
33 #include "train.h" |
28 #include "train.h" |
34 #include "bridge.h" |
29 #include "bridge.h" |
35 #include "newgrf_callbacks.h" |
30 #include "newgrf_callbacks.h" |
36 #include "newgrf_engine.h" |
31 #include "newgrf_engine.h" |
37 #include "newgrf_sound.h" |
32 #include "newgrf_sound.h" |
38 #include "newgrf_text.h" |
33 #include "newgrf_text.h" |
39 #include "direction.h" |
34 #include "direction_func.h" |
40 #include "yapf/yapf.h" |
35 #include "yapf/yapf.h" |
41 #include "date.h" |
|
42 #include "cargotype.h" |
36 #include "cargotype.h" |
43 #include "group.h" |
37 #include "group.h" |
44 #include "table/sprites.h" |
38 #include "table/sprites.h" |
|
39 #include "tunnelbridge_map.h" |
|
40 #include "strings_func.h" |
|
41 #include "functions.h" |
|
42 #include "window_func.h" |
|
43 #include "date_func.h" |
|
44 #include "vehicle_func.h" |
|
45 #include "sound_func.h" |
|
46 #include "variables.h" |
|
47 #include "autoreplace_gui.h" |
|
48 #include "gfx_func.h" |
45 #include "ai/ai.h" |
49 #include "ai/ai.h" |
|
50 |
46 |
51 |
47 static bool TrainCheckIfLineEnds(Vehicle *v); |
52 static bool TrainCheckIfLineEnds(Vehicle *v); |
48 static void TrainController(Vehicle *v, bool update_image); |
53 static void TrainController(Vehicle *v, bool update_image); |
49 |
54 |
50 static const byte _vehicle_initial_x_fract[4] = {10, 8, 4, 8}; |
55 static const byte _vehicle_initial_x_fract[4] = {10, 8, 4, 8}; |
161 const RailVehicleInfo *rvi_v = RailVehInfo(v->engine_type); |
166 const RailVehicleInfo *rvi_v = RailVehInfo(v->engine_type); |
162 EngineID first_engine = IsFrontEngine(v) ? v->engine_type : INVALID_ENGINE; |
167 EngineID first_engine = IsFrontEngine(v) ? v->engine_type : INVALID_ENGINE; |
163 v->u.rail.cached_total_length = 0; |
168 v->u.rail.cached_total_length = 0; |
164 v->u.rail.compatible_railtypes = 0; |
169 v->u.rail.compatible_railtypes = 0; |
165 |
170 |
|
171 bool train_can_tilt = true; |
|
172 |
166 for (Vehicle *u = v; u != NULL; u = u->Next()) { |
173 for (Vehicle *u = v; u != NULL; u = u->Next()) { |
167 const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type); |
174 const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type); |
168 |
175 |
169 /* Check the v->first cache. */ |
176 /* Check the v->first cache. */ |
170 assert(u->First() == v); |
177 assert(u->First() == v); |
|
178 |
|
179 if (!HasBit(EngInfo(u->engine_type)->misc_flags, EF_RAIL_TILTS)) train_can_tilt = false; |
171 |
180 |
172 /* update the 'first engine' */ |
181 /* update the 'first engine' */ |
173 u->u.rail.first_engine = v == u ? INVALID_ENGINE : first_engine; |
182 u->u.rail.first_engine = v == u ? INVALID_ENGINE : first_engine; |
174 u->u.rail.railtype = rvi_u->railtype; |
183 u->u.rail.railtype = rvi_u->railtype; |
175 |
184 |
308 } |
294 } |
309 |
295 |
310 /** new acceleration*/ |
296 /** new acceleration*/ |
311 static int GetTrainAcceleration(Vehicle *v, bool mode) |
297 static int GetTrainAcceleration(Vehicle *v, bool mode) |
312 { |
298 { |
313 int max_speed = 2000; |
299 static const int absolute_max_speed = 2000; |
|
300 int max_speed = absolute_max_speed; |
314 int speed = v->cur_speed * 10 / 16; // km-ish/h -> mp/h |
301 int speed = v->cur_speed * 10 / 16; // km-ish/h -> mp/h |
315 int curvecount[2] = {0, 0}; |
302 int curvecount[2] = {0, 0}; |
316 |
303 |
317 /*first find the curve speed limit */ |
304 /*first find the curve speed limit */ |
318 int numcurve = 0; |
305 int numcurve = 0; |
319 int sum = 0; |
306 int sum = 0; |
320 int pos = 0; |
307 int pos = 0; |
321 int lastpos = -1; |
308 int lastpos = -1; |
322 for (const Vehicle *u = v; u->Next() != NULL; u = u->Next(), pos++) { |
309 for (const Vehicle *u = v; u->Next() != NULL; u = u->Next(), pos++) { |
323 Direction dir = u->direction; |
310 Direction this_dir = u->direction; |
324 Direction ndir = u->Next()->direction; |
311 Direction next_dir = u->Next()->direction; |
325 int i; |
312 |
326 |
313 DirDiff dirdiff = DirDifference(this_dir, next_dir); |
327 for (i = 0; i < 2; i++) { |
314 if (dirdiff == DIRDIFF_SAME) continue; |
328 if ( _curve_neighbours45[dir][i] == ndir) { |
315 |
329 curvecount[i]++; |
316 if (dirdiff == DIRDIFF_45LEFT) curvecount[0]++; |
330 if (lastpos != -1) { |
317 if (dirdiff == DIRDIFF_45RIGHT) curvecount[1]++; |
331 numcurve++; |
318 if (dirdiff == DIRDIFF_45LEFT || dirdiff == DIRDIFF_45RIGHT) { |
332 sum += pos - lastpos; |
319 if (lastpos != -1) { |
333 if (pos - lastpos == 1) { |
320 numcurve++; |
334 max_speed = 88; |
321 sum += pos - lastpos; |
335 } |
322 if (pos - lastpos == 1) { |
|
323 max_speed = 88; |
336 } |
324 } |
337 lastpos = pos; |
325 } |
338 } |
326 lastpos = pos; |
339 } |
327 } |
340 |
328 |
341 /*if we have a 90 degree turn, fix the speed limit to 60 */ |
329 /*if we have a 90 degree turn, fix the speed limit to 60 */ |
342 if (_curve_neighbours90[dir][0] == ndir || |
330 if (dirdiff == DIRDIFF_90LEFT || dirdiff == DIRDIFF_90RIGHT) { |
343 _curve_neighbours90[dir][1] == ndir) { |
|
344 max_speed = 61; |
331 max_speed = 61; |
345 } |
332 } |
346 } |
333 } |
347 |
|
348 if (numcurve > 0) sum /= numcurve; |
|
349 |
334 |
350 if ((curvecount[0] != 0 || curvecount[1] != 0) && max_speed > 88) { |
335 if ((curvecount[0] != 0 || curvecount[1] != 0) && max_speed > 88) { |
351 int total = curvecount[0] + curvecount[1]; |
336 int total = curvecount[0] + curvecount[1]; |
352 |
337 |
353 if (curvecount[0] == 1 && curvecount[1] == 1) { |
338 if (curvecount[0] == 1 && curvecount[1] == 1) { |
354 max_speed = 0xFFFF; |
339 max_speed = absolute_max_speed; |
355 } else if (total > 1) { |
340 } else if (total > 1) { |
|
341 if (numcurve > 0) sum /= numcurve; |
356 max_speed = 232 - (13 - Clamp(sum, 1, 12)) * (13 - Clamp(sum, 1, 12)); |
342 max_speed = 232 - (13 - Clamp(sum, 1, 12)) * (13 - Clamp(sum, 1, 12)); |
357 } |
343 } |
358 } |
344 } |
359 |
345 |
360 max_speed += (max_speed / 2) * v->u.rail.railtype; |
346 if (max_speed != absolute_max_speed) { |
|
347 /* Apply the engine's rail type curve speed advantage, if it slowed by curves */ |
|
348 const RailtypeInfo *rti = GetRailTypeInfo(v->u.rail.railtype); |
|
349 max_speed += (max_speed / 2) * rti->curve_speed; |
|
350 |
|
351 if (v->u.rail.cached_tilt) { |
|
352 /* Apply max_speed bonus of 20% for a tilting train */ |
|
353 max_speed += max_speed / 5; |
|
354 } |
|
355 } |
361 |
356 |
362 if (IsTileType(v->tile, MP_STATION) && IsFrontEngine(v)) { |
357 if (IsTileType(v->tile, MP_STATION) && IsFrontEngine(v)) { |
363 if (TrainShouldStop(v, v->tile)) { |
358 if (TrainShouldStop(v, v->tile)) { |
364 int station_length = GetStationByTile(v->tile)->GetPlatformLength(v->tile, DirToDiagDir(v->direction)); |
359 int station_length = GetStationByTile(v->tile)->GetPlatformLength(v->tile, DirToDiagDir(v->direction)); |
365 int delta_v; |
360 |
366 |
361 int st_max_speed = 120; |
367 max_speed = 120; |
362 |
368 |
363 int delta_v = v->cur_speed / (station_length + 1); |
369 delta_v = v->cur_speed / (station_length + 1); |
364 if (v->max_speed > (v->cur_speed - delta_v)) { |
370 if (v->max_speed > (v->cur_speed - delta_v)) |
365 st_max_speed = v->cur_speed - (delta_v / 10); |
371 max_speed = v->cur_speed - (delta_v / 10); |
366 } |
372 |
367 |
373 max_speed = max(max_speed, 25 * station_length); |
368 st_max_speed = max(st_max_speed, 25 * station_length); |
|
369 max_speed = min(max_speed, st_max_speed); |
374 } |
370 } |
375 } |
371 } |
376 |
372 |
377 int mass = v->u.rail.cached_weight; |
373 int mass = v->u.rail.cached_weight; |
378 int power = v->u.rail.cached_power * 746; |
374 int power = v->u.rail.cached_power * 746; |
514 DrawSprite(image, pal, x, y); |
510 DrawSprite(image, pal, x, y); |
515 } |
511 } |
516 |
512 |
517 static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 flags) |
513 static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 flags) |
518 { |
514 { |
519 SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); |
|
520 |
|
521 const RailVehicleInfo *rvi = RailVehInfo(engine); |
515 const RailVehicleInfo *rvi = RailVehInfo(engine); |
522 CommandCost value((GetEngineProperty(engine, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8); |
516 CommandCost value(EXPENSES_NEW_VEHICLES, (GetEngineProperty(engine, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8); |
523 |
517 |
524 uint num_vehicles = 1 + CountArticulatedParts(engine, false); |
518 uint num_vehicles = 1 + CountArticulatedParts(engine, false); |
525 |
519 |
526 if (!(flags & DC_QUERY_COST)) { |
520 if (!(flags & DC_QUERY_COST)) { |
527 /* Allow for the wagon and the articulated parts, plus one to "terminate" the list. */ |
521 /* Allow for the wagon and the articulated parts, plus one to "terminate" the list. */ |
674 if (!(flags & DC_QUERY_COST)) { |
668 if (!(flags & DC_QUERY_COST)) { |
675 if (!IsTileDepotType(tile, TRANSPORT_RAIL)) return CMD_ERROR; |
669 if (!IsTileDepotType(tile, TRANSPORT_RAIL)) return CMD_ERROR; |
676 if (!IsTileOwner(tile, _current_player)) return CMD_ERROR; |
670 if (!IsTileOwner(tile, _current_player)) return CMD_ERROR; |
677 } |
671 } |
678 |
672 |
679 SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); |
|
680 |
|
681 const RailVehicleInfo *rvi = RailVehInfo(p1); |
673 const RailVehicleInfo *rvi = RailVehInfo(p1); |
682 |
674 |
683 /* Check if depot and new engine uses the same kind of tracks */ |
675 /* Check if depot and new engine uses the same kind of tracks */ |
684 /* We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */ |
676 /* We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */ |
685 if (!HasPowerOnRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR; |
677 if (!HasPowerOnRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR; |
1023 return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
1016 return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
1024 |
1017 |
1025 if (flags & DC_EXEC) src->unitnumber = unit_num; |
1018 if (flags & DC_EXEC) src->unitnumber = unit_num; |
1026 } |
1019 } |
1027 |
1020 |
1028 if (dst_head != NULL) { |
1021 /* |
1029 /* Check NewGRF Callback 0x1D */ |
1022 * Check whether the vehicles in the source chain are in the destination |
1030 uint16 callback = GetVehicleCallbackParent(CBID_TRAIN_ALLOW_WAGON_ATTACH, 0, 0, dst_head->engine_type, src, dst_head); |
1023 * chain. This can easily be done by checking whether the first vehicle |
1031 if (callback != CALLBACK_FAILED) { |
1024 * of the source chain is in the destination chain as the Next/Previous |
1032 if (callback == 0xFD) return_cmd_error(STR_INCOMPATIBLE_RAIL_TYPES); |
1025 * pointers always make a doubly linked list of it where the assumption |
1033 if (callback < 0xFD) { |
1026 * v->Next()->Previous() == v holds (assuming v->Next() != NULL). |
1034 StringID error = GetGRFStringID(GetEngineGRFID(dst_head->engine_type), 0xD000 + callback); |
1027 */ |
1035 return_cmd_error(error); |
1028 bool src_in_dst = false; |
1036 } |
1029 for (Vehicle *v = dst_head; !src_in_dst && v != NULL; v = v->Next()) src_in_dst = v == src; |
1037 } |
1030 |
|
1031 /* |
|
1032 * If the source chain is in the destination chain then the user is |
|
1033 * only reordering the vehicles, thus not attaching a new vehicle. |
|
1034 * Therefor the 'allow wagon attach' callback does not need to be |
|
1035 * called. If it would be called strange things would happen because |
|
1036 * one 'attaches' an already 'attached' vehicle causing more trouble |
|
1037 * than it actually solves (infinite loops and such). |
|
1038 */ |
|
1039 if (dst_head != NULL && !src_in_dst) { |
|
1040 /* |
|
1041 * When performing the 'allow wagon attach' callback, we have to check |
|
1042 * that for each and every wagon, not only the first one. This means |
|
1043 * that we have to test one wagon, attach it to the train and then test |
|
1044 * the next wagon till we have reached the end. We have to restore it |
|
1045 * to the state it was before we 'tried' attaching the train when the |
|
1046 * attaching fails or succeeds because we are not 'only' doing this |
|
1047 * in the DC_EXEC state. |
|
1048 */ |
|
1049 Vehicle *dst_tail = dst_head; |
|
1050 while (dst_tail->Next() != NULL) dst_tail = dst_tail->Next(); |
|
1051 |
|
1052 Vehicle *orig_tail = dst_tail; |
|
1053 Vehicle *next_to_attach = src; |
|
1054 Vehicle *src_previous = src->Previous(); |
|
1055 |
|
1056 while (next_to_attach != NULL) { |
|
1057 /* Back up and clear the first_engine data to avoid using wagon override group */ |
|
1058 EngineID first_engine = next_to_attach->u.rail.first_engine; |
|
1059 next_to_attach->u.rail.first_engine = INVALID_ENGINE; |
|
1060 |
|
1061 uint16 callback = GetVehicleCallbackParent(CBID_TRAIN_ALLOW_WAGON_ATTACH, 0, 0, dst_head->engine_type, next_to_attach, dst_head); |
|
1062 |
|
1063 /* Restore original first_engine data */ |
|
1064 next_to_attach->u.rail.first_engine = first_engine; |
|
1065 |
|
1066 if (callback != CALLBACK_FAILED) { |
|
1067 StringID error = STR_NULL; |
|
1068 |
|
1069 if (callback == 0xFD) error = STR_INCOMPATIBLE_RAIL_TYPES; |
|
1070 if (callback < 0xFD) error = GetGRFStringID(GetEngineGRFID(dst_head->engine_type), 0xD000 + callback); |
|
1071 |
|
1072 if (error != STR_NULL) { |
|
1073 /* |
|
1074 * The attaching is not allowed. In this case 'next_to_attach' |
|
1075 * can contain some vehicles of the 'source' and the destination |
|
1076 * train can have some too. We 'just' add the to-be added wagons |
|
1077 * to the chain and then split it where it was previously |
|
1078 * separated, i.e. the tail of the original destination train. |
|
1079 * Furthermore the 'previous' link of the original source vehicle needs |
|
1080 * to be restored, otherwise the train goes missing in the depot. |
|
1081 */ |
|
1082 dst_tail->SetNext(next_to_attach); |
|
1083 orig_tail->SetNext(NULL); |
|
1084 if (src_previous != NULL) src_previous->SetNext(src); |
|
1085 |
|
1086 return_cmd_error(error); |
|
1087 } |
|
1088 } |
|
1089 |
|
1090 /* Only check further wagons if told to move the chain */ |
|
1091 if (!HasBit(p2, 0)) break; |
|
1092 |
|
1093 /* |
|
1094 * Adding a next wagon to the chain so we can test the other wagons. |
|
1095 * First 'take' the first wagon from 'next_to_attach' and move it |
|
1096 * to the next wagon. Then add that to the tail of the destination |
|
1097 * train and update the tail with the new vehicle. |
|
1098 */ |
|
1099 Vehicle *to_add = next_to_attach; |
|
1100 next_to_attach = next_to_attach->Next(); |
|
1101 |
|
1102 to_add->SetNext(NULL); |
|
1103 dst_tail->SetNext(to_add); |
|
1104 dst_tail = dst_tail->Next(); |
|
1105 } |
|
1106 |
|
1107 /* |
|
1108 * When we reach this the attaching is allowed. It also means that the |
|
1109 * chain of vehicles to attach is empty, so we do not need to merge that. |
|
1110 * This means only the splitting needs to be done. |
|
1111 * Furthermore the 'previous' link of the original source vehicle needs |
|
1112 * to be restored, otherwise the train goes missing in the depot. |
|
1113 */ |
|
1114 orig_tail->SetNext(NULL); |
|
1115 if (src_previous != NULL) src_previous->SetNext(src); |
1038 } |
1116 } |
1039 |
1117 |
1040 /* do it? */ |
1118 /* do it? */ |
1041 if (flags & DC_EXEC) { |
1119 if (flags & DC_EXEC) { |
1042 /* If we move the front Engine and if the second vehicle is not an engine |
1120 /* If we move the front Engine and if the second vehicle is not an engine |
1526 } |
1602 } |
1527 |
1603 |
1528 /* Check if the vehicle is a train and is on the tile we are testing */ |
1604 /* Check if the vehicle is a train and is on the tile we are testing */ |
1529 static void *TestTrainOnCrossing(Vehicle *v, void *data) |
1605 static void *TestTrainOnCrossing(Vehicle *v, void *data) |
1530 { |
1606 { |
1531 if (v->tile != *(const TileIndex*)data || v->type != VEH_TRAIN) return NULL; |
1607 if (v->type != VEH_TRAIN) return NULL; |
1532 return v; |
1608 return v; |
1533 } |
1609 } |
1534 |
1610 |
1535 static void DisableTrainCrossing(TileIndex tile) |
1611 static void DisableTrainCrossing(TileIndex tile) |
1536 { |
1612 { |
1537 if (IsLevelCrossingTile(tile) && |
1613 if (IsLevelCrossingTile(tile) && |
1538 VehicleFromPos(tile, &tile, TestTrainOnCrossing) == NULL && // empty? |
1614 IsCrossingBarred(tile) && |
1539 IsCrossingBarred(tile)) { |
1615 VehicleFromPos(tile, NULL, &TestTrainOnCrossing) == NULL) { // empty? |
1540 UnbarCrossing(tile); |
1616 UnbarCrossing(tile); |
1541 MarkTileDirtyByTile(tile); |
1617 MarkTileDirtyByTile(tile); |
1542 } |
1618 } |
1543 } |
1619 } |
1544 |
1620 |
2773 tcc.num = 0; |
2845 tcc.num = 0; |
2774 |
2846 |
2775 /* find colliding vehicles */ |
2847 /* find colliding vehicles */ |
2776 if (v->u.rail.track == TRACK_BIT_WORMHOLE) { |
2848 if (v->u.rail.track == TRACK_BIT_WORMHOLE) { |
2777 VehicleFromPos(v->tile, &tcc, FindTrainCollideEnum); |
2849 VehicleFromPos(v->tile, &tcc, FindTrainCollideEnum); |
2778 if (IsBridgeTile(v->tile)) { |
2850 VehicleFromPos(GetOtherTunnelBridgeEnd(v->tile), &tcc, FindTrainCollideEnum); |
2779 VehicleFromPos(GetOtherBridgeEnd(v->tile), &tcc, FindTrainCollideEnum); |
|
2780 } else { |
|
2781 VehicleFromPos(GetOtherTunnelEnd(v->tile), &tcc, FindTrainCollideEnum); |
|
2782 } |
|
2783 } else { |
2851 } else { |
2784 VehicleFromPosXY(v->x_pos, v->y_pos, &tcc, FindTrainCollideEnum); |
2852 VehicleFromPosXY(v->x_pos, v->y_pos, &tcc, FindTrainCollideEnum); |
2785 } |
2853 } |
2786 |
2854 |
2787 /* any dead -> no crash */ |
2855 /* any dead -> no crash */ |
2797 |
2865 |
2798 ModifyStationRatingAround(v->tile, v->owner, -160, 30); |
2866 ModifyStationRatingAround(v->tile, v->owner, -160, 30); |
2799 SndPlayVehicleFx(SND_13_BIG_CRASH, v); |
2867 SndPlayVehicleFx(SND_13_BIG_CRASH, v); |
2800 } |
2868 } |
2801 |
2869 |
2802 struct VehicleAtSignalData { |
|
2803 TileIndex tile; |
|
2804 Direction direction; |
|
2805 }; |
|
2806 |
|
2807 static void *CheckVehicleAtSignal(Vehicle *v, void *data) |
2870 static void *CheckVehicleAtSignal(Vehicle *v, void *data) |
2808 { |
2871 { |
2809 const VehicleAtSignalData* vasd = (VehicleAtSignalData*)data; |
2872 Direction dir = *(Direction*)data; |
2810 |
2873 |
2811 if (v->type == VEH_TRAIN && IsFrontEngine(v) && v->tile == vasd->tile) { |
2874 if (v->type == VEH_TRAIN && IsFrontEngine(v)) { |
2812 DirDiff diff = ChangeDirDiff(DirDifference(v->direction, vasd->direction), DIRDIFF_90RIGHT); |
2875 DirDiff diff = ChangeDirDiff(DirDifference(v->direction, dir), DIRDIFF_90RIGHT); |
2813 |
2876 |
2814 if (diff == DIRDIFF_90RIGHT || (v->cur_speed <= 5 && diff <= DIRDIFF_REVERSE)) return v; |
2877 if (diff == DIRDIFF_90RIGHT || (v->cur_speed <= 5 && diff <= DIRDIFF_REVERSE)) return v; |
2815 } |
2878 } |
2816 return NULL; |
2879 return NULL; |
2817 } |
2880 } |
3025 v->cur_speed = 0; |
3087 v->cur_speed = 0; |
3026 v->subspeed = 0; |
3088 v->subspeed = 0; |
3027 ReverseTrainDirection(v); |
3089 ReverseTrainDirection(v); |
3028 } |
3090 } |
3029 |
3091 |
3030 extern TileIndex CheckTunnelBusy(TileIndex tile, uint *length); |
|
3031 |
|
3032 /** |
3092 /** |
3033 * Deletes/Clears the last wagon of a crashed train. It takes the engine of the |
3093 * Deletes/Clears the last wagon of a crashed train. It takes the engine of the |
3034 * train, then goes to the last wagon and deletes that. Each call to this function |
3094 * train, then goes to the last wagon and deletes that. Each call to this function |
3035 * will remove the last wagon of a crashed train. If this wagon was on a crossing, |
3095 * will remove the last wagon of a crashed train. If this wagon was on a crossing, |
3036 * or inside a tunnel, recalculate the signals as they might need updating |
3096 * or inside a tunnel/bridge, recalculate the signals as they might need updating |
3037 * @param v the Vehicle of which last wagon is to be removed |
3097 * @param v the Vehicle of which last wagon is to be removed |
3038 */ |
3098 */ |
3039 static void DeleteLastWagon(Vehicle *v) |
3099 static void DeleteLastWagon(Vehicle *v) |
3040 { |
3100 { |
3041 /* Go to the last wagon and delete the link pointing there |
3101 /* Go to the last wagon and delete the link pointing there |
3060 |
3120 |
3061 /* Check if the wagon was on a road/rail-crossing and disable it if no |
3121 /* Check if the wagon was on a road/rail-crossing and disable it if no |
3062 * others are on it */ |
3122 * others are on it */ |
3063 DisableTrainCrossing(v->tile); |
3123 DisableTrainCrossing(v->tile); |
3064 |
3124 |
3065 if ((v->u.rail.track == TRACK_BIT_WORMHOLE && v->vehstatus & VS_HIDDEN)) { // inside a tunnel |
3125 if (v->u.rail.track == TRACK_BIT_WORMHOLE) { // inside a tunnel / bridge |
3066 TileIndex endtile = CheckTunnelBusy(v->tile, NULL); |
3126 TileIndex endtile = GetOtherTunnelBridgeEnd(v->tile); |
3067 |
3127 |
3068 if (endtile == INVALID_TILE) return; // tunnel is busy (error returned) |
3128 if (GetVehicleTunnelBridge(v->tile, endtile) != NULL) return; // tunnel / bridge is busy |
3069 |
3129 |
3070 switch (v->direction) { |
3130 DiagDirection dir = GetTunnelBridgeDirection(v->tile); |
3071 case 1: |
3131 |
3072 case 5: |
3132 /* v->direction is "random", so it cannot be used to determine the direction of the track */ |
3073 SetSignalsOnBothDir(v->tile, 0); |
3133 UpdateSignalsOnSegment(v->tile, dir); |
3074 SetSignalsOnBothDir(endtile, 0); |
3134 UpdateSignalsOnSegment(endtile, ReverseDiagDir(dir)); |
3075 break; |
|
3076 |
|
3077 case 3: |
|
3078 case 7: |
|
3079 SetSignalsOnBothDir(v->tile, 1); |
|
3080 SetSignalsOnBothDir(endtile, 1); |
|
3081 break; |
|
3082 |
|
3083 default: |
|
3084 break; |
|
3085 } |
|
3086 } |
3135 } |
3087 } |
3136 } |
3088 |
3137 |
3089 static void ChangeTrainDirRandomly(Vehicle *v) |
3138 static void ChangeTrainDirRandomly(Vehicle *v) |
3090 { |
3139 { |