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

Function CmdBuildRailWaypoint

src/waypoint_cmd.cpp:208–327  ·  view source on GitHub ↗

* Convert existing rail to waypoint. Eg build a waypoint station over * piece of rail * @param flags type of operation * @param start_tile northern most tile where waypoint will be built * @param axis orientation (Axis) * @param width width of waypoint * @param height height of waypoint * @param spec_class custom station class * @param spec_index custom station id * @param station_to_join

Source from the content-addressed store, hash-verified

206 * @return the cost of this operation or an error
207 */
208CommandCost CmdBuildRailWaypoint(DoCommandFlags flags, TileIndex start_tile, Axis axis, uint8_t width, uint8_t height, StationClassID spec_class, uint16_t spec_index, StationID station_to_join, bool adjacent)
209{
210 if (!IsValidAxis(axis)) return CMD_ERROR;
211 /* Check if the given station class is valid */
212 if (static_cast<uint>(spec_class) >= StationClass::GetClassCount()) return CMD_ERROR;
213 const StationClass *cls = StationClass::Get(spec_class);
214 if (!IsWaypointClass(*cls)) return CMD_ERROR;
215 if (spec_index >= cls->GetSpecCount()) return CMD_ERROR;
216
217 /* The number of parts to build */
218 uint8_t count = axis == AXIS_X ? height : width;
219
220 if ((axis == AXIS_X ? width : height) != 1) return CMD_ERROR;
221 if (count == 0 || count > _settings_game.station.station_spread) return CMD_ERROR;
222
223 bool reuse = (station_to_join != NEW_STATION);
224 if (!reuse) station_to_join = StationID::Invalid();
225 bool distant_join = (station_to_join != StationID::Invalid());
226
227 if (distant_join && (!_settings_game.station.distant_join_stations || !Waypoint::IsValidID(station_to_join))) return CMD_ERROR;
228
229 TileArea new_location(start_tile, width, height);
230
231 /* only AddCost for non-existing waypoints */
232 CommandCost cost(EXPENSES_CONSTRUCTION);
233 for (TileIndex cur_tile : new_location) {
234 if (!IsRailWaypointTile(cur_tile)) cost.AddCost(_price[PR_BUILD_WAYPOINT_RAIL]);
235 }
236
237 /* Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station) */
238 StationID est = StationID::Invalid();
239
240 const StationSpec *spec = StationClass::Get(spec_class)->GetSpec(spec_index);
241 RailStationTileLayout stl{spec, count, 1};
242
243 /* Check whether the tiles we're building on are valid rail or not. */
244 TileIndexDiff offset = TileOffsByAxis(OtherAxis(axis));
245 for (auto [i, it, tile] = std::make_tuple(0, stl.begin(), start_tile); i < count; ++i, ++it, tile += offset) {
246 CommandCost ret = IsValidTileForWaypoint(tile, axis, &est);
247 if (ret.Failed()) return ret;
248
249 ret = IsRailStationBridgeAboveOk(tile, spec, StationType::RailWaypoint, *it + axis);
250 if (ret.Failed()) return ret;
251 }
252
253 Waypoint *wp = nullptr;
254 CommandCost ret = FindJoiningWaypoint(est, station_to_join, adjacent, new_location, &wp, false);
255 if (ret.Failed()) return ret;
256
257 /* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */
258 TileIndex center_tile = start_tile + (count / 2) * offset;
259 if (wp == nullptr && reuse) wp = FindDeletedWaypointCloseTo(center_tile, STR_SV_STNAME_WAYPOINT, _current_company, false);
260
261 if (wp != nullptr) {
262 /* Reuse an existing waypoint. */
263 if (wp->owner != _current_company) return CommandCost(STR_ERROR_TOO_CLOSE_TO_ANOTHER_WAYPOINT);
264
265 /* Check if we want to expand an already existing waypoint. */

Callers

nothing calls this directly

Calls 15

IsValidAxisFunction · 0.85
InvalidFunction · 0.85
IsRailWaypointTileFunction · 0.85
TileOffsByAxisFunction · 0.85
OtherAxisFunction · 0.85
IsValidTileForWaypointFunction · 0.85
FindJoiningWaypointFunction · 0.85
CommandCostClass · 0.85
CanExpandRailStationFunction · 0.85
AllocateSpecToStationFunction · 0.85

Tested by

no test coverage detected