Skip to content

Commit

Permalink
Feature: WIP Draft for extended road depots (platform type).
Browse files Browse the repository at this point in the history
  • Loading branch information
J0anJosep committed Apr 11, 2021
1 parent a45483a commit af107b0
Show file tree
Hide file tree
Showing 19 changed files with 642 additions and 136 deletions.
2 changes: 2 additions & 0 deletions src/autoreplace_cmd.cpp
Expand Up @@ -805,6 +805,7 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1
if (v->type == VEH_TRAIN) {
train_placement.LiftTrain(Train::From(v), flags);
} else if (IsBigDepotTile(v->tile)) {
if (v->type == VEH_ROAD) ChangeNumDepotVehicles(v->tile, -1);
SetBigDepotReservation(v, false);
}

Expand Down Expand Up @@ -853,6 +854,7 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1
}
train_placement.PlaceTrain(Train::From(v), flags);
} else if (IsBigDepotTile(v->tile)) {
if (v->type == VEH_ROAD) ChangeNumDepotVehicles(v->tile, 1);
SetBigDepotReservation(v, true);
}

Expand Down
33 changes: 31 additions & 2 deletions src/depot.cpp
Expand Up @@ -169,6 +169,31 @@ void Depot::RescanDepotTiles()
}
}

DepotReservation GetDepotReservationStatus(TileIndex tile) {
assert(IsBigDepotTile(tile) && IsRoadDepot(tile));
uint num_veh = GetNumDepotVehicles(tile);
switch (num_veh) {
case 0:
return DEPOT_RESERVATION_EMPTY;
default:
assert(num_veh < ROAD_DEPOT_CAPACITY);
return DEPOT_RESERVATION_IN_USE;
case ROAD_DEPOT_CAPACITY:
num_veh = 0;
for (const Vehicle *u : Vehicle::Iterate()) {
if (u->type != VEH_ROAD) continue;
if (!u->IsFrontEngine()) continue;
if (!u->IsInDepot()) continue;
if (u->tile != tile) continue;
if ((u->vehstatus & VS_STOPPED) == 0) continue;
num_veh++;
}
assert(num_veh <= ROAD_DEPOT_CAPACITY);
return num_veh == ROAD_DEPOT_CAPACITY ?
DEPOT_RESERVATION_FULL_STOPPED_VEH : DEPOT_RESERVATION_IN_USE;
}
}

/**
* Fix tile reservations on big depots and vehicle changes.
* @param v Vehicle to be revised.
Expand All @@ -180,11 +205,15 @@ void SetBigDepotReservation(Vehicle *v, bool reserve)
assert(IsBigDepotTile(v->tile));
DepotReservation res_type = DEPOT_RESERVATION_EMPTY;

res_type = (v->vehstatus & VS_STOPPED) ?
DEPOT_RESERVATION_FULL_STOPPED_VEH : DEPOT_RESERVATION_IN_USE;
if (reserve && v->type != VEH_ROAD) {
res_type = (v->vehstatus & VS_STOPPED) ?
DEPOT_RESERVATION_FULL_STOPPED_VEH : DEPOT_RESERVATION_IN_USE;
}

switch (v->type) {
case VEH_ROAD:
res_type = GetDepotReservationStatus(v->tile);
SetDepotReservation(v->tile, res_type);
break;

case VEH_SHIP:
Expand Down
2 changes: 0 additions & 2 deletions src/economy_type.h
Expand Up @@ -222,8 +222,6 @@ static const int INVALID_PRICE_MODIFIER = MIN_PRICE_MODIFIER - 1;
static const uint TUNNELBRIDGE_TRACKBIT_FACTOR = 4;
/** Multiplier for how many regular track bits a level crossing counts. */
static const uint LEVELCROSSING_TRACKBIT_FACTOR = 2;
/** Multiplier for how many regular track bits a road depot counts. */
static const uint ROAD_DEPOT_TRACKBIT_FACTOR = 2;
/** Multiplier for how many regular track bits a bay stop counts. */
static const uint ROAD_STOP_TRACKBIT_FACTOR = 2;
/** Multiplier for how many regular tiles a lock counts. */
Expand Down
9 changes: 6 additions & 3 deletions src/lang/english.txt
Expand Up @@ -2518,7 +2518,8 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}Build ro
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Build tramway section. Ctrl toggles build/remove for tramway construction. Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}Build road section using the Autoroad mode. Ctrl toggles build/remove for road construction. Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM :{BLACK}Build tramway section using the Autotram mode. Ctrl toggles build/remove for tramway construction. Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Build road vehicle depot (for buying and servicing vehicles). Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Build one-tile road vehicle depot (for buying and servicing vehicles). Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_BIG_DEPOT :{BLACK}Build multi-tile road vehicle depots (for buying and servicing vehicles). Ctrl enables joining depots. Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Build tram vehicle depot (for buying and servicing vehicles). Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}Build bus station. Ctrl enables joining stations. Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Build passenger tram station. Ctrl enables joining stations. Shift toggles building/showing cost estimate
Expand Down Expand Up @@ -2777,7 +2778,8 @@ STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT_EXTENDED :Extended railwa
STR_LAI_ROAD_DESCRIPTION_ROAD :Road
STR_LAI_ROAD_DESCRIPTION_ROAD_WITH_STREETLIGHTS :Road with street lights
STR_LAI_ROAD_DESCRIPTION_TREE_LINED_ROAD :Tree-lined road
STR_LAI_ROAD_DESCRIPTION_ROAD_VEHICLE_DEPOT :Road vehicle depot
STR_LAI_ROAD_DESCRIPTION_ROAD_VEHICLE_DEPOT_STANDARD :Standard road vehicle depot
STR_LAI_ROAD_DESCRIPTION_ROAD_VEHICLE_DEPOT_EXTENDED :Extended road vehicle depot
STR_LAI_ROAD_DESCRIPTION_ROAD_RAIL_LEVEL_CROSSING :Road/rail level crossing
STR_LAI_ROAD_DESCRIPTION_TRAMWAY :Tramway

Expand Down Expand Up @@ -4587,7 +4589,7 @@ STR_ERROR_CANT_START_PLATFORM_LONG :{WHITE}{VEHICLE
STR_ERROR_DEPOT_FULL_DEPOT :There is no free depot compatible with this type of vehicle
STR_ADVICE_PLATFORM_TYPE :{WHITE}{VEHICLE} cannot leave depot because there is no compatible platform for this type of train
STR_ADVICE_PLATFORM_LONG :{WHITE}{VEHICLE} cannot leave depot because compatible platforms are not long enough
STR_ADVICE_TRAIN_HAS_NO_POWER :{WHITE}{VEHICLE} cannot leave depot because it has no power in any tile of the depot
STR_ADVICE_VEHICLE_HAS_NO_POWER :{WHITE}{VEHICLE} cannot leave depot because it has no power in any tile of the depot
STR_ADVICE_PLATFORM_FREE_PLATFORM :{WHITE}{VEHICLE} cannot leave depot because compatible platforms are occupied
STR_ADVICE_PLATFORM_SIGNALS :{WHITE}{VEHICLE} cannot leave depot because the segments of the compatible free platforms are occupied. Check the signaling of those segments.

Expand Down Expand Up @@ -4748,6 +4750,7 @@ STR_ERROR_NO_VEHICLES_AVAILABLE_YET_EXPLANATION :{WHITE}Start a
STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Can't make train pass signal at danger...
STR_ERROR_CAN_T_REVERSE_DIRECTION_TRAIN :{WHITE}Can't reverse direction of train...
STR_ERROR_TRAIN_START_NO_POWER :Train has no power
STR_ERROR_ROAD_VEHICLE_START_NO_POWER :Road vehicle has no power

STR_ERROR_CAN_T_MAKE_ROAD_VEHICLE_TURN :{WHITE}Can't make road vehicle turn around...

Expand Down
24 changes: 15 additions & 9 deletions src/pathfinder/follow_track.hpp
Expand Up @@ -277,12 +277,14 @@ struct CFollowTrackT

/* road depots can be also left in one direction only */
if (IsRoadTT() && IsDepotTypeTile(m_old_tile, TT())) {
DiagDirection exitdir = GetRoadDepotDirection(m_old_tile);
if (exitdir != m_exitdir) {
RoadTramType rtt = IsTram() ? RTT_TRAM : RTT_ROAD;
RoadBits rb = GetRoadBits(m_old_tile, rtt);
if ((rb & DiagDirToRoadBits(m_exitdir)) == ROAD_NONE) {
m_err = EC_NO_WAY;
return false;
}
}

return true;
}

Expand All @@ -309,16 +311,17 @@ struct CFollowTrackT

/* road and rail depots can also be entered from one direction only */
if (IsRoadTT() && IsDepotTypeTile(m_new_tile, TT())) {
DiagDirection exitdir = GetRoadDepotDirection(m_new_tile);
if (ReverseDiagDir(exitdir) != m_exitdir) {
m_err = EC_NO_WAY;
return false;
}
/* don't try to enter other company's depots */
if (GetTileOwner(m_new_tile) != m_veh_owner) {
m_err = EC_OWNER;
return false;
}
RoadTramType rtt = IsTram() ? RTT_TRAM : RTT_ROAD;
RoadBits rb = GetRoadBits(m_new_tile, rtt);
if ((rb & DiagDirToRoadBits(ReverseDiagDir(m_exitdir))) == ROAD_NONE) {
m_err = EC_NO_WAY;
return false;
}
}
if (IsRailTT() && IsSmallRailDepotTile(m_new_tile)) {
DiagDirection exitdir = GetRailDepotDirection(m_new_tile);
Expand Down Expand Up @@ -407,9 +410,12 @@ struct CFollowTrackT
if (IsBigRailDepot(m_old_tile)) return false;
exitdir = GetRailDepotDirection(m_old_tile);
break;
case TRANSPORT_ROAD:
exitdir = GetRoadDepotDirection(m_old_tile);
case TRANSPORT_ROAD: {
RoadBits rb = GetRoadBits(m_old_tile, IsTram() ? RTT_TRAM : RTT_ROAD) & DiagDirToRoadBits(m_exitdir);
if (rb != ROAD_NONE) return false;
exitdir = ReverseDiagDir(m_exitdir);
break;
}
default: NOT_REACHED();
}

Expand Down
24 changes: 21 additions & 3 deletions src/pathfinder/npf/npf.cpp
Expand Up @@ -368,7 +368,25 @@ static int32 NPFRoadPathCost(AyStar *as, AyStarNode *current, OpenListNode *pare
case MP_ROAD:
cost = NPF_TILE_LENGTH;
/* Increase the cost for level crossings */
if (IsLevelCrossing(tile)) cost += _settings_game.pf.npf.npf_crossing_penalty;
if (IsLevelCrossing(tile)) {
cost += _settings_game.pf.npf.npf_crossing_penalty;
} else if (IsRoadDepot(tile) && IsBigDepot(tile)) {
/* Check if vehicle is heading towards this depot. */
NPFFindStationOrTileData *fstd = (NPFFindStationOrTileData*)as->user_target;
bool dest_depot = fstd->v->current_order.IsType(OT_GOTO_DEPOT) && GetDepotIndex(tile) == fstd->v->current_order.GetDestination();
switch (GetDepotReservation(tile)) {
case DEPOT_RESERVATION_FULL_STOPPED_VEH:
cost += dest_depot ? NPF_INFINITE_PENALTY : (8 * NPF_TILE_LENGTH);
break;
case DEPOT_RESERVATION_IN_USE:
cost += 4 * NPF_TILE_LENGTH;
break;
case DEPOT_RESERVATION_EMPTY:
cost += NPF_TILE_LENGTH;
break;
default: NOT_REACHED();
}
}
break;

case MP_STATION: {
Expand Down Expand Up @@ -643,7 +661,7 @@ static int32 NPFFindStationOrTile(const AyStar *as, const OpenListNode *current)
(fstd->not_articulated || IsDriveThroughStopTile(tile)))
return AYSTAR_FOUND_END_NODE;
} else if (IsDepotTypeTile(tile, user->type) && GetDepotIndex(tile) == fstd->depot_index) {
return AYSTAR_FOUND_END_NODE;
if (fstd->v->type != VEH_ROAD || !IsFullDepot(tile)) return AYSTAR_FOUND_END_NODE;
}

return AYSTAR_DONE;
Expand Down Expand Up @@ -825,7 +843,7 @@ static DiagDirection GetSingleTramBit(TileIndex tile)
*/
static DiagDirection GetTileSingleEntry(TileIndex tile, TransportType type, uint subtype)
{
if (type != TRANSPORT_WATER && IsDepotTypeTile(tile, type) && !IsBigRailDepotTile(tile)) return GetDepotDirection(tile, type);
if (type != TRANSPORT_WATER && IsDepotTypeTile(tile, type) && !IsBigDepotTile(tile)) return GetDepotDirection(tile, type);

if (type == TRANSPORT_ROAD) {
if (IsStandardRoadStopTile(tile)) return GetRoadStopDir(tile);
Expand Down
22 changes: 18 additions & 4 deletions src/pathfinder/yapf/yapf_road.cpp
Expand Up @@ -66,6 +66,19 @@ class CYapfCostRoadT
/* Increase the cost for level crossings */
if (IsLevelCrossing(tile)) {
cost += Yapf().PfGetSettings().road_crossing_penalty;
} else if (IsRoadDepot(tile) && IsBigDepot(tile)) {
switch (GetDepotReservation(tile)) {
case DEPOT_RESERVATION_FULL_STOPPED_VEH:
cost += 8 * YAPF_TILE_LENGTH;
break;
case DEPOT_RESERVATION_IN_USE:
cost += 4 * YAPF_TILE_LENGTH;
break;
case DEPOT_RESERVATION_EMPTY:
cost += YAPF_TILE_LENGTH;
break;
default: NOT_REACHED();
}
}
break;

Expand Down Expand Up @@ -133,7 +146,7 @@ class CYapfCostRoadT
}

/* stop if we have just entered the depot */
if (IsRoadDepotTile(tile) && trackdir == DiagDirToDiagTrackdir(ReverseDiagDir(GetRoadDepotDirection(tile)))) {
if (IsRoadDepotTile(tile) && !IsBigRoadDepotTile(tile) && trackdir == DiagDirToDiagTrackdir(ReverseDiagDir(GetRoadDepotDirection(tile)))) {
/* next time we will reverse and leave the depot */
break;
}
Expand Down Expand Up @@ -199,12 +212,12 @@ class CYapfDestinationAnyDepotRoadT
/** Called by YAPF to detect if node ends in the desired destination */
inline bool PfDetectDestination(Node &n)
{
return IsRoadDepotTile(n.m_segment_last_tile);
return PfDetectDestinationTile(n.m_segment_last_tile, n.m_segment_last_td);
}

inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir)
{
return IsRoadDepotTile(tile);
return IsRoadDepotTile(tile) && !IsFullDepot(tile);
}

/**
Expand Down Expand Up @@ -288,7 +301,8 @@ class CYapfDestinationTileRoadT

if (m_dest_depot != INVALID_DEPOT) {
return IsRoadDepotTile(tile) &&
GetDepotIndex(tile) == m_dest_depot;
GetDepotIndex(tile) == m_dest_depot &&
!IsFullDepot(tile);
}

return tile == m_destTile && HasTrackdir(m_destTrackdirs, trackdir);
Expand Down

0 comments on commit af107b0

Please sign in to comment.