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

Function CmdBuildRoadWaypoint

src/waypoint_cmd.cpp:342–467  ·  view source on GitHub ↗

* Build a road waypoint on an existing road. * @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 road stop class. * @param spec_index custom road stop id. * @param station_to_join station ID to join (NEW_STATIO

Source from the content-addressed store, hash-verified

340 * @return the cost of this operation or an error.
341 */
342CommandCost CmdBuildRoadWaypoint(DoCommandFlags flags, TileIndex start_tile, Axis axis, uint8_t width, uint8_t height, RoadStopClassID spec_class, uint16_t spec_index, StationID station_to_join, bool adjacent)
343{
344 if (!IsValidAxis(axis)) return CMD_ERROR;
345 /* Check if the given station class is valid */
346 if (static_cast<uint>(spec_class) >= RoadStopClass::GetClassCount()) return CMD_ERROR;
347 const RoadStopClass *cls = RoadStopClass::Get(spec_class);
348 if (!IsWaypointClass(*cls)) return CMD_ERROR;
349 if (spec_index >= cls->GetSpecCount()) return CMD_ERROR;
350
351 const RoadStopSpec *roadstopspec = RoadStopClass::Get(spec_class)->GetSpec(spec_index);
352
353 /* The number of parts to build */
354 uint8_t count = axis == AXIS_X ? height : width;
355
356 if ((axis == AXIS_X ? width : height) != 1) return CMD_ERROR;
357 if (count == 0 || count > _settings_game.station.station_spread) return CMD_ERROR;
358
359 bool reuse = (station_to_join != NEW_STATION);
360 if (!reuse) station_to_join = StationID::Invalid();
361 bool distant_join = (station_to_join != StationID::Invalid());
362
363 if (distant_join && (!_settings_game.station.distant_join_stations || !Waypoint::IsValidID(station_to_join))) return CMD_ERROR;
364
365 TileArea roadstop_area(start_tile, width, height);
366
367 /* Total road stop cost. */
368 Money unit_cost;
369 if (roadstopspec != nullptr) {
370 unit_cost = roadstopspec->GetBuildCost(PR_BUILD_STATION_TRUCK);
371 } else {
372 unit_cost = _price[PR_BUILD_STATION_TRUCK];
373 }
374 StationID est = StationID::Invalid();
375 CommandCost cost = CalculateRoadStopCost(roadstop_area, flags, true, StationType::RoadWaypoint, roadstopspec, axis, AxisToDiagDir(axis), &est, INVALID_ROADTYPE, unit_cost);
376 if (cost.Failed()) return cost;
377
378 Waypoint *wp = nullptr;
379 CommandCost ret = FindJoiningWaypoint(est, station_to_join, adjacent, roadstop_area, &wp, true);
380 if (ret.Failed()) return ret;
381
382 /* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */
383 TileIndex center_tile = start_tile + (count / 2) * TileOffsByAxis(OtherAxis(axis));
384 if (wp == nullptr && reuse) wp = FindDeletedWaypointCloseTo(center_tile, STR_SV_STNAME_WAYPOINT, _current_company, true);
385
386 if (wp != nullptr) {
387 /* Reuse an existing waypoint. */
388 if (!HasBit(wp->waypoint_flags, WPF_ROAD)) return CMD_ERROR;
389 if (wp->owner != _current_company) return CommandCost(STR_ERROR_TOO_CLOSE_TO_ANOTHER_WAYPOINT);
390
391 ret = wp->rect.BeforeAddRect(start_tile, width, height, StationRect::ADD_TEST);
392 if (ret.Failed()) return ret;
393 } else {
394 /* Check if we can create a new waypoint. */
395 if (!Waypoint::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_STATIONS_LOADING);
396 }
397
398 /* Check if we can allocate a custom spec to this waypoint. */
399 auto specindex = AllocateSpecToRoadStop(roadstopspec, wp);

Callers

nothing calls this directly

Calls 15

IsValidAxisFunction · 0.85
InvalidFunction · 0.85
CalculateRoadStopCostFunction · 0.85
AxisToDiagDirFunction · 0.85
FindJoiningWaypointFunction · 0.85
TileOffsByAxisFunction · 0.85
OtherAxisFunction · 0.85
HasBitFunction · 0.85
CommandCostClass · 0.85
AllocateSpecToRoadStopFunction · 0.85
SetBitFunction · 0.85

Tested by

no test coverage detected