Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Orientation of rail and road depots can be changed #9642

Merged
merged 1 commit into from Jul 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions regression/regression/main.nut
Expand Up @@ -1107,6 +1107,7 @@ function Regression::Rail()
print(" IsRailTile(): " + AIRail.IsRailTile(33411));
print(" BuildRailDepot(): " + AIRail.BuildRailDepot(0, 1));
print(" BuildRailDepot(): " + AIRail.BuildRailDepot(33411, 33411));
print(" BuildRailDepot(): " + AIRail.BuildRailDepot(33411, 33410));
print(" BuildRailDepot(): " + AIRail.BuildRailDepot(33411, 33414));
print(" BuildRailDepot(): " + AIRail.BuildRailDepot(33411, 33412));
print(" GetRailDepotFrontTile(): " + AIRail.GetRailDepotFrontTile(33411));
Expand Down Expand Up @@ -1203,6 +1204,7 @@ function Regression::Road()
print(" IsRoadTile(): " + AIRoad.IsRoadTile(33411));
print(" BuildRoadDepot(): " + AIRoad.BuildRoadDepot(0, 1));
print(" BuildRoadDepot(): " + AIRoad.BuildRoadDepot(33411, 33411));
print(" BuildRoadDepot(): " + AIRoad.BuildRoadDepot(33411, 33410));
print(" BuildRoadDepot(): " + AIRoad.BuildRoadDepot(33411, 33414));
print(" BuildRoadDepot(): " + AIRoad.BuildRoadDepot(33411, 33412));
print(" HasRoadType(Road): " + AIRoad.HasRoadType(33411, AIRoad.ROADTYPE_ROAD));
Expand Down
16 changes: 9 additions & 7 deletions regression/regression/result.txt
Expand Up @@ -7498,6 +7498,7 @@ ERROR: IsEnd() is invalid as Begin() is never called
BuildRailDepot(): false
BuildRailDepot(): false
BuildRailDepot(): true
BuildRailDepot(): true
BuildRailDepot(): false
GetRailDepotFrontTile(): 33412
IsBuildable(): false
Expand Down Expand Up @@ -7591,11 +7592,12 @@ ERROR: IsEnd() is invalid as Begin() is never called
BuildRoadDepot(): false
BuildRoadDepot(): false
BuildRoadDepot(): true
BuildRoadDepot(): true
BuildRoadDepot(): false
HasRoadType(Road): true
HasRoadType(Tram): false
GetLastError(): 260
GetLastErrorString(): ERR_AREA_NOT_CLEAR
GetLastError(): 259
GetLastErrorString(): ERR_ALREADY_BUILT
GetErrorCategory(): 1
IsRoadTile(): false
GetRoadDepotFrontTile(): 33412
Expand Down Expand Up @@ -9311,7 +9313,7 @@ ERROR: IsEnd() is invalid as Begin() is never called
IsStoppedInDepot(): false
--Accounting--
GetCosts(): -5947
Should be: -5947
Should be: -5946
GetName(): Road Vehicle #1
SetName(): true
GetName(): MyVehicleName
Expand Down Expand Up @@ -9408,11 +9410,11 @@ ERROR: IsEnd() is invalid as Begin() is never called
14 => 1
12 => 1
Age ListDump:
14 => 1
13 => 1
12 => 1
17 => 0
16 => 0
14 => 0
13 => 0
MaxAge ListDump:
16 => 10980
14 => 10980
Expand All @@ -9421,9 +9423,9 @@ ERROR: IsEnd() is invalid as Begin() is never called
12 => 5490
AgeLeft ListDump:
16 => 10980
14 => 10979
14 => 10980
17 => 7320
13 => 5489
13 => 5490
12 => 5489
CurrentSpeed ListDump:
12 => 27
Expand Down
42 changes: 31 additions & 11 deletions src/rail_cmd.cpp
Expand Up @@ -989,24 +989,44 @@ CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, RailType rai
cost.AddCost(_price[PR_BUILD_FOUNDATION]);
}

cost.AddCost(Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile));
if (cost.Failed()) return cost;
/* Allow the user to rotate the depot instead of having to destroy it and build it again */
bool rotate_existing_depot = false;
if (IsRailDepotTile(tile) && railtype == GetRailType(tile)) {
CommandCost ret = CheckTileOwnership(tile);
if (ret.Failed()) return ret;

if (dir == GetRailDepotDirection(tile)) return_cmd_error(STR_ERROR_ALREADY_BUILT);

ret = EnsureNoVehicleOnGround(tile);
if (ret.Failed()) return ret;

rotate_existing_depot = true;
}

if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
if (!rotate_existing_depot) {
cost.AddCost(Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile));
if (cost.Failed()) return cost;

if (!Depot::CanAllocateItem()) return CMD_ERROR;
if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);

if (!Depot::CanAllocateItem()) return CMD_ERROR;
}

if (flags & DC_EXEC) {
Depot *d = new Depot(tile);
d->build_date = TimerGameCalendar::date;
if (rotate_existing_depot) {
SetRailDepotExitDirection(tile, dir);
} else {
Depot *d = new Depot(tile);
d->build_date = TimerGameCalendar::date;

MakeRailDepot(tile, _current_company, d->index, dir, railtype);
MarkTileDirtyByTile(tile);
MakeDefaultName(d);
MakeRailDepot(tile, _current_company, d->index, dir, railtype);
MakeDefaultName(d);

Company::Get(_current_company)->infrastructure.rail[railtype]++;
DirtyCompanyInfrastructureWindows(_current_company);
Company::Get(_current_company)->infrastructure.rail[railtype]++;
DirtyCompanyInfrastructureWindows(_current_company);
}

MarkTileDirtyByTile(tile);
AddSideToSignalBuffer(tile, INVALID_DIAGDIR, _current_company);
YapfNotifyTrackLayoutChange(tile, DiagDirToDiagTrack(dir));
}
Expand Down
40 changes: 29 additions & 11 deletions src/rail_map.h
Expand Up @@ -530,19 +530,37 @@ static inline void MakeRailNormal(Tile t, Owner o, TrackBits b, RailType r)
t.m8() = r;
}

/**
* Sets the exit direction of a rail depot.
* @param tile Tile of the depot.
* @param dir Direction of the depot exit.
*/
static inline void SetRailDepotExitDirection(Tile tile, DiagDirection dir)
{
assert(IsRailDepotTile(tile));
SB(tile.m5(), 0, 2, dir);
}

static inline void MakeRailDepot(Tile t, Owner o, DepotID did, DiagDirection d, RailType r)
/**
* Make a rail depot.
* @param tile Tile to make a depot on.
* @param owner New owner of the depot.
* @param depot_id New depot ID.
* @param dir Direction of the depot exit.
* @param rail_type Rail type of the depot.
*/
static inline void MakeRailDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirection dir, RailType rail_type)
{
SetTileType(t, MP_RAILWAY);
SetTileOwner(t, o);
SetDockingTile(t, false);
t.m2() = did;
t.m3() = 0;
t.m4() = 0;
t.m5() = RAIL_TILE_DEPOT << 6 | d;
SB(t.m6(), 2, 4, 0);
t.m7() = 0;
t.m8() = r;
SetTileType(tile, MP_RAILWAY);
SetTileOwner(tile, owner);
SetDockingTile(tile, false);
tile.m2() = depot_id;
tile.m3() = 0;
tile.m4() = 0;
tile.m5() = RAIL_TILE_DEPOT << 6 | dir;
SB(tile.m6(), 2, 4, 0);
tile.m7() = 0;
tile.m8() = rail_type;
}

#endif /* RAIL_MAP_H */
42 changes: 32 additions & 10 deletions src/road_cmd.cpp
Expand Up @@ -1163,24 +1163,46 @@ CommandCost CmdBuildRoadDepot(DoCommandFlag flags, TileIndex tile, RoadType rt,
cost.AddCost(_price[PR_BUILD_FOUNDATION]);
}

cost.AddCost(Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile));
if (cost.Failed()) return cost;
/* Allow the user to rotate the depot instead of having to destroy it and build it again */
bool rotate_existing_depot = false;
if (IsRoadDepotTile(tile) && (HasRoadTypeTram(tile) ? rt == GetRoadTypeTram(tile) : rt == GetRoadTypeRoad(tile)))
{
CommandCost ret = CheckTileOwnership(tile);
if (ret.Failed()) return ret;

if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
if (dir == GetRoadDepotDirection(tile)) return_cmd_error(STR_ERROR_ALREADY_BUILT);

if (!Depot::CanAllocateItem()) return CMD_ERROR;
ret = EnsureNoVehicleOnGround(tile);
if (ret.Failed()) return ret;

rotate_existing_depot = true;
}

if (!rotate_existing_depot) {
cost.AddCost(Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile));
if (cost.Failed()) return cost;

if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);

if (!Depot::CanAllocateItem()) return CMD_ERROR;
}

if (flags & DC_EXEC) {
Depot *dep = new Depot(tile);
dep->build_date = TimerGameCalendar::date;
if (rotate_existing_depot) {
SetRoadDepotExitDirection(tile, dir);
} else {
Depot *dep = new Depot(tile);
dep->build_date = TimerGameCalendar::date;
MakeRoadDepot(tile, _current_company, dep->index, dir, rt);
MakeDefaultName(dep);
}

MarkTileDirtyByTile(tile);

/* A road depot has two road bits. */
UpdateCompanyRoadInfrastructure(rt, _current_company, ROAD_DEPOT_TRACKBIT_FACTOR);

MakeRoadDepot(tile, _current_company, dep->index, dir, rt);
MarkTileDirtyByTile(tile);
MakeDefaultName(dep);
}

cost.AddCost(_price[PR_BUILD_DEPOT_ROAD]);
return cost;
}
Expand Down
47 changes: 29 additions & 18 deletions src/road_map.h
Expand Up @@ -673,26 +673,37 @@ static inline void MakeRoadCrossing(Tile t, Owner road, Owner tram, Owner rail,
}

/**
* Make a road depot.
* @param t Tile to make a level crossing.
* @param owner New owner of the depot.
* @param did New depot ID.
* @param dir Direction of the depot exit.*
* @param rt Road type of the depot.
* Sets the exit direction of a road depot.
* @param tile Tile of the depot.
* @param dir Direction of the depot exit.
*/
static inline void MakeRoadDepot(Tile t, Owner owner, DepotID did, DiagDirection dir, RoadType rt)
static inline void SetRoadDepotExitDirection(Tile tile, DiagDirection dir)
{
SetTileType(t, MP_ROAD);
SetTileOwner(t, owner);
t.m2() = did;
t.m3() = 0;
t.m4() = INVALID_ROADTYPE;
t.m5() = ROAD_TILE_DEPOT << 6 | dir;
SB(t.m6(), 2, 4, 0);
t.m7() = owner;
t.m8() = INVALID_ROADTYPE << 6;
SetRoadType(t, GetRoadTramType(rt), rt);
SetRoadOwner(t, RTT_TRAM, owner);
assert(IsRoadDepotTile(tile));
SB(tile.m5(), 0, 2, dir);
}

/**
* Make a road depot.
* @param tile Tile to make a depot on.
* @param owner New owner of the depot.
* @param depot_id New depot ID.
* @param dir Direction of the depot exit.
* @param rail_type Road type of the depot.
*/
static inline void MakeRoadDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirection dir, RoadType rail_type)
{
SetTileType(tile, MP_ROAD);
SetTileOwner(tile, owner);
tile.m2() = depot_id;
tile.m3() = 0;
tile.m4() = INVALID_ROADTYPE;
tile.m5() = ROAD_TILE_DEPOT << 6 | dir;
SB(tile.m6(), 2, 4, 0);
tile.m7() = owner;
tile.m8() = INVALID_ROADTYPE << 6;
SetRoadType(tile, GetRoadTramType(rail_type), rail_type);
SetRoadOwner(tile, RTT_TRAM, owner);
}

#endif /* ROAD_MAP_H */