Skip to content

Commit

Permalink
Allow converting track under trains when compatible with the new rail…
Browse files Browse the repository at this point in the history
… type
  • Loading branch information
JGRennison committed Sep 24, 2020
1 parent 481710f commit a18ebba
Showing 1 changed file with 65 additions and 1 deletion.
66 changes: 65 additions & 1 deletion src/rail_cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2027,6 +2027,70 @@ static Vehicle *UpdateTrainPowerProc(Vehicle *v, void *data)
return nullptr;
}

struct EnsureNoIncompatibleRailtypeTrainOnGroundData {
int z;
RailType type;
};

static Vehicle *EnsureNoIncompatibleRailtypeTrainProc(Vehicle *v, void *data)
{
const EnsureNoIncompatibleRailtypeTrainOnGroundData *procdata = (EnsureNoIncompatibleRailtypeTrainOnGroundData *)data;

if (v->z_pos > procdata->z) return nullptr;
if (HasBit(Train::From(v)->First()->compatible_railtypes, procdata->type)) return nullptr;

return v;
}

CommandCost EnsureNoIncompatibleRailtypeTrainOnGround(TileIndex tile, RailType type)
{
EnsureNoIncompatibleRailtypeTrainOnGroundData data = {
GetTileMaxPixelZ(tile),
type
};

if (HasVehicleOnPos(tile, VEH_TRAIN, &data, &EnsureNoIncompatibleRailtypeTrainProc)) {
return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY);
}
return CommandCost();
}

struct EnsureNoIncompatibleRailtypeTrainOnTrackBitsData {
TrackBits track_bits;
RailType type;
};

static Vehicle *EnsureNoIncompatibleRailtypeTrainOnTrackProc(Vehicle *v, void *data)
{
const EnsureNoIncompatibleRailtypeTrainOnTrackBitsData *procdata = (EnsureNoIncompatibleRailtypeTrainOnTrackBitsData *)data;
TrackBits rail_bits = procdata->track_bits;

Train *t = Train::From(v);
if (HasBit(t->First()->compatible_railtypes, procdata->type)) return nullptr;
if (rail_bits & TRACK_BIT_WORMHOLE) {
if (t->track & TRACK_BIT_WORMHOLE) return v;
rail_bits &= ~TRACK_BIT_WORMHOLE;
} else if (t->track & TRACK_BIT_WORMHOLE) {
return nullptr;
}
if ((t->track != rail_bits) && !TracksOverlap(t->track | rail_bits)) return nullptr;

return v;
}

CommandCost EnsureNoIncompatibleRailtypeTrainOnTrackBits(TileIndex tile, TrackBits track_bits, RailType type)
{
EnsureNoIncompatibleRailtypeTrainOnTrackBitsData data = {
track_bits,
type
};

if (HasVehicleOnPos(tile, VEH_TRAIN, &data, &EnsureNoIncompatibleRailtypeTrainOnTrackProc)) {
return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY);
}
return CommandCost();
}

/**
* Convert one rail type to the other. You can convert normal rail to
* monorail/maglev easily or vice-versa.
Expand Down Expand Up @@ -2119,7 +2183,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
* Tunnels and bridges have special check later */
if (tt != MP_TUNNELBRIDGE) {
if (!IsCompatibleRail(type, totype) || !IsCompatibleRail(secondary_type, totype)) {
CommandCost ret = IsPlainRailTile(tile) ? EnsureNoTrainOnTrackBits(tile, GetTrackBits(tile)) : EnsureNoVehicleOnGround(tile);
CommandCost ret = IsPlainRailTile(tile) ? EnsureNoIncompatibleRailtypeTrainOnTrackBits(tile, GetTrackBits(tile), totype) : EnsureNoIncompatibleRailtypeTrainOnGround(tile, totype);
if (ret.Failed()) {
error = ret;
continue;
Expand Down

0 comments on commit a18ebba

Please sign in to comment.