/* static */ bool AIRail::BuildRailWaypoint(TileIndex tile) { EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsRailTile(tile)); EnforcePrecondition(false, GetRailTracks(tile) == RAILTRACK_NE_SW || GetRailTracks(tile) == RAILTRACK_NW_SE); EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType())); return AIObject::DoCommand(tile, GetCurrentRailType() | (GetRailTracks(tile) == RAILTRACK_NE_SW ? AXIS_X : AXIS_Y) << 4 | 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16, CMD_BUILD_RAIL_WAYPOINT); }
/* static */ bool ScriptRail::BuildSignal(TileIndex tile, TileIndex front, SignalType signal) { EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, ScriptMap::DistanceManhattan(tile, front) == 1) EnforcePrecondition(false, ::IsPlainRailTile(tile)); EnforcePrecondition(false, ::IsValidSignalType(signal)); Track track = INVALID_TRACK; uint signal_cycles; int data_index = 2 + (::TileX(front) - ::TileX(tile)) + 2 * (::TileY(front) - ::TileY(tile)); for (int i = 0; i < NUM_TRACK_DIRECTIONS; i++) { const Track &t = _possible_trackdirs[data_index][i].track; if (!(::TrackToTrackBits(t) & GetRailTracks(tile))) continue; track = t; signal_cycles = _possible_trackdirs[data_index][i].signal_cycles; break; } EnforcePrecondition(false, track != INVALID_TRACK); uint p1 = track; if (signal < SIGNALTYPE_TWOWAY) { if (signal != SIGNALTYPE_PBS && signal != SIGNALTYPE_PBS_ONEWAY) signal_cycles++; p1 |= (signal_cycles << 15); } p1 |= ((signal >= SIGNALTYPE_TWOWAY ? signal ^ SIGNALTYPE_TWOWAY : signal) << 5); return ScriptObject::DoCommand(tile, p1, 0, CMD_BUILD_SIGNALS); }
/* static */ bool AIRail::RemoveRailTrack(TileIndex tile, RailTrack rail_track) { EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsPlainRailTile(tile) || ::IsLevelCrossingTile(tile)); EnforcePrecondition(false, GetRailTracks(tile) & rail_track); EnforcePrecondition(false, KillFirstBit((uint)rail_track) == 0); return AIObject::DoCommand(tile, tile, GetCurrentRailType() | (FindFirstTrack((::TrackBits)rail_track) << 4), CMD_REMOVE_RAILROAD_TRACK); }
/* static */ bool AIRail::RemoveSignal(TileIndex tile, TileIndex front) { EnforcePrecondition(false, AIMap::DistanceManhattan(tile, front) == 1) EnforcePrecondition(false, GetSignalType(tile, front) != SIGNALTYPE_NONE); Track track = INVALID_TRACK; int data_index = 2 + (::TileX(front) - ::TileX(tile)) + 2 * (::TileY(front) - ::TileY(tile)); for (int i = 0; i < NUM_TRACK_DIRECTIONS; i++) { const Track &t = _possible_trackdirs[data_index][i].track; if (!(::TrackToTrackBits(t) & GetRailTracks(tile))) continue; track = t; break; } EnforcePrecondition(false, track != INVALID_TRACK); return AIObject::DoCommand(tile, track, 0, CMD_REMOVE_SIGNALS); }
/* static */ ScriptRail::SignalType ScriptRail::GetSignalType(TileIndex tile, TileIndex front) { if (ScriptMap::DistanceManhattan(tile, front) != 1) return SIGNALTYPE_NONE; if (!::IsTileType(tile, MP_RAILWAY) || !::HasSignals(tile)) return SIGNALTYPE_NONE; int data_index = 2 + (::TileX(front) - ::TileX(tile)) + 2 * (::TileY(front) - ::TileY(tile)); for (int i = 0; i < NUM_TRACK_DIRECTIONS; i++) { const Track &track = _possible_trackdirs[data_index][i].track; if (!(::TrackToTrackBits(track) & GetRailTracks(tile))) continue; if (!HasSignalOnTrack(tile, track)) continue; if (!HasSignalOnTrackdir(tile, _possible_trackdirs[data_index][i].trackdir)) continue; SignalType st = (SignalType)::GetSignalType(tile, track); if (HasSignalOnTrackdir(tile, ::ReverseTrackdir(_possible_trackdirs[data_index][i].trackdir))) st = (SignalType)(st | SIGNALTYPE_TWOWAY); return st; } return SIGNALTYPE_NONE; }
/* static */ bool ScriptRail::AreTilesConnected(TileIndex from, TileIndex tile, TileIndex to) { if (!IsRailTile(tile)) return false; if (from == to || ScriptMap::DistanceManhattan(from, tile) != 1 || ScriptMap::DistanceManhattan(tile, to) != 1) return false; if (to < from) ::Swap(from, to); if (tile - from == 1) { if (to - tile == 1) return (GetRailTracks(tile) & RAILTRACK_NE_SW) != 0; if (to - tile == ::MapSizeX()) return (GetRailTracks(tile) & RAILTRACK_NE_SE) != 0; } else if (tile - from == ::MapSizeX()) { if (tile - to == 1) return (GetRailTracks(tile) & RAILTRACK_NW_NE) != 0; if (to - tile == 1) return (GetRailTracks(tile) & RAILTRACK_NW_SW) != 0; if (to - tile == ::MapSizeX()) return (GetRailTracks(tile) & RAILTRACK_NW_SE) != 0; } else { return (GetRailTracks(tile) & RAILTRACK_SW_SE) != 0; } NOT_REACHED(); }