75 * 11uuuudd => rail depot |
77 * 11uuuudd => rail depot |
76 */ |
78 */ |
77 |
79 |
78 static bool CheckTrackCombination(TileIndex tile, TrackBits to_build, uint flags) |
80 static bool CheckTrackCombination(TileIndex tile, TrackBits to_build, uint flags) |
79 { |
81 { |
80 TrackBits current; /* The current track layout */ |
82 TrackBits current; // The current track layout |
81 TrackBits future; /* The track layout we want to build */ |
83 TrackBits future; // The track layout we want to build |
82 _error_message = STR_1001_IMPOSSIBLE_TRACK_COMBINATION; |
84 _error_message = STR_1001_IMPOSSIBLE_TRACK_COMBINATION; |
83 |
85 |
84 if (!IsPlainRailTile(tile)) return false; |
86 if (!IsPlainRailTile(tile)) return false; |
85 |
87 |
86 /* So, we have a tile with tracks on it (and possibly signals). Let's see |
88 /* So, we have a tile with tracks on it (and possibly signals). Let's see |
188 |
190 |
189 |
191 |
190 static uint32 CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile) |
192 static uint32 CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile) |
191 { |
193 { |
192 if (IsSteepSlope(tileh)) { |
194 if (IsSteepSlope(tileh)) { |
193 if (existing == 0) { |
195 if (_patches.build_on_slopes && existing == 0) { |
194 TrackBits valid = TRACK_BIT_CROSS | (HASBIT(1 << SLOPE_STEEP_W | 1 << SLOPE_STEEP_E, tileh) ? TRACK_BIT_VERT : TRACK_BIT_HORZ); |
196 TrackBits valid = TRACK_BIT_CROSS | (HASBIT(1 << SLOPE_STEEP_W | 1 << SLOPE_STEEP_E, tileh) ? TRACK_BIT_VERT : TRACK_BIT_HORZ); |
195 if (valid & rail_bits) return _price.terraform; |
197 if (valid & rail_bits) return _price.terraform; |
196 } |
198 } |
197 } else { |
199 } else { |
198 rail_bits |= existing; |
200 rail_bits |= existing; |
199 |
201 |
200 // don't allow building on the lower side of a coast |
202 /* don't allow building on the lower side of a coast */ |
201 if (IsTileType(tile, MP_WATER) && |
203 if (IsTileType(tile, MP_WATER) && |
202 ~_valid_tileh_slopes[1][tileh] & rail_bits) { |
204 ~_valid_tileh_slopes[1][tileh] & rail_bits) { |
203 return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER); |
205 return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER); |
204 } |
206 } |
205 |
207 |
206 // no special foundation |
208 /* no special foundation */ |
207 if ((~_valid_tileh_slopes[0][tileh] & rail_bits) == 0) |
209 if ((~_valid_tileh_slopes[0][tileh] & rail_bits) == 0) |
208 return 0; |
210 return 0; |
209 |
211 |
210 if ((~_valid_tileh_slopes[1][tileh] & rail_bits) == 0 || ( // whole tile is leveled up |
212 if ((~_valid_tileh_slopes[1][tileh] & rail_bits) == 0 || ( // whole tile is leveled up |
211 (rail_bits == TRACK_BIT_X || rail_bits == TRACK_BIT_Y) && |
213 (rail_bits == TRACK_BIT_X || rail_bits == TRACK_BIT_Y) && |
226 /* Validate functions for rail building */ |
228 /* Validate functions for rail building */ |
227 static inline bool ValParamTrackOrientation(Track track) {return IsValidTrack(track);} |
229 static inline bool ValParamTrackOrientation(Track track) {return IsValidTrack(track);} |
228 |
230 |
229 /** Build a single piece of rail |
231 /** Build a single piece of rail |
230 * @param tile tile to build on |
232 * @param tile tile to build on |
|
233 * @param flags operation to perform |
231 * @param p1 railtype of being built piece (normal, mono, maglev) |
234 * @param p1 railtype of being built piece (normal, mono, maglev) |
232 * @param p2 rail track to build |
235 * @param p2 rail track to build |
233 */ |
236 */ |
234 int32 CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
237 int32 CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
235 { |
238 { |
250 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); |
253 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); |
251 |
254 |
252 switch (GetTileType(tile)) { |
255 switch (GetTileType(tile)) { |
253 case MP_RAILWAY: |
256 case MP_RAILWAY: |
254 if (!CheckTrackCombination(tile, trackbit, flags) || |
257 if (!CheckTrackCombination(tile, trackbit, flags) || |
255 !EnsureNoVehicle(tile)) { |
258 !EnsureNoVehicleOnGround(tile)) { |
256 return CMD_ERROR; |
259 return CMD_ERROR; |
257 } |
260 } |
258 if (!IsTileOwner(tile, _current_player) || |
261 if (!IsTileOwner(tile, _current_player) || |
259 !IsCompatibleRail(GetRailType(tile), railtype)) { |
262 !IsCompatibleRail(GetRailType(tile), railtype)) { |
260 // Get detailed error message |
263 /* Get detailed error message */ |
261 return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
264 return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
262 } |
265 } |
263 |
266 |
264 ret = CheckRailSlope(tileh, trackbit, GetTrackBits(tile), tile); |
267 ret = CheckRailSlope(tileh, trackbit, GetTrackBits(tile), tile); |
265 if (CmdFailed(ret)) return ret; |
268 if (CmdFailed(ret)) return ret; |
285 if (!HASBIT(M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT), tileh)) { |
288 if (!HASBIT(M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT), tileh)) { |
286 return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION); |
289 return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION); |
287 } |
290 } |
288 #undef M |
291 #undef M |
289 |
292 |
290 if (!EnsureNoVehicle(tile)) return CMD_ERROR; |
293 if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR; |
291 |
294 |
292 if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) { |
295 if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) { |
293 if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS); |
296 if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS); |
294 |
297 |
295 if ((track == TRACK_X && GetRoadBits(tile) == ROAD_Y) || |
298 RoadTypes roadtypes = GetRoadTypes(tile); |
296 (track == TRACK_Y && GetRoadBits(tile) == ROAD_X)) { |
299 RoadBits road = GetRoadBits(tile, ROADTYPE_ROAD); |
|
300 RoadBits tram = GetRoadBits(tile, ROADTYPE_TRAM); |
|
301 switch (roadtypes) { |
|
302 default: break; |
|
303 case ROADTYPES_TRAM: |
|
304 /* Tram crossings must always have road. */ |
|
305 SetRoadOwner(tile, ROADTYPE_ROAD, _current_player); |
|
306 roadtypes |= ROADTYPES_ROAD; |
|
307 break; |
|
308 |
|
309 case ROADTYPES_ROADTRAM: if (road == tram) break; |
|
310 /* FALL THROUGH */ |
|
311 case ROADTYPES_ROADHWAY: // Road and highway are incompatible in this case |
|
312 case ROADTYPES_TRAMHWAY: // Tram and highway are incompatible in this case |
|
313 case ROADTYPES_ALL: // Also incompatible |
|
314 return CMD_ERROR; |
|
315 } |
|
316 |
|
317 road |= tram | GetRoadBits(tile, ROADTYPE_HWAY); |
|
318 |
|
319 if ((track == TRACK_X && road == ROAD_Y) || |
|
320 (track == TRACK_Y && road == ROAD_X)) { |
297 if (flags & DC_EXEC) { |
321 if (flags & DC_EXEC) { |
298 MakeRoadCrossing(tile, GetTileOwner(tile), _current_player, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, GetTownIndex(tile)); |
322 MakeRoadCrossing(tile, GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY), _current_player, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, roadtypes, GetTownIndex(tile)); |
299 } |
323 } |
300 break; |
324 break; |
301 } |
325 } |
302 } |
326 } |
303 |
327 |
348 switch (GetTileType(tile)) { |
373 switch (GetTileType(tile)) { |
349 case MP_STREET: { |
374 case MP_STREET: { |
350 if (!IsLevelCrossing(tile) || |
375 if (!IsLevelCrossing(tile) || |
351 GetCrossingRailBits(tile) != trackbit || |
376 GetCrossingRailBits(tile) != trackbit || |
352 (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) || |
377 (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) || |
353 !EnsureNoVehicle(tile)) { |
378 !EnsureNoVehicleOnGround(tile)) { |
354 return CMD_ERROR; |
379 return CMD_ERROR; |
355 } |
380 } |
356 |
381 |
357 if (flags & DC_EXEC) { |
382 if (flags & DC_EXEC) { |
358 MakeRoadNormal(tile, GetCrossingRoadOwner(tile), GetCrossingRoadBits(tile), GetTownIndex(tile)); |
383 MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypes(tile), GetTownIndex(tile), GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY)); |
359 } |
384 } |
360 break; |
385 break; |
361 } |
386 } |
362 |
387 |
363 case MP_RAILWAY: { |
388 case MP_RAILWAY: { |
364 TrackBits present; |
389 TrackBits present; |
365 |
390 |
366 if (!IsPlainRailTile(tile) || |
391 if (!IsPlainRailTile(tile) || |
367 (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) || |
392 (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) || |
368 !EnsureNoVehicle(tile)) { |
393 !EnsureNoVehicleOnGround(tile)) { |
369 return CMD_ERROR; |
394 return CMD_ERROR; |
370 } |
395 } |
371 |
396 |
372 present = GetTrackBits(tile); |
397 present = GetTrackBits(tile); |
373 if ((present & trackbit) == 0) return CMD_ERROR; |
398 if ((present & trackbit) == 0) return CMD_ERROR; |
430 int ey = TileY(end); |
455 int ey = TileY(end); |
431 int dx, dy, trdx, trdy; |
456 int dx, dy, trdx, trdy; |
432 |
457 |
433 if (!ValParamTrackOrientation(TrackdirToTrack(*trackdir))) return CMD_ERROR; |
458 if (!ValParamTrackOrientation(TrackdirToTrack(*trackdir))) return CMD_ERROR; |
434 |
459 |
435 // calculate delta x,y from start to end tile |
460 /* calculate delta x,y from start to end tile */ |
436 dx = ex - x; |
461 dx = ex - x; |
437 dy = ey - y; |
462 dy = ey - y; |
438 |
463 |
439 // calculate delta x,y for the first direction |
464 /* calculate delta x,y for the first direction */ |
440 trdx = _trackdelta[*trackdir].x; |
465 trdx = _trackdelta[*trackdir].x; |
441 trdy = _trackdelta[*trackdir].y; |
466 trdy = _trackdelta[*trackdir].y; |
442 |
467 |
443 if (!IsDiagonalTrackdir(*trackdir)) { |
468 if (!IsDiagonalTrackdir(*trackdir)) { |
444 trdx += _trackdelta[*trackdir ^ 1].x; |
469 trdx += _trackdelta[*trackdir ^ 1].x; |
445 trdy += _trackdelta[*trackdir ^ 1].y; |
470 trdy += _trackdelta[*trackdir ^ 1].y; |
446 } |
471 } |
447 |
472 |
448 // validate the direction |
473 /* validate the direction */ |
449 while ( |
474 while ( |
450 (trdx <= 0 && dx > 0) || |
475 (trdx <= 0 && dx > 0) || |
451 (trdx >= 0 && dx < 0) || |
476 (trdx >= 0 && dx < 0) || |
452 (trdy <= 0 && dy > 0) || |
477 (trdy <= 0 && dy > 0) || |
453 (trdy >= 0 && dy < 0) |
478 (trdy >= 0 && dy < 0) |
459 } else { // other direction is invalid too, invalid drag |
484 } else { // other direction is invalid too, invalid drag |
460 return CMD_ERROR; |
485 return CMD_ERROR; |
461 } |
486 } |
462 } |
487 } |
463 |
488 |
464 // (for diagonal tracks, this is already made sure of by above test), but: |
489 /* (for diagonal tracks, this is already made sure of by above test), but: |
465 // for non-diagonal tracks, check if the start and end tile are on 1 line |
490 * for non-diagonal tracks, check if the start and end tile are on 1 line */ |
466 if (!IsDiagonalTrackdir(*trackdir)) { |
491 if (!IsDiagonalTrackdir(*trackdir)) { |
467 trdx = _trackdelta[*trackdir].x; |
492 trdx = _trackdelta[*trackdir].x; |
468 trdy = _trackdelta[*trackdir].y; |
493 trdy = _trackdelta[*trackdir].y; |
469 if (abs(dx) != abs(dy) && abs(dx) + abs(trdy) != abs(dy) + abs(trdx)) |
494 if (abs(dx) != abs(dy) && abs(dx) + abs(trdy) != abs(dy) + abs(trdx)) |
470 return CMD_ERROR; |
495 return CMD_ERROR; |
473 return 0; |
498 return 0; |
474 } |
499 } |
475 |
500 |
476 /** Build a stretch of railroad tracks. |
501 /** Build a stretch of railroad tracks. |
477 * @param tile start tile of drag |
502 * @param tile start tile of drag |
|
503 * @param flags operation to perform |
478 * @param p1 end tile of drag |
504 * @param p1 end tile of drag |
479 * @param p2 various bitstuffed elements |
505 * @param p2 various bitstuffed elements |
480 * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev) |
506 * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev) |
481 * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum) |
507 * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum) |
482 * - p2 = (bit 7) - 0 = build, 1 = remove tracks |
508 * - p2 = (bit 7) - 0 = build, 1 = remove tracks |
513 |
539 |
514 if (tile == end_tile) break; |
540 if (tile == end_tile) break; |
515 |
541 |
516 tile += ToTileIndexDiff(_trackdelta[trackdir]); |
542 tile += ToTileIndexDiff(_trackdelta[trackdir]); |
517 |
543 |
518 // toggle railbit for the non-diagonal tracks |
544 /* toggle railbit for the non-diagonal tracks */ |
519 if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0); |
545 if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0); |
520 } |
546 } |
521 |
547 |
522 return (total_cost == 0) ? CMD_ERROR : total_cost; |
548 return (total_cost == 0) ? CMD_ERROR : total_cost; |
523 } |
549 } |
524 |
550 |
525 /** Build rail on a stretch of track. |
551 /** Build rail on a stretch of track. |
526 * Stub for the unified rail builder/remover |
552 * Stub for the unified rail builder/remover |
|
553 * @param tile start tile of drag |
|
554 * @param flags operation to perform |
|
555 * @param p1 end tile of drag |
|
556 * @param p2 various bitstuffed elements |
|
557 * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev) |
|
558 * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum) |
|
559 * - p2 = (bit 7) - 0 = build, 1 = remove tracks |
527 * @see CmdRailTrackHelper |
560 * @see CmdRailTrackHelper |
528 */ |
561 */ |
529 int32 CmdBuildRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
562 int32 CmdBuildRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
530 { |
563 { |
531 return CmdRailTrackHelper(tile, flags, p1, CLRBIT(p2, 7)); |
564 return CmdRailTrackHelper(tile, flags, p1, CLRBIT(p2, 7)); |
532 } |
565 } |
533 |
566 |
534 /** Build rail on a stretch of track. |
567 /** Build rail on a stretch of track. |
535 * Stub for the unified rail builder/remover |
568 * Stub for the unified rail builder/remover |
|
569 * @param tile start tile of drag |
|
570 * @param flags operation to perform |
|
571 * @param p1 end tile of drag |
|
572 * @param p2 various bitstuffed elements |
|
573 * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev) |
|
574 * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum) |
|
575 * - p2 = (bit 7) - 0 = build, 1 = remove tracks |
536 * @see CmdRailTrackHelper |
576 * @see CmdRailTrackHelper |
537 */ |
577 */ |
538 int32 CmdRemoveRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
578 int32 CmdRemoveRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
539 { |
579 { |
540 return CmdRailTrackHelper(tile, flags, p1, SETBIT(p2, 7)); |
580 return CmdRailTrackHelper(tile, flags, p1, SETBIT(p2, 7)); |
541 } |
581 } |
542 |
582 |
543 /** Build a train depot |
583 /** Build a train depot |
544 * @param tile position of the train depot |
584 * @param tile position of the train depot |
|
585 * @param flags operation to perform |
545 * @param p1 rail type |
586 * @param p1 rail type |
546 * @param p2 bit 0..1 entrance direction (DiagDirection) |
587 * @param p2 bit 0..1 entrance direction (DiagDirection) |
547 * |
588 * |
548 * @todo When checking for the tile slope, |
589 * @todo When checking for the tile slope, |
549 * distingush between "Flat land required" and "land sloped in wrong direction" |
590 * distingush between "Flat land required" and "land sloped in wrong direction" |
605 |
646 |
606 /** Build signals, alternate between double/single, signal/semaphore, |
647 /** Build signals, alternate between double/single, signal/semaphore, |
607 * pre/exit/combo-signals, and what-else not. If the rail piece does not |
648 * pre/exit/combo-signals, and what-else not. If the rail piece does not |
608 * have any signals, bit 4 (cycle signal-type) is ignored |
649 * have any signals, bit 4 (cycle signal-type) is ignored |
609 * @param tile tile where to build the signals |
650 * @param tile tile where to build the signals |
|
651 * @param flags operation to perform |
610 * @param p1 various bitstuffed elements |
652 * @param p1 various bitstuffed elements |
611 * - p1 = (bit 0-2) - track-orientation, valid values: 0-5 (Track enum) |
653 * - p1 = (bit 0-2) - track-orientation, valid values: 0-5 (Track enum) |
612 * - p1 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) |
654 * - p1 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) |
613 * - p1 = (bit 4) - 0 = signals, 1 = semaphores |
655 * - p1 = (bit 4) - 0 = signals, 1 = semaphores |
614 * @param p2 used for CmdBuildManySignals() to copy direction of first signal |
656 * @param p2 used for CmdBuildManySignals() to copy direction of first signal |
619 Track track = (Track)GB(p1, 0, 3); |
661 Track track = (Track)GB(p1, 0, 3); |
620 bool pre_signal = HASBIT(p1, 3); |
662 bool pre_signal = HASBIT(p1, 3); |
621 SignalVariant sigvar = (pre_signal ^ HASBIT(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC; |
663 SignalVariant sigvar = (pre_signal ^ HASBIT(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC; |
622 int32 cost; |
664 int32 cost; |
623 |
665 |
624 if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicle(tile)) |
666 if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicleOnGround(tile)) |
625 return CMD_ERROR; |
667 return CMD_ERROR; |
626 |
668 |
627 /* Protect against invalid signal copying */ |
669 /* Protect against invalid signal copying */ |
628 if (p2 != 0 && (p2 & SignalOnTrack(track)) == 0) return CMD_ERROR; |
670 if (p2 != 0 && (p2 & SignalOnTrack(track)) == 0) return CMD_ERROR; |
629 |
671 |
645 } |
687 } |
646 |
688 |
647 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); |
689 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); |
648 |
690 |
649 if (!HasSignalOnTrack(tile, track)) { |
691 if (!HasSignalOnTrack(tile, track)) { |
650 // build new signals |
692 /* build new signals */ |
651 cost = _price.build_signals; |
693 cost = _price.build_signals; |
652 } else { |
694 } else { |
653 if (p2 != 0 && sigvar != GetSignalVariant(tile)) { |
695 if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) { |
654 // convert signals <-> semaphores |
696 /* convert signals <-> semaphores */ |
655 cost = _price.build_signals + _price.remove_signals; |
697 cost = _price.build_signals + _price.remove_signals; |
656 } else { |
698 } else { |
657 // it is free to change orientation/pre-exit-combo signals |
699 /* it is free to change orientation/pre-exit-combo signals */ |
658 cost = 0; |
700 cost = 0; |
659 } |
701 } |
660 } |
702 } |
661 |
703 |
662 if (flags & DC_EXEC) { |
704 if (flags & DC_EXEC) { |
663 if (!HasSignals(tile)) { |
705 if (!HasSignals(tile)) { |
664 // there are no signals at all on this tile yet |
706 /* there are no signals at all on this tile yet */ |
665 SetHasSignals(tile, true); |
707 SetHasSignals(tile, true); |
666 _m[tile].m2 |= 0xF0; // all signals are on |
708 SetSignalStates(tile, 0xF); // all signals are on |
667 _m[tile].m3 &= ~0xF0; // no signals built by default |
709 SetPresentSignals(tile, 0); // no signals built by default |
668 SetSignalType(tile, SIGTYPE_NORMAL); |
710 SetSignalType(tile, track, SIGTYPE_NORMAL); |
669 SetSignalVariant(tile, sigvar); |
711 SetSignalVariant(tile, track, sigvar); |
670 } |
712 } |
671 |
713 |
672 if (p2 == 0) { |
714 if (p2 == 0) { |
673 if (!HasSignalOnTrack(tile, track)) { |
715 if (!HasSignalOnTrack(tile, track)) { |
674 // build new signals |
716 /* build new signals */ |
675 _m[tile].m3 |= SignalOnTrack(track); |
717 SetPresentSignals(tile, GetPresentSignals(tile) | SignalOnTrack(track)); |
|
718 SetSignalType(tile, track, SIGTYPE_NORMAL); |
|
719 SetSignalVariant(tile, track, sigvar); |
676 } else { |
720 } else { |
677 if (pre_signal) { |
721 if (pre_signal) { |
678 // cycle between normal -> pre -> exit -> combo -> ... |
722 /* cycle between normal -> pre -> exit -> combo -> ... */ |
679 SignalType type = GetSignalType(tile); |
723 SignalType type = GetSignalType(tile, track); |
680 |
724 |
681 SetSignalType(tile, type == SIGTYPE_COMBO ? SIGTYPE_NORMAL : (SignalType)(type + 1)); |
725 SetSignalType(tile, track, type == SIGTYPE_COMBO ? SIGTYPE_NORMAL : (SignalType)(type + 1)); |
682 } else { |
726 } else { |
683 CycleSignalSide(tile, track); |
727 CycleSignalSide(tile, track); |
684 } |
728 } |
685 } |
729 } |
686 } else { |
730 } else { |
687 /* If CmdBuildManySignals is called with copying signals, just copy the |
731 /* If CmdBuildManySignals is called with copying signals, just copy the |
688 * direction of the first signal given as parameter by CmdBuildManySignals */ |
732 * direction of the first signal given as parameter by CmdBuildManySignals */ |
689 _m[tile].m3 &= ~SignalOnTrack(track); |
733 SetPresentSignals(tile, (GetPresentSignals(tile) & ~SignalOnTrack(track)) | (p2 & SignalOnTrack(track))); |
690 _m[tile].m3 |= p2 & SignalOnTrack(track); |
734 SetSignalVariant(tile, track, sigvar); |
691 SetSignalVariant(tile, sigvar); |
|
692 } |
735 } |
693 |
736 |
694 MarkTileDirtyByTile(tile); |
737 MarkTileDirtyByTile(tile); |
695 SetSignalsOnBothDir(tile, track); |
738 SetSignalsOnBothDir(tile, track); |
696 YapfNotifyTrackLayoutChange(tile, track); |
739 YapfNotifyTrackLayoutChange(tile, track); |
699 return cost; |
742 return cost; |
700 } |
743 } |
701 |
744 |
702 /** Build many signals by dragging; AutoSignals |
745 /** Build many signals by dragging; AutoSignals |
703 * @param tile start tile of drag |
746 * @param tile start tile of drag |
|
747 * @param flags operation to perform |
704 * @param p1 end tile of drag |
748 * @param p1 end tile of drag |
705 * @param p2 various bitstuffed elements |
749 * @param p2 various bitstuffed elements |
706 * - p2 = (bit 0- 2) - track-orientation, valid values: 0-5 (Track enum) |
750 * - p2 = (bit 0- 2) - track-orientation, valid values: 0-5 (Track enum) |
707 * - p2 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) |
751 * - p2 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) |
708 * - p2 = (bit 4) - 0 = signals, 1 = semaphores |
752 * - p2 = (bit 4) - 0 = signals, 1 = semaphores |
737 |
781 |
738 if (CmdFailed(ValidateAutoDrag(&trackdir, tile, end_tile))) return CMD_ERROR; |
782 if (CmdFailed(ValidateAutoDrag(&trackdir, tile, end_tile))) return CMD_ERROR; |
739 |
783 |
740 track = TrackdirToTrack(trackdir); /* trackdir might have changed, keep track in sync */ |
784 track = TrackdirToTrack(trackdir); /* trackdir might have changed, keep track in sync */ |
741 |
785 |
742 // copy the signal-style of the first rail-piece if existing |
786 /* copy the signal-style of the first rail-piece if existing */ |
743 if (HasSignals(tile)) { |
787 if (HasSignals(tile)) { |
744 signals = _m[tile].m3 & SignalOnTrack(track); |
788 signals = GetPresentSignals(tile) & SignalOnTrack(track); |
745 if (signals == 0) signals = SignalOnTrack(track); /* Can this actually occur? */ |
789 if (signals == 0) signals = SignalOnTrack(track); /* Can this actually occur? */ |
746 |
790 |
747 // copy signal/semaphores style (independent of CTRL) |
791 /* copy signal/semaphores style (independent of CTRL) */ |
748 semaphores = GetSignalVariant(tile) != SIG_ELECTRIC; |
792 semaphores = GetSignalVariant(tile, track) != SIG_ELECTRIC; |
749 } else { // no signals exist, drag a two-way signal stretch |
793 } else { // no signals exist, drag a two-way signal stretch |
750 signals = SignalOnTrack(track); |
794 signals = SignalOnTrack(track); |
751 } |
795 } |
752 |
796 |
753 /* signal_ctr - amount of tiles already processed |
797 /* signal_ctr - amount of tiles already processed |
758 * signals - is there a signal/semaphore on the first tile, copy its style (two-way/single-way) |
802 * signals - is there a signal/semaphore on the first tile, copy its style (two-way/single-way) |
759 * and convert all others to semaphore/signal |
803 * and convert all others to semaphore/signal |
760 * remove - 1 remove signals, 0 build signals */ |
804 * remove - 1 remove signals, 0 build signals */ |
761 signal_ctr = total_cost = 0; |
805 signal_ctr = total_cost = 0; |
762 for (;;) { |
806 for (;;) { |
763 // only build/remove signals with the specified density |
807 /* only build/remove signals with the specified density */ |
764 if (signal_ctr % signal_density == 0) { |
808 if (signal_ctr % signal_density == 0) { |
765 uint32 p1 = GB(TrackdirToTrack(trackdir), 0, 3); |
809 uint32 p1 = GB(TrackdirToTrack(trackdir), 0, 3); |
766 SB(p1, 3, 1, mode); |
810 SB(p1, 3, 1, mode); |
767 SB(p1, 4, 1, semaphores); |
811 SB(p1, 4, 1, semaphores); |
768 ret = DoCommand(tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS); |
812 ret = DoCommand(tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS); |
777 if (tile == end_tile) break; |
821 if (tile == end_tile) break; |
778 |
822 |
779 tile += ToTileIndexDiff(_trackdelta[trackdir]); |
823 tile += ToTileIndexDiff(_trackdelta[trackdir]); |
780 signal_ctr++; |
824 signal_ctr++; |
781 |
825 |
782 // toggle railbit for the non-diagonal tracks (|, -- tracks) |
826 /* toggle railbit for the non-diagonal tracks (|, -- tracks) */ |
783 if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0); |
827 if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0); |
784 } |
828 } |
785 |
829 |
786 return error ? CMD_ERROR : total_cost; |
830 return error ? CMD_ERROR : total_cost; |
787 } |
831 } |
788 |
832 |
789 /** Build signals on a stretch of track. |
833 /** Build signals on a stretch of track. |
790 * Stub for the unified signal builder/remover |
834 * Stub for the unified signal builder/remover |
|
835 * @param tile start tile of drag |
|
836 * @param flags operation to perform |
|
837 * @param p1 end tile of drag |
|
838 * @param p2 various bitstuffed elements |
|
839 * - p2 = (bit 0- 2) - track-orientation, valid values: 0-5 (Track enum) |
|
840 * - p2 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) |
|
841 * - p2 = (bit 4) - 0 = signals, 1 = semaphores |
|
842 * - p2 = (bit 5) - 0 = build, 1 = remove signals |
|
843 * - p2 = (bit 24-31) - user defined signals_density |
791 * @see CmdSignalTrackHelper |
844 * @see CmdSignalTrackHelper |
792 */ |
845 */ |
793 int32 CmdBuildSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
846 int32 CmdBuildSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
794 { |
847 { |
795 return CmdSignalTrackHelper(tile, flags, p1, p2); |
848 return CmdSignalTrackHelper(tile, flags, p1, p2); |
796 } |
849 } |
797 |
850 |
798 /** Remove signals |
851 /** Remove signals |
799 * @param tile coordinates where signal is being deleted from |
852 * @param tile coordinates where signal is being deleted from |
800 * @param various bitstuffed elements, only track information is used |
853 * @param flags operation to perform |
801 * - p1 = (bit 0- 2) - track-orientation, valid values: 0-5 (Track enum) |
854 * @param p1 various bitstuffed elements, only track information is used |
802 * - p1 = (bit 3) - override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) |
855 * - (bit 0- 2) - track-orientation, valid values: 0-5 (Track enum) |
803 * - p1 = (bit 4) - 0 = signals, 1 = semaphores |
856 * - (bit 3) - override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) |
|
857 * - (bit 4) - 0 = signals, 1 = semaphores |
|
858 * @param p2 unused |
804 */ |
859 */ |
805 int32 CmdRemoveSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
860 int32 CmdRemoveSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
806 { |
861 { |
807 Track track = (Track)GB(p1, 0, 3); |
862 Track track = (Track)GB(p1, 0, 3); |
808 |
863 |
809 if (!ValParamTrackOrientation(track) || |
864 if (!ValParamTrackOrientation(track) || |
810 !IsTileType(tile, MP_RAILWAY) || |
865 !IsTileType(tile, MP_RAILWAY) || |
811 !EnsureNoVehicle(tile) || |
866 !EnsureNoVehicleOnGround(tile) || |
812 !HasSignalOnTrack(tile, track)) { |
867 !HasSignalOnTrack(tile, track)) { |
813 return CMD_ERROR; |
868 return CMD_ERROR; |
814 } |
869 } |
815 |
870 |
816 /* Only water can remove signals from anyone */ |
871 /* Only water can remove signals from anyone */ |
818 |
873 |
819 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); |
874 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); |
820 |
875 |
821 /* Do it? */ |
876 /* Do it? */ |
822 if (flags & DC_EXEC) { |
877 if (flags & DC_EXEC) { |
823 _m[tile].m3 &= ~SignalOnTrack(track); |
878 SetPresentSignals(tile, GetPresentSignals(tile) & ~SignalOnTrack(track)); |
824 |
879 |
825 /* removed last signal from tile? */ |
880 /* removed last signal from tile? */ |
826 if (GB(_m[tile].m3, 4, 4) == 0) { |
881 if (GetPresentSignals(tile) == 0) { |
827 SB(_m[tile].m2, 4, 4, 0); |
882 SetSignalStates(tile, 0); |
828 SetHasSignals(tile, false); |
883 SetHasSignals(tile, false); |
829 SetSignalVariant(tile, SIG_ELECTRIC); // remove any possible semaphores |
884 SetSignalVariant(tile, INVALID_TRACK, SIG_ELECTRIC); // remove any possible semaphores |
830 } |
885 } |
831 |
886 |
832 SetSignalsOnBothDir(tile, track); |
887 SetSignalsOnBothDir(tile, track); |
833 YapfNotifyTrackLayoutChange(tile, track); |
888 YapfNotifyTrackLayoutChange(tile, track); |
834 |
889 |
838 return _price.remove_signals; |
893 return _price.remove_signals; |
839 } |
894 } |
840 |
895 |
841 /** Remove signals on a stretch of track. |
896 /** Remove signals on a stretch of track. |
842 * Stub for the unified signal builder/remover |
897 * Stub for the unified signal builder/remover |
|
898 * @param tile start tile of drag |
|
899 * @param flags operation to perform |
|
900 * @param p1 end tile of drag |
|
901 * @param p2 various bitstuffed elements |
|
902 * - p2 = (bit 0- 2) - track-orientation, valid values: 0-5 (Track enum) |
|
903 * - p2 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) |
|
904 * - p2 = (bit 4) - 0 = signals, 1 = semaphores |
|
905 * - p2 = (bit 5) - 0 = build, 1 = remove signals |
|
906 * - p2 = (bit 24-31) - user defined signals_density |
843 * @see CmdSignalTrackHelper |
907 * @see CmdSignalTrackHelper |
844 */ |
908 */ |
845 int32 CmdRemoveSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
909 int32 CmdRemoveSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
846 { |
910 { |
847 return CmdSignalTrackHelper(tile, flags, p1, SETBIT(p2, 5)); // bit 5 is remove bit |
911 return CmdSignalTrackHelper(tile, flags, p1, SETBIT(p2, 5)); // bit 5 is remove bit |
863 { |
927 { |
864 if (!CheckTileOwnership(tile)) return CMD_ERROR; |
928 if (!CheckTileOwnership(tile)) return CMD_ERROR; |
865 |
929 |
866 if (GetRailType(tile) == totype) return CMD_ERROR; |
930 if (GetRailType(tile) == totype) return CMD_ERROR; |
867 |
931 |
868 if (!EnsureNoVehicle(tile) && (!IsCompatibleRail(GetRailType(tile), totype) || IsPlainRailTile(tile))) return CMD_ERROR; |
932 if (!EnsureNoVehicleOnGround(tile) && (!IsCompatibleRail(GetRailType(tile), totype) || IsPlainRailTile(tile))) return CMD_ERROR; |
869 |
933 |
870 // 'hidden' elrails can't be downgraded to normal rail when elrails are disabled |
934 /* 'hidden' elrails can't be downgraded to normal rail when elrails are disabled */ |
871 if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR; |
935 if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR; |
872 |
936 |
873 // change type. |
937 /* change type. */ |
874 if (exec) { |
938 if (exec) { |
875 SetRailType(tile, totype); |
939 SetRailType(tile, totype); |
876 MarkTileDirtyByTile(tile); |
940 MarkTileDirtyByTile(tile); |
877 |
941 |
878 // notify YAPF about the track layout change |
942 /* notify YAPF about the track layout change */ |
879 TrackBits tracks = GetTrackBits(tile); |
943 TrackBits tracks = GetTrackBits(tile); |
880 while (tracks != TRACK_BIT_NONE) { |
944 while (tracks != TRACK_BIT_NONE) { |
881 YapfNotifyTrackLayoutChange(tile, RemoveFirstTrack(&tracks)); |
945 YapfNotifyTrackLayoutChange(tile, RemoveFirstTrack(&tracks)); |
882 } |
946 } |
883 |
947 |
904 extern int32 DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec); |
968 extern int32 DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec); |
905 |
969 |
906 /** Convert one rail type to the other. You can convert normal rail to |
970 /** Convert one rail type to the other. You can convert normal rail to |
907 * monorail/maglev easily or vice-versa. |
971 * monorail/maglev easily or vice-versa. |
908 * @param tile end tile of rail conversion drag |
972 * @param tile end tile of rail conversion drag |
|
973 * @param flags operation to perform |
909 * @param p1 start tile of drag |
974 * @param p1 start tile of drag |
910 * @param p2 new railtype to convert to |
975 * @param p2 new railtype to convert to |
911 */ |
976 */ |
912 int32 CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
977 int32 CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
913 { |
978 { |
1062 SpriteID sprite; |
1127 SpriteID sprite; |
1063 |
1128 |
1064 /* _signal_base is set by our NewGRF Action 5 loader. If it is 0 then we |
1129 /* _signal_base is set by our NewGRF Action 5 loader. If it is 0 then we |
1065 * just draw the standard signals, else we get the offset from _signal_base |
1130 * just draw the standard signals, else we get the offset from _signal_base |
1066 * and draw that sprite. All the signal sprites are loaded sequentially. */ |
1131 * and draw that sprite. All the signal sprites are loaded sequentially. */ |
1067 if (_signal_base == 0 || (GetSignalType(tile) == 0 && GetSignalVariant(tile) == SIG_ELECTRIC)) { |
1132 if (_signal_base == 0 || (GetSignalType(tile, track) == SIGTYPE_NORMAL && GetSignalVariant(tile, track) == SIG_ELECTRIC)) { |
1068 sprite = SignalBase[side][GetSignalVariant(tile)][GetSignalType(tile)] + image + condition; |
1133 sprite = SignalBase[side][GetSignalVariant(tile, track)][GetSignalType(tile, track)] + image + condition; |
1069 } else { |
1134 } else { |
1070 sprite = _signal_base + (GetSignalType(tile) - 1) * 16 + GetSignalVariant(tile) * 64 + image + condition; |
1135 sprite = _signal_base + (GetSignalType(tile, track) - 1) * 16 + GetSignalVariant(tile, track) * 64 + image + condition; |
1071 } |
1136 } |
1072 |
1137 |
1073 AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, 10, GetSlopeZ(x,y)); |
1138 AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, 10, GetSlopeZ(x,y)); |
1074 } |
1139 } |
1075 |
1140 |
1173 |
1238 |
1174 /** |
1239 /** |
1175 * Draw ground sprite and track bits |
1240 * Draw ground sprite and track bits |
1176 * @param ti TileInfo |
1241 * @param ti TileInfo |
1177 * @param track TrackBits to draw |
1242 * @param track TrackBits to draw |
1178 * @param earth Draw as earth |
|
1179 * @param snow Draw as snow |
|
1180 * @param flat Always draw foundation |
|
1181 */ |
1243 */ |
1182 static void DrawTrackBits(TileInfo* ti, TrackBits track) |
1244 static void DrawTrackBits(TileInfo* ti, TrackBits track) |
1183 { |
1245 { |
1184 const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); |
1246 const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); |
1185 SpriteID image; |
1247 SpriteID image; |
1186 SpriteID pal = PAL_NONE; |
1248 SpriteID pal = PAL_NONE; |
1187 bool junction = false; |
1249 bool junction = false; |
1188 |
1250 |
1189 // Select the sprite to use. |
1251 /* Select the sprite to use. */ |
1190 (image = rti->base_sprites.track_y, track == TRACK_BIT_Y) || |
1252 (image = rti->base_sprites.track_y, track == TRACK_BIT_Y) || |
1191 (image++, track == TRACK_BIT_X) || |
1253 (image++, track == TRACK_BIT_X) || |
1192 (image++, track == TRACK_BIT_UPPER) || |
1254 (image++, track == TRACK_BIT_UPPER) || |
1193 (image++, track == TRACK_BIT_LOWER) || |
1255 (image++, track == TRACK_BIT_LOWER) || |
1194 (image++, track == TRACK_BIT_RIGHT) || |
1256 (image++, track == TRACK_BIT_RIGHT) || |
1208 if (ti->tileh != SLOPE_FLAT) { |
1270 if (ti->tileh != SLOPE_FLAT) { |
1209 uint foundation = GetRailFoundation(ti->tileh, track); |
1271 uint foundation = GetRailFoundation(ti->tileh, track); |
1210 |
1272 |
1211 if (foundation != 0) DrawFoundation(ti, foundation); |
1273 if (foundation != 0) DrawFoundation(ti, foundation); |
1212 |
1274 |
1213 // DrawFoundation() modifies ti. |
1275 /* DrawFoundation() modifies it. |
1214 // Default sloped sprites.. |
1276 * Default sloped sprites.. */ |
1215 if (ti->tileh != SLOPE_FLAT) |
1277 if (ti->tileh != SLOPE_FLAT) |
1216 image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y; |
1278 image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y; |
1217 } |
1279 } |
1218 |
1280 |
1219 switch (GetRailGroundType(ti->tile)) { |
1281 switch (GetRailGroundType(ti->tile)) { |
1222 default: break; |
1284 default: break; |
1223 } |
1285 } |
1224 |
1286 |
1225 DrawGroundSprite(image, pal); |
1287 DrawGroundSprite(image, pal); |
1226 |
1288 |
1227 // Draw track pieces individually for junction tiles |
1289 /* Draw track pieces individually for junction tiles */ |
1228 if (junction) { |
1290 if (junction) { |
1229 if (track & TRACK_BIT_X) DrawGroundSprite(rti->base_sprites.single_y, PAL_NONE); |
1291 if (track & TRACK_BIT_X) DrawGroundSprite(rti->base_sprites.single_y, PAL_NONE); |
1230 if (track & TRACK_BIT_Y) DrawGroundSprite(rti->base_sprites.single_x, PAL_NONE); |
1292 if (track & TRACK_BIT_Y) DrawGroundSprite(rti->base_sprites.single_x, PAL_NONE); |
1231 if (track & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n, PAL_NONE); |
1293 if (track & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n, PAL_NONE); |
1232 if (track & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s, PAL_NONE); |
1294 if (track & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s, PAL_NONE); |
1238 |
1300 |
1239 } |
1301 } |
1240 |
1302 |
1241 static void DrawSignals(TileIndex tile, TrackBits rails) |
1303 static void DrawSignals(TileIndex tile, TrackBits rails) |
1242 { |
1304 { |
1243 #define MAYBE_DRAW_SIGNAL(x,y,z) if (IsSignalPresent(tile, x)) DrawSingleSignal(tile, GetSingleSignalState(tile, x), y - 0x4FB, z) |
1305 #define MAYBE_DRAW_SIGNAL(x,y,z,t) if (IsSignalPresent(tile, x)) DrawSingleSignal(tile, t, GetSingleSignalState(tile, x), y - 0x4FB, z) |
1244 |
1306 |
1245 if (!(rails & TRACK_BIT_Y)) { |
1307 if (!(rails & TRACK_BIT_Y)) { |
1246 if (!(rails & TRACK_BIT_X)) { |
1308 if (!(rails & TRACK_BIT_X)) { |
1247 if (rails & TRACK_BIT_LEFT) { |
1309 if (rails & TRACK_BIT_LEFT) { |
1248 MAYBE_DRAW_SIGNAL(2, 0x509, 0); |
1310 MAYBE_DRAW_SIGNAL(2, 0x509, 0, TRACK_LEFT); |
1249 MAYBE_DRAW_SIGNAL(3, 0x507, 1); |
1311 MAYBE_DRAW_SIGNAL(3, 0x507, 1, TRACK_LEFT); |
1250 } |
1312 } |
1251 if (rails & TRACK_BIT_RIGHT) { |
1313 if (rails & TRACK_BIT_RIGHT) { |
1252 MAYBE_DRAW_SIGNAL(0, 0x509, 2); |
1314 MAYBE_DRAW_SIGNAL(0, 0x509, 2, TRACK_RIGHT); |
1253 MAYBE_DRAW_SIGNAL(1, 0x507, 3); |
1315 MAYBE_DRAW_SIGNAL(1, 0x507, 3, TRACK_RIGHT); |
1254 } |
1316 } |
1255 if (rails & TRACK_BIT_UPPER) { |
1317 if (rails & TRACK_BIT_UPPER) { |
1256 MAYBE_DRAW_SIGNAL(3, 0x505, 4); |
1318 MAYBE_DRAW_SIGNAL(3, 0x505, 4, TRACK_UPPER); |
1257 MAYBE_DRAW_SIGNAL(2, 0x503, 5); |
1319 MAYBE_DRAW_SIGNAL(2, 0x503, 5, TRACK_UPPER); |
1258 } |
1320 } |
1259 if (rails & TRACK_BIT_LOWER) { |
1321 if (rails & TRACK_BIT_LOWER) { |
1260 MAYBE_DRAW_SIGNAL(1, 0x505, 6); |
1322 MAYBE_DRAW_SIGNAL(1, 0x505, 6, TRACK_LOWER); |
1261 MAYBE_DRAW_SIGNAL(0, 0x503, 7); |
1323 MAYBE_DRAW_SIGNAL(0, 0x503, 7, TRACK_LOWER); |
1262 } |
1324 } |
1263 } else { |
1325 } else { |
1264 MAYBE_DRAW_SIGNAL(3, 0x4FB, 8); |
1326 MAYBE_DRAW_SIGNAL(3, 0x4FB, 8, TRACK_X); |
1265 MAYBE_DRAW_SIGNAL(2, 0x4FD, 9); |
1327 MAYBE_DRAW_SIGNAL(2, 0x4FD, 9, TRACK_X); |
1266 } |
1328 } |
1267 } else { |
1329 } else { |
1268 MAYBE_DRAW_SIGNAL(3, 0x4FF, 10); |
1330 MAYBE_DRAW_SIGNAL(3, 0x4FF, 10, TRACK_Y); |
1269 MAYBE_DRAW_SIGNAL(2, 0x501, 11); |
1331 MAYBE_DRAW_SIGNAL(2, 0x501, 11, TRACK_Y); |
1270 } |
1332 } |
1271 } |
1333 } |
1272 |
1334 |
1273 static void DrawTile_Track(TileInfo *ti) |
1335 static void DrawTile_Track(TileInfo *ti) |
1274 { |
1336 { |
1280 if (IsPlainRailTile(ti->tile)) { |
1342 if (IsPlainRailTile(ti->tile)) { |
1281 TrackBits rails = GetTrackBits(ti->tile); |
1343 TrackBits rails = GetTrackBits(ti->tile); |
1282 |
1344 |
1283 DrawTrackBits(ti, rails); |
1345 DrawTrackBits(ti, rails); |
1284 |
1346 |
1285 if (_display_opt & DO_FULL_DETAIL) DrawTrackDetails(ti); |
1347 if (HASBIT(_display_opt, DO_FULL_DETAIL)) DrawTrackDetails(ti); |
1286 |
1348 |
1287 if (HasSignals(ti->tile)) DrawSignals(ti->tile, rails); |
1349 if (HasSignals(ti->tile)) DrawSignals(ti->tile, rails); |
1288 } else { |
1350 } else { |
1289 // draw depot/waypoint |
1351 /* draw depot/waypoint */ |
1290 const DrawTileSprites* dts; |
1352 const DrawTileSprites* dts; |
1291 const DrawTileSeqStruct* dtss; |
1353 const DrawTileSeqStruct* dtss; |
1292 uint32 relocation; |
1354 uint32 relocation; |
1293 |
1355 |
1294 if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh); |
1356 if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh); |
1299 relocation = rti->total_offset; |
1361 relocation = rti->total_offset; |
1300 |
1362 |
1301 image = dts->ground_sprite; |
1363 image = dts->ground_sprite; |
1302 if (image != SPR_FLAT_GRASS_TILE) image += rti->total_offset; |
1364 if (image != SPR_FLAT_GRASS_TILE) image += rti->total_offset; |
1303 |
1365 |
1304 // adjust ground tile for desert |
1366 /* adjust ground tile for desert |
1305 // don't adjust for snow, because snow in depots looks weird |
1367 * don't adjust for snow, because snow in depots looks weird */ |
1306 if (IsSnowRailGround(ti->tile) && _opt.landscape == LT_TROPIC) { |
1368 if (IsSnowRailGround(ti->tile) && _opt.landscape == LT_TROPIC) { |
1307 if (image != SPR_FLAT_GRASS_TILE) { |
1369 if (image != SPR_FLAT_GRASS_TILE) { |
1308 image += rti->snow_offset; // tile with tracks |
1370 image += rti->snow_offset; // tile with tracks |
1309 } else { |
1371 } else { |
1310 image = SPR_FLAT_SNOWY_TILE; // flat ground |
1372 image = SPR_FLAT_SNOWY_TILE; // flat ground |
1311 } |
1373 } |
1312 } |
1374 } |
1313 } else { |
1375 } else { |
1314 // look for customization |
1376 /* look for customization */ |
1315 byte stat_id = GetWaypointByTile(ti->tile)->stat_id; |
1377 byte stat_id = GetWaypointByTile(ti->tile)->stat_id; |
1316 const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, stat_id); |
1378 const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, stat_id); |
1317 |
1379 |
1318 if (statspec != NULL) { |
1380 if (statspec != NULL) { |
1319 // emulate station tile - open with building |
1381 /* emulate station tile - open with building */ |
1320 const Station* st = ComposeWaypointStation(ti->tile); |
1382 const Station* st = ComposeWaypointStation(ti->tile); |
1321 uint gfx = 2; |
1383 uint gfx = 2; |
1322 |
1384 |
1323 if (HASBIT(statspec->callbackmask, CBM_CUSTOM_LAYOUT)) { |
1385 if (HASBIT(statspec->callbackmask, CBM_CUSTOM_LAYOUT)) { |
1324 uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile); |
1386 uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile); |
1431 int cur; |
1493 int cur; |
1432 int cur_stack; |
1494 int cur_stack; |
1433 bool stop; |
1495 bool stop; |
1434 bool has_presignal; |
1496 bool has_presignal; |
1435 |
1497 |
1436 // presignal info |
1498 /* presignal info */ |
1437 int presignal_exits; |
1499 int presignal_exits; |
1438 int presignal_exits_free; |
1500 int presignal_exits_free; |
1439 |
1501 |
1440 // these are used to keep track of the signals that change. |
1502 /* these are used to keep track of the signals that change. */ |
1441 TrackdirByte bit[NUM_SSD_ENTRY]; |
1503 TrackdirByte bit[NUM_SSD_ENTRY]; |
1442 TileIndex tile[NUM_SSD_ENTRY]; |
1504 TileIndex tile[NUM_SSD_ENTRY]; |
1443 |
1505 |
1444 // these are used to keep track of the stack that modifies presignals recursively |
1506 /* these are used to keep track of the stack that modifies presignals recursively */ |
1445 TileIndex next_tile[NUM_SSD_STACK]; |
1507 TileIndex next_tile[NUM_SSD_STACK]; |
1446 DiagDirectionByte next_dir[NUM_SSD_STACK]; |
1508 DiagDirectionByte next_dir[NUM_SSD_STACK]; |
1447 |
1509 |
1448 }; |
1510 }; |
1449 |
1511 |
1450 static bool SetSignalsEnumProc(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state) |
1512 static bool SetSignalsEnumProc(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state) |
1451 { |
1513 { |
1452 SetSignalsData* ssd = (SetSignalsData*)data; |
1514 SetSignalsData* ssd = (SetSignalsData*)data; |
|
1515 Track track = TrackdirToTrack(trackdir); |
1453 |
1516 |
1454 if (!IsTileType(tile, MP_RAILWAY)) return false; |
1517 if (!IsTileType(tile, MP_RAILWAY)) return false; |
1455 |
1518 |
1456 // the tile has signals? |
1519 /* the tile has signals? */ |
1457 if (HasSignalOnTrack(tile, TrackdirToTrack(trackdir))) { |
1520 if (HasSignalOnTrack(tile, track)) { |
1458 if (HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir))) { |
1521 if (HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir))) { |
1459 // yes, add the signal to the list of signals |
1522 /* yes, add the signal to the list of signals */ |
1460 if (ssd->cur != NUM_SSD_ENTRY) { |
1523 if (ssd->cur != NUM_SSD_ENTRY) { |
1461 ssd->tile[ssd->cur] = tile; // remember the tile index |
1524 ssd->tile[ssd->cur] = tile; // remember the tile index |
1462 ssd->bit[ssd->cur] = trackdir; // and the controlling bit number |
1525 ssd->bit[ssd->cur] = trackdir; // and the controlling bit number |
1463 ssd->cur++; |
1526 ssd->cur++; |
1464 } |
1527 } |
1465 |
1528 |
1466 // remember if this block has a presignal. |
1529 /* remember if this block has a presignal. */ |
1467 ssd->has_presignal |= IsPresignalEntry(tile); |
1530 ssd->has_presignal |= IsPresignalEntry(tile, track); |
1468 } |
1531 } |
1469 |
1532 |
1470 if (HasSignalOnTrackdir(tile, trackdir) && IsPresignalExit(tile)) { |
1533 if (HasSignalOnTrackdir(tile, trackdir) && IsPresignalExit(tile, track)) { |
1471 // this is an exit signal that points out from the segment |
1534 /* this is an exit signal that points out from the segment */ |
1472 ssd->presignal_exits++; |
1535 ssd->presignal_exits++; |
1473 if (GetSignalStateByTrackdir(tile, trackdir) != SIGNAL_STATE_RED) |
1536 if (GetSignalStateByTrackdir(tile, trackdir) != SIGNAL_STATE_RED) |
1474 ssd->presignal_exits_free++; |
1537 ssd->presignal_exits_free++; |
1475 } |
1538 } |
1476 |
1539 |
1524 direction = GetBridgeRampDirection(tile); |
1587 direction = GetBridgeRampDirection(tile); |
1525 } |
1588 } |
1526 |
1589 |
1527 dest.track = 1 << (direction & 1); // get the trackbit the vehicle would have if it has not entered the tunnel yet (ie is still visible) |
1590 dest.track = 1 << (direction & 1); // get the trackbit the vehicle would have if it has not entered the tunnel yet (ie is still visible) |
1528 |
1591 |
1529 // check for a vehicle with that trackdir on the start tile of the tunnel |
1592 /* check for a vehicle with that trackdir on the start tile of the tunnel */ |
1530 if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL) return true; |
1593 if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL) return true; |
1531 |
1594 |
1532 // check for a vehicle with that trackdir on the end tile of the tunnel |
1595 /* check for a vehicle with that trackdir on the end tile of the tunnel */ |
1533 if (VehicleFromPos(end, &dest, SignalVehicleCheckProc) != NULL) return true; |
1596 if (VehicleFromPos(end, &dest, SignalVehicleCheckProc) != NULL) return true; |
1534 |
1597 |
1535 // now check all tiles from start to end for a warping vehicle |
1598 /* now check all tiles from start to end for a warping vehicle |
1536 // NOTE: the hashes for tiles may overlap, so this could maybe be optimised a bit by not checking every tile? |
1599 * NOTE: the hashes for tiles may overlap, so this could maybe be optimised a bit by not checking every tile? */ |
1537 dest.track = 0x40; //Vehicle inside a tunnel or on a bridge |
1600 dest.track = 0x40; //Vehicle inside a tunnel or on a bridge |
1538 for (; tile != end; tile += TileOffsByDiagDir(direction)) { |
1601 for (; tile != end; tile += TileOffsByDiagDir(direction)) { |
1539 if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL) |
1602 if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL) |
1540 return true; |
1603 return true; |
1541 } |
1604 } |
1542 |
1605 |
1543 // no vehicle found |
1606 /* no vehicle found */ |
1544 return false; |
1607 return false; |
1545 } |
1608 } |
1546 |
1609 |
1547 return VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL; |
1610 return VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL; |
1548 } |
1611 } |
1593 |
1656 |
1594 static void ChangeSignalStates(SetSignalsData *ssd) |
1657 static void ChangeSignalStates(SetSignalsData *ssd) |
1595 { |
1658 { |
1596 int i; |
1659 int i; |
1597 |
1660 |
1598 // thinking about presignals... |
1661 /* thinking about presignals... |
1599 // the presignal is green if, |
1662 * the presignal is green if, |
1600 // if no train is in the segment AND |
1663 * if no train is in the segment AND |
1601 // there is at least one green exit signal OR |
1664 * there is at least one green exit signal OR |
1602 // there are no exit signals in the segment |
1665 * there are no exit signals in the segment */ |
1603 |
1666 |
1604 // then mark the signals in the segment accordingly |
1667 /* then mark the signals in the segment accordingly */ |
1605 for (i = 0; i != ssd->cur; i++) { |
1668 for (i = 0; i != ssd->cur; i++) { |
1606 TileIndex tile = ssd->tile[i]; |
1669 TileIndex tile = ssd->tile[i]; |
1607 byte bit = SignalAgainstTrackdir(ssd->bit[i]); |
1670 byte bit = SignalAgainstTrackdir(ssd->bit[i]); |
1608 uint16 m2 = _m[tile].m2; |
1671 uint signals = GetSignalStates(tile); |
1609 |
1672 Track track = TrackdirToTrack(ssd->bit[i]); |
1610 // presignals don't turn green if there is at least one presignal exit and none are free |
1673 |
1611 if (IsPresignalEntry(tile)) { |
1674 /* presignals don't turn green if there is at least one presignal exit and none are free */ |
|
1675 if (IsPresignalEntry(tile, track)) { |
1612 int ex = ssd->presignal_exits, exfree = ssd->presignal_exits_free; |
1676 int ex = ssd->presignal_exits, exfree = ssd->presignal_exits_free; |
1613 |
1677 |
1614 // subtract for dual combo signals so they don't count themselves |
1678 /* subtract for dual combo signals so they don't count themselves */ |
1615 if (IsPresignalExit(tile) && HasSignalOnTrackdir(tile, ssd->bit[i])) { |
1679 if (IsPresignalExit(tile, track) && HasSignalOnTrackdir(tile, ssd->bit[i])) { |
1616 ex--; |
1680 ex--; |
1617 if (GetSignalStateByTrackdir(tile, ssd->bit[i]) != SIGNAL_STATE_RED) exfree--; |
1681 if (GetSignalStateByTrackdir(tile, ssd->bit[i]) != SIGNAL_STATE_RED) exfree--; |
1618 } |
1682 } |
1619 |
1683 |
1620 // if we have exits and none are free, make red. |
1684 /* if we have exits and none are free, make red. */ |
1621 if (ex && !exfree) goto make_red; |
1685 if (ex && !exfree) goto make_red; |
1622 } |
1686 } |
1623 |
1687 |
1624 // check if the signal is unaffected. |
1688 /* check if the signal is unaffected. */ |
1625 if (ssd->stop) { |
1689 if (ssd->stop) { |
1626 make_red: |
1690 make_red: |
1627 // turn red |
1691 /* turn red */ |
1628 if ((bit & m2) == 0) continue; |
1692 if ((bit & signals) == 0) continue; |
1629 } else { |
1693 } else { |
1630 // turn green |
1694 /* turn green */ |
1631 if ((bit & m2) != 0) continue; |
1695 if ((bit & signals) != 0) continue; |
1632 } |
1696 } |
1633 |
1697 |
1634 /* Update signals on the other side of this exit-combo signal; it changed. */ |
1698 /* Update signals on the other side of this exit-combo signal; it changed. */ |
1635 if (IsPresignalExit(tile)) { |
1699 if (IsPresignalExit(tile, track)) { |
1636 if (ssd->cur_stack != NUM_SSD_STACK) { |
1700 if (ssd->cur_stack != NUM_SSD_STACK) { |
1637 ssd->next_tile[ssd->cur_stack] = tile; |
1701 ssd->next_tile[ssd->cur_stack] = tile; |
1638 ssd->next_dir[ssd->cur_stack] = _dir_from_track[ssd->bit[i]]; |
1702 ssd->next_dir[ssd->cur_stack] = _dir_from_track[ssd->bit[i]]; |
1639 ssd->cur_stack++; |
1703 ssd->cur_stack++; |
1640 } else { |
1704 } else { |
1641 DEBUG(misc, 0, "NUM_SSD_STACK too small"); /// @todo WTF is this??? |
1705 DEBUG(misc, 0, "NUM_SSD_STACK too small"); /// @todo WTF is this??? |
1642 } |
1706 } |
1643 } |
1707 } |
1644 |
1708 |
1645 // it changed, so toggle it |
1709 /* it changed, so toggle it */ |
1646 _m[tile].m2 = m2 ^ bit; |
1710 SetSignalStates(tile, signals ^ bit); |
1647 MarkTileDirtyByTile(tile); |
1711 MarkTileDirtyByTile(tile); |
1648 } |
1712 } |
1649 } |
1713 } |
1650 |
1714 |
1651 |
1715 |
1655 int result = -1; |
1719 int result = -1; |
1656 |
1720 |
1657 ssd.cur_stack = 0; |
1721 ssd.cur_stack = 0; |
1658 |
1722 |
1659 for (;;) { |
1723 for (;;) { |
1660 // go through one segment and update all signals pointing into that segment. |
1724 /* go through one segment and update all signals pointing into that segment. */ |
1661 ssd.cur = ssd.presignal_exits = ssd.presignal_exits_free = 0; |
1725 ssd.cur = ssd.presignal_exits = ssd.presignal_exits_free = 0; |
1662 ssd.has_presignal = false; |
1726 ssd.has_presignal = false; |
1663 |
1727 |
1664 FollowTrack(tile, 0xC000 | TRANSPORT_RAIL, direction, SetSignalsEnumProc, SetSignalsAfterProc, &ssd); |
1728 FollowTrack(tile, 0xC000 | TRANSPORT_RAIL, 0, direction, SetSignalsEnumProc, SetSignalsAfterProc, &ssd); |
1665 ChangeSignalStates(&ssd); |
1729 ChangeSignalStates(&ssd); |
1666 |
1730 |
1667 // remember the result only for the first iteration. |
1731 /* remember the result only for the first iteration. */ |
1668 if (result < 0) { |
1732 if (result < 0) { |
1669 // stay in depot while segment is occupied or while all presignal exits are blocked |
1733 /* stay in depot while segment is occupied or while all presignal exits are blocked */ |
1670 result = ssd.stop || (ssd.presignal_exits > 0 && ssd.presignal_exits_free == 0); |
1734 result = ssd.stop || (ssd.presignal_exits > 0 && ssd.presignal_exits_free == 0); |
1671 } |
1735 } |
1672 |
1736 |
1673 // if any exit signals were changed, we need to keep going to modify the stuff behind those. |
1737 /* if any exit signals were changed, we need to keep going to modify the stuff behind those. */ |
1674 if (ssd.cur_stack == 0) break; |
1738 if (ssd.cur_stack == 0) break; |
1675 |
1739 |
1676 // one or more exit signals were changed, so we need to update another segment too. |
1740 /* one or more exit signals were changed, so we need to update another segment too. */ |
1677 tile = ssd.next_tile[--ssd.cur_stack]; |
1741 tile = ssd.next_tile[--ssd.cur_stack]; |
1678 direction = ssd.next_dir[ssd.cur_stack]; |
1742 direction = ssd.next_dir[ssd.cur_stack]; |
1679 } |
1743 } |
1680 |
1744 |
1681 return result != 0; |
1745 return result != 0; |
1865 return (rails == TRACK_BIT_CROSS) ? ret | 0x40 : ret; |
1929 return (rails == TRACK_BIT_CROSS) ? ret | 0x40 : ret; |
1866 } |
1930 } |
1867 |
1931 |
1868 case RAIL_TILE_SIGNALS: { |
1932 case RAIL_TILE_SIGNALS: { |
1869 uint32 ret = GetTrackBits(tile) * 0x101; |
1933 uint32 ret = GetTrackBits(tile) * 0x101; |
1870 byte a; |
1934 byte a = GetPresentSignals(tile); |
1871 uint16 b; |
1935 uint b = GetSignalStates(tile); |
1872 |
|
1873 a = _m[tile].m3; |
|
1874 b = _m[tile].m2; |
|
1875 |
1936 |
1876 b &= a; |
1937 b &= a; |
1877 |
1938 |
1878 /* When signals are not present (in neither |
1939 /* When signals are not present (in neither |
1879 * direction), we pretend them to be green. (So if |
1940 * direction), we pretend them to be green. (So if |
1880 * signals are only one way, the other way will |
1941 * signals are only one way, the other way will |
1881 * implicitely become `red' */ |
1942 * implicitely become `red' */ |
1882 if ((a & 0xC0) == 0) b |= 0xC0; |
1943 if ((a & 0xC) == 0) b |= 0xC; |
1883 if ((a & 0x30) == 0) b |= 0x30; |
1944 if ((a & 0x3) == 0) b |= 0x3; |
1884 |
1945 |
1885 if ((b & 0x80) == 0) ret |= 0x10070000; |
1946 if ((b & 0x8) == 0) ret |= 0x10070000; |
1886 if ((b & 0x40) == 0) ret |= 0x07100000; |
1947 if ((b & 0x4) == 0) ret |= 0x07100000; |
1887 if ((b & 0x20) == 0) ret |= 0x20080000; |
1948 if ((b & 0x2) == 0) ret |= 0x20080000; |
1888 if ((b & 0x10) == 0) ret |= 0x08200000; |
1949 if ((b & 0x1) == 0) ret |= 0x08200000; |
1889 |
1950 |
1890 return ret; |
1951 return ret; |
1891 } |
1952 } |
1892 |
1953 |
1893 case RAIL_TILE_DEPOT: return AxisToTrackBits(DiagDirToAxis(GetRailDepotDirection(tile))) * 0x101; |
1954 case RAIL_TILE_DEPOT: return AxisToTrackBits(DiagDirToAxis(GetRailDepotDirection(tile))) * 0x101; |
1911 case RAIL_TILE_NORMAL: |
1972 case RAIL_TILE_NORMAL: |
1912 td->str = STR_1021_RAILROAD_TRACK; |
1973 td->str = STR_1021_RAILROAD_TRACK; |
1913 break; |
1974 break; |
1914 |
1975 |
1915 case RAIL_TILE_SIGNALS: { |
1976 case RAIL_TILE_SIGNALS: { |
1916 const StringID signal_type[] = { |
1977 const StringID signal_type[4][4] = { |
1917 STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS, |
1978 { |
1918 STR_RAILROAD_TRACK_WITH_PRESIGNALS, |
1979 STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS, |
1919 STR_RAILROAD_TRACK_WITH_EXITSIGNALS, |
1980 STR_RAILROAD_TRACK_WITH_NORMAL_PRESIGNALS, |
1920 STR_RAILROAD_TRACK_WITH_COMBOSIGNALS |
1981 STR_RAILROAD_TRACK_WITH_NORMAL_EXITSIGNALS, |
|
1982 STR_RAILROAD_TRACK_WITH_NORMAL_COMBOSIGNALS |
|
1983 }, |
|
1984 { |
|
1985 STR_RAILROAD_TRACK_WITH_NORMAL_PRESIGNALS, |
|
1986 STR_RAILROAD_TRACK_WITH_PRESIGNALS, |
|
1987 STR_RAILROAD_TRACK_WITH_PRE_EXITSIGNALS, |
|
1988 STR_RAILROAD_TRACK_WITH_PRE_COMBOSIGNALS |
|
1989 }, |
|
1990 { |
|
1991 STR_RAILROAD_TRACK_WITH_NORMAL_EXITSIGNALS, |
|
1992 STR_RAILROAD_TRACK_WITH_PRE_EXITSIGNALS, |
|
1993 STR_RAILROAD_TRACK_WITH_EXITSIGNALS, |
|
1994 STR_RAILROAD_TRACK_WITH_EXIT_COMBOSIGNALS |
|
1995 }, |
|
1996 { |
|
1997 STR_RAILROAD_TRACK_WITH_NORMAL_COMBOSIGNALS, |
|
1998 STR_RAILROAD_TRACK_WITH_PRE_COMBOSIGNALS, |
|
1999 STR_RAILROAD_TRACK_WITH_EXIT_COMBOSIGNALS, |
|
2000 STR_RAILROAD_TRACK_WITH_COMBOSIGNALS |
|
2001 } |
1921 }; |
2002 }; |
1922 |
2003 |
1923 td->str = signal_type[GetSignalType(tile)]; |
2004 td->str = signal_type[GetSignalType(tile, TRACK_UPPER)][GetSignalType(tile, TRACK_LOWER)]; |
1924 break; |
2005 break; |
1925 } |
2006 } |
1926 |
2007 |
1927 case RAIL_TILE_DEPOT: |
2008 case RAIL_TILE_DEPOT: |
1928 td->str = STR_1023_RAILROAD_TRAIN_DEPOT; |
2009 td->str = STR_1023_RAILROAD_TRAIN_DEPOT; |