MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / CmdBuildSingleRail

Function CmdBuildSingleRail

src/rail_cmd.cpp:423–603  ·  view source on GitHub ↗

* Build a single piece of rail * @param flags operation to perform * @param tile tile to build on * @param railtype railtype of being built piece (normal, mono, maglev) * @param track track-orientation * @param auto_remove_signals false = error on signal in the way, true = auto remove signals when in the way * @return the cost of this operation or an error */

Source from the content-addressed store, hash-verified

421 * @return the cost of this operation or an error
422 */
423CommandCost CmdBuildSingleRail(DoCommandFlags flags, TileIndex tile, RailType railtype, Track track, bool auto_remove_signals)
424{
425 CommandCost cost(EXPENSES_CONSTRUCTION);
426
427 if (!ValParamRailType(railtype) || !ValParamTrackOrientation(track)) return CMD_ERROR;
428
429 Slope tileh = GetTileSlope(tile);
430 TrackBits trackbit = TrackToTrackBits(track);
431
432 switch (GetTileType(tile)) {
433 case MP_RAILWAY: {
434 CommandCost ret = CheckTileOwnership(tile);
435 if (ret.Failed()) return ret;
436
437 if (!IsPlainRail(tile)) return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile); // just get appropriate error message
438
439 if (!IsCompatibleRail(GetRailType(tile), railtype)) return CommandCost(STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION);
440
441 ret = CheckTrackCombination(tile, trackbit);
442 if (ret.Succeeded()) ret = EnsureNoTrainOnTrack(tile, track);
443 if (ret.Failed()) return ret;
444
445 ret = CheckRailSlope(tileh, trackbit, GetTrackBits(tile), tile);
446 if (ret.Failed()) return ret;
447 cost.AddCost(ret.GetCost());
448
449 if (HasSignals(tile) && TracksOverlap(GetTrackBits(tile) | TrackToTrackBits(track))) {
450 /* If adding the new track causes any overlap, all signals must be removed first */
451 if (!auto_remove_signals) return CommandCost(STR_ERROR_MUST_REMOVE_SIGNALS_FIRST);
452
453 for (Track track_it = TRACK_BEGIN; track_it < TRACK_END; track_it++) {
454 if (HasTrack(tile, track_it) && HasSignalOnTrack(tile, track_it)) {
455 CommandCost ret_remove_signals = Command<CMD_REMOVE_SINGLE_SIGNAL>::Do(flags, tile, track_it);
456 if (ret_remove_signals.Failed()) return ret_remove_signals;
457 cost.AddCost(ret_remove_signals.GetCost());
458 }
459 }
460 }
461
462 /* If the rail types don't match, try to convert only if engines of
463 * the new rail type are not powered on the present rail type and engines of
464 * the present rail type are powered on the new rail type. */
465 if (GetRailType(tile) != railtype && !HasPowerOnRail(railtype, GetRailType(tile))) {
466 if (HasPowerOnRail(GetRailType(tile), railtype)) {
467 ret = Command<CMD_CONVERT_RAIL>::Do(flags, tile, tile, railtype, false);
468 if (ret.Failed()) return ret;
469 cost.AddCost(ret.GetCost());
470 } else {
471 return CMD_ERROR;
472 }
473 }
474
475 if (flags.Test(DoCommandFlag::Execute)) {
476 SetRailGroundType(tile, RailGroundType::Barren);
477 TrackBits bits = GetTrackBits(tile);
478 SetTrackBits(tile, bits | trackbit);
479 /* Subtract old infrastructure count. */
480 uint pieces = CountBits(bits);

Callers

nothing calls this directly

Calls 15

ValParamRailTypeFunction · 0.85
ValParamTrackOrientationFunction · 0.85
GetTileSlopeFunction · 0.85
TrackToTrackBitsFunction · 0.85
GetTileTypeFunction · 0.85
CheckTileOwnershipFunction · 0.85
IsPlainRailFunction · 0.85
IsCompatibleRailFunction · 0.85
GetRailTypeFunction · 0.85
CommandCostClass · 0.85
CheckTrackCombinationFunction · 0.85
EnsureNoTrainOnTrackFunction · 0.85

Tested by

no test coverage detected