diff options
author | Michael Lutz <michi@icosahedron.de> | 2021-11-15 00:03:01 +0100 |
---|---|---|
committer | Michael Lutz <michi@icosahedron.de> | 2021-12-16 22:28:32 +0100 |
commit | 46bd2f1cedde365218a3f1a52116fe169587af89 (patch) | |
tree | 633af4662d44346fc74abe4646b22c01df42e78a /src/road_cmd.cpp | |
parent | 55170ae703dd2f55ae5c2151aa97dd12da1e917e (diff) | |
download | openttd-46bd2f1cedde365218a3f1a52116fe169587af89.tar.xz |
Codechange: Un-bitstuff remaining transport infrastructure commands.
Diffstat (limited to 'src/road_cmd.cpp')
-rw-r--r-- | src/road_cmd.cpp | 130 |
1 files changed, 50 insertions, 80 deletions
diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index ece49676b..e160a2b84 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -606,14 +606,13 @@ static CommandCost CheckRoadSlope(Slope tileh, RoadBits *pieces, RoadBits existi * Build a piece of road. * @param flags operation to perform * @param tile tile where to build road - * @param p1 bit 0..3 road pieces to build (RoadBits) - * bit 4..9 road type - * bit 11..12 disallowed directions to toggle - * @param p2 the town that is building the road (0 if not applicable) - * @param text unused + * @param pieces road pieces to build (RoadBits) + * @param rt road type + * @param toggle_drd disallowed directions to toggle + * @param town_id the town that is building the road (0 if not applicable) * @return the cost of this operation or an error */ -CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, RoadBits pieces, RoadType rt, DisallowedRoadDirections toggle_drd, TownID town_id) { CompanyID company = _current_company; CommandCost cost(EXPENSES_CONSTRUCTION); @@ -623,10 +622,10 @@ CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero * if a non-company is building the road */ - if ((Company::IsValidID(company) && p2 != 0) || (company == OWNER_TOWN && !Town::IsValidID(p2)) || (company == OWNER_DEITY && p2 != 0)) return CMD_ERROR; + if ((Company::IsValidID(company) && town_id != 0) || (company == OWNER_TOWN && !Town::IsValidID(town_id)) || (company == OWNER_DEITY && town_id != 0)) return CMD_ERROR; if (company != OWNER_TOWN) { const Town *town = CalcClosestTownFromTile(tile); - p2 = (town != nullptr) ? town->index : INVALID_TOWN; + town_id = (town != nullptr) ? town->index : INVALID_TOWN; if (company == OWNER_DEITY) { company = OWNER_TOWN; @@ -638,16 +637,10 @@ CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 } } - RoadBits pieces = Extract<RoadBits, 0, 4>(p1); - /* do not allow building 'zero' road bits, code wouldn't handle it */ - if (pieces == ROAD_NONE) return CMD_ERROR; - - RoadType rt = Extract<RoadType, 4, 6>(p1); + if (pieces == ROAD_NONE || !IsEnumValid(pieces) || !IsEnumValid(toggle_drd)) return CMD_ERROR; if (!ValParamRoadType(rt)) return CMD_ERROR; - DisallowedRoadDirections toggle_drd = Extract<DisallowedRoadDirections, 11, 2>(p1); - Slope tileh = GetTileSlope(tile); RoadTramType rtt = GetRoadTramType(rt); @@ -785,7 +778,7 @@ CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /* Always add road to the roadtypes (can't draw without it) */ bool reserved = HasBit(GetRailReservationTrackBits(tile), railtrack); - MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetRailType(tile), rtt == RTT_ROAD ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, p2); + MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetRailType(tile), rtt == RTT_ROAD ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, town_id); SetCrossingReservation(tile, reserved); UpdateLevelCrossing(tile, false); MarkTileDirtyByTile(tile); @@ -870,7 +863,7 @@ do_clear:; if (HasPowerOnRoad(rt, existing_rt)) { rt = existing_rt; } else if (HasPowerOnRoad(existing_rt, rt)) { - CommandCost ret = Command<CMD_CONVERT_ROAD>::Do(flags, tile, tile, rt, {}); + CommandCost ret = Command<CMD_CONVERT_ROAD>::Do(flags, tile, tile, rt); if (ret.Failed()) return ret; cost.AddCost(ret); } else { @@ -895,7 +888,7 @@ do_clear:; if (existing == ROAD_NONE || rttype == ROAD_TILE_CROSSING) { SetRoadType(tile, rtt, rt); SetRoadOwner(tile, rtt, company); - if (rtt == RTT_ROAD) SetTownIndex(tile, p2); + if (rtt == RTT_ROAD) SetTownIndex(tile, town_id); } if (rttype != ROAD_TILE_CROSSING) SetRoadBits(tile, existing | pieces, rtt); break; @@ -927,7 +920,7 @@ do_clear:; } default: - MakeRoadNormal(tile, pieces, (rtt == RTT_ROAD) ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, p2, company, company); + MakeRoadNormal(tile, pieces, (rtt == RTT_ROAD) ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, town_id, company, company); break; } @@ -971,49 +964,40 @@ static bool CanConnectToRoad(TileIndex tile, RoadType rt, DiagDirection dir) * Build a long piece of road. * @param flags operation to perform * @param start_tile start tile of drag (the building cost will appear over this tile) - * @param p1 end tile of drag - * @param p2 various bitstuffed elements - * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1). Only used if bit 6 is set or if we are building a single tile - * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2). Only used if bit 6 is set or if we are building a single tile - * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4) - * - p2 = (bit 3..8) - road type - * - p2 = (bit 10) - set road direction - * - p2 = (bit 11) - defines two different behaviors for this command: - * - 0 = Build up to an obstacle. Do not build the first and last roadbits unless they can be connected to something, or if we are building a single tile - * - 1 = Fail if an obstacle is found. Always take into account bit 0 and 1. This behavior is used for scripts - * @param text unused + * @param end_tile end tile of drag + * @param rt road type + * @param axis direction + * @param drd set road direction + * @param start_half start tile starts in the 2nd half of tile (p2 & 1). Only used if \c is_ai is set or if we are building a single tile + * @param end_half end tile starts in the 2nd half of tile (p2 & 2). Only used if \c is_ai is set or if we are building a single tile + * @param is_ai defines two different behaviors for this command: + * - false = Build up to an obstacle. Do not build the first and last roadbits unless they can be connected to something, or if we are building a single tile + * - true = Fail if an obstacle is found. Always take into account start_half and end_half. This behavior is used for scripts * @return the cost of this operation or an error */ -CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, TileIndex end_tile, RoadType rt, Axis axis, DisallowedRoadDirections drd, bool start_half, bool end_half, bool is_ai) { - DisallowedRoadDirections drd = DRD_NORTHBOUND; + if (end_tile >= MapSize()) return CMD_ERROR; - if (p1 >= MapSize()) return CMD_ERROR; - TileIndex end_tile = p1; + if (!ValParamRoadType(rt) || !IsEnumValid(axis) || !IsEnumValid(drd)) return CMD_ERROR; - RoadType rt = Extract<RoadType, 3, 6>(p2); - if (!ValParamRoadType(rt)) return CMD_ERROR; - - Axis axis = Extract<Axis, 2, 1>(p2); /* Only drag in X or Y direction dictated by the direction variable */ if (axis == AXIS_X && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis if (axis == AXIS_Y && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis DiagDirection dir = AxisToDiagDir(axis); - /* Swap direction, also the half-tile drag var (bit 0 and 1) */ - if (start_tile > end_tile || (start_tile == end_tile && HasBit(p2, 0))) { + /* Swap direction, also the half-tile drag vars. */ + if (start_tile > end_tile || (start_tile == end_tile && start_half)) { dir = ReverseDiagDir(dir); - p2 ^= 3; - drd = DRD_SOUTHBOUND; + std::swap(start_half, end_half); + if (drd == DRD_NORTHBOUND || drd == DRD_SOUTHBOUND) drd ^= DRD_BOTH; } /* On the X-axis, we have to swap the initial bits, so they * will be interpreted correctly in the GTTS. Furthermore * when you just 'click' on one tile to build them. */ - if ((axis == AXIS_Y) == (start_tile == end_tile && HasBit(p2, 0) == HasBit(p2, 1))) drd ^= DRD_BOTH; - /* No disallowed direction bits have to be toggled */ - if (!HasBit(p2, 10)) drd = DRD_NONE; + if ((drd == DRD_NORTHBOUND || drd == DRD_SOUTHBOUND) && (axis == AXIS_Y) == (start_tile == end_tile && start_half == end_half)) drd ^= DRD_BOTH; CommandCost cost(EXPENSES_CONSTRUCTION); CommandCost last_error = CMD_ERROR; @@ -1021,7 +1005,6 @@ CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p bool had_bridge = false; bool had_tunnel = false; bool had_success = false; - bool is_ai = HasBit(p2, 11); /* Start tile is the first tile clicked by the user. */ for (;;) { @@ -1037,11 +1020,11 @@ CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p } } else { /* Road parts only have to be built at the start tile or at the end tile. */ - if (tile == end_tile && !HasBit(p2, 1)) bits &= DiagDirToRoadBits(ReverseDiagDir(dir)); - if (tile == start_tile && HasBit(p2, 0)) bits &= DiagDirToRoadBits(dir); + if (tile == end_tile && !end_half) bits &= DiagDirToRoadBits(ReverseDiagDir(dir)); + if (tile == start_tile && start_half) bits &= DiagDirToRoadBits(dir); } - CommandCost ret = Command<CMD_BUILD_ROAD>::Do(flags, tile, drd << 11 | rt << 4 | bits, 0, {}); + CommandCost ret = Command<CMD_BUILD_ROAD>::Do(flags, tile, bits, rt, drd, 0); if (ret.Failed()) { last_error = ret; if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT) { @@ -1080,36 +1063,28 @@ CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p * Remove a long piece of road. * @param flags operation to perform * @param start_tile start tile of drag - * @param p1 end tile of drag - * @param p2 various bitstuffed elements - * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1) - * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2) - * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4) - * - p2 = (bit 3 - 8) - road type - * @param text unused + * @param end_tile end tile of drag + * @param rt road type + * @param axis direction + * @param start_half start tile starts in the 2nd half of tile + * @param end_half end tile starts in the 2nd half of tile (p2 & 2) * @return the cost of this operation or an error */ -CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, TileIndex end_tile, RoadType rt, Axis axis, bool start_half, bool end_half) { CommandCost cost(EXPENSES_CONSTRUCTION); - if (p1 >= MapSize()) return CMD_ERROR; + if (end_tile >= MapSize()) return CMD_ERROR; + if (!ValParamRoadType(rt) || !IsEnumValid(axis)) return CMD_ERROR; - TileIndex end_tile = p1; - RoadType rt = Extract<RoadType, 3, 6>(p2); - if (!ValParamRoadType(rt)) return CMD_ERROR; - - Axis axis = Extract<Axis, 2, 1>(p2); /* Only drag in X or Y direction dictated by the direction variable */ if (axis == AXIS_X && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis if (axis == AXIS_Y && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis - /* Swap start and ending tile, also the half-tile drag var (bit 0 and 1) */ - if (start_tile > end_tile || (start_tile == end_tile && HasBit(p2, 0))) { - TileIndex t = start_tile; - start_tile = end_tile; - end_tile = t; - p2 ^= IsInsideMM(p2 & 3, 1, 3) ? 3 : 0; + /* Swap start and ending tile, also the half-tile drag vars. */ + if (start_tile > end_tile || (start_tile == end_tile && start_half)) { + std::swap(start_tile, end_tile); + std::swap(start_half, end_half); } Money money_available = GetAvailableMoneyForCommand(); @@ -1121,8 +1096,8 @@ CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 for (;;) { RoadBits bits = AxisToRoadBits(axis); - if (tile == end_tile && !HasBit(p2, 1)) bits &= ROAD_NW | ROAD_NE; - if (tile == start_tile && HasBit(p2, 0)) bits &= ROAD_SE | ROAD_SW; + if (tile == end_tile && !end_half) bits &= ROAD_NW | ROAD_NE; + if (tile == start_tile && start_half) bits &= ROAD_SE | ROAD_SW; /* try to remove the halves. */ if (bits != 0) { @@ -1132,7 +1107,7 @@ CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 if (flags & DC_EXEC) { money_spent += ret.GetCost(); if (money_spent > 0 && money_spent > money_available) { - _additional_cash_required = Command<CMD_REMOVE_LONG_ROAD>::Do(flags & ~DC_EXEC, start_tile, end_tile, p2, {}).GetCost(); + _additional_cash_required = Command<CMD_REMOVE_LONG_ROAD>::Do(flags & ~DC_EXEC, start_tile, end_tile, rt, axis, start_half, end_half).GetCost(); return cost; } RemoveRoad(tile, flags, bits, rtt, true, false); @@ -2342,17 +2317,12 @@ static void ConvertRoadTypeOwner(TileIndex tile, uint num_pieces, Owner owner, R * * @param flags operation to perform * @param tile end tile of road conversion drag - * @param p1 start tile of drag - * @param p2 various bitstuffed elements: - * - p2 = (bit 0..5) new roadtype to convert to. - * @param text unused + * @param area_start start tile of drag + * @param to_type new roadtype to convert to. * @return the cost of this operation or an error */ -CommandCost CmdConvertRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdConvertRoad(DoCommandFlag flags, TileIndex tile, TileIndex area_start, RoadType to_type) { - RoadType to_type = Extract<RoadType, 0, 6>(p2); - - TileIndex area_start = p1; TileIndex area_end = tile; if (!ValParamRoadType(to_type)) return CMD_ERROR; |