diff --git a/src/ai/api/ai_road.cpp b/src/ai/api/ai_road.cpp --- a/src/ai/api/ai_road.cpp +++ b/src/ai/api/ai_road.cpp @@ -528,8 +528,9 @@ static bool NeighbourHasReachableRoad(:: p2 |= drive_through ? 2 : 0; p2 |= road_veh_type == ROADVEHTYPE_TRUCK ? 1 : 0; p2 |= ::RoadTypeToRoadTypes(AIObject::GetRoadType()) << 2; + p2 |= entrance_dir << 6; p2 |= (AIStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16; - return AIObject::DoCommand(tile, entrance_dir, p2, CMD_BUILD_ROAD_STOP); + return AIObject::DoCommand(tile, 0, p2, CMD_BUILD_ROAD_STOP); } /* static */ bool AIRoad::BuildRoadStation(TileIndex tile, TileIndex front, RoadVehicleType road_veh_type, StationID station_id) diff --git a/src/command_func.h b/src/command_func.h --- a/src/command_func.h +++ b/src/command_func.h @@ -123,6 +123,7 @@ CommandCallback CcBuildRailTunnel; CommandCallback CcPlaySound1D; CommandCallback CcBuildRoadTunnel; CommandCallback CcRoadDepot; +CommandCallback CcRoadStop; /* train_gui.cpp */ CommandCallback CcBuildWagon; diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp --- a/src/network/network_command.cpp +++ b/src/network/network_command.cpp @@ -47,6 +47,7 @@ static CommandCallback * const _callback /* 0x14 */ CcGiveMoney, /* 0x15 */ CcCreateGroup, /* 0x16 */ CcFoundRandomTown, + /* 0x17 */ CcRoadStop, }; /** Local queue of packets */ diff --git a/src/road_gui.cpp b/src/road_gui.cpp --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -196,8 +196,6 @@ void CcRoadDepot(const CommandCost &resu SndPlayTileFx(SND_1F_SPLAT, tile); if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); BuildRoadOutsideStation(tile, dir); - /* For a drive-through road stop build connecting road for other entrance */ - if (HasBit(p2, 1)) BuildRoadOutsideStation(tile, ReverseDiagDir(dir)); } static void PlaceRoad_Depot(TileIndex tile) @@ -205,16 +203,42 @@ static void PlaceRoad_Depot(TileIndex ti DoCommandP(tile, _cur_roadtype << 2 | _road_depot_orientation, 0, CMD_BUILD_ROAD_DEPOT | CMD_MSG(_road_type_infos[_cur_roadtype].err_depot), CcRoadDepot); } +/** Command callback for building road stops. + * @param result Result of the build road stop command. + * @param tile Tile to build the stop at. + * @param p1 Unused. + * @param p2 bit 0: 0 For bus stops, 1 for truck stops. + * bit 1: 0 For normal stops, 1 for drive-through. + * bit 2..3: The roadtypes. + * bit 5: Allow stations directly adjacent to other stations. + * bit 6..7: Entrance direction (#DiagDirection). + * bit 16..31: Station ID to join (NEW_STATION if build new one). + * @see CmdBuildRoadStop + */ +void CcRoadStop(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +{ + if (result.Failed()) return; + + DiagDirection dir = (DiagDirection)GB(p2, 6, 2); + SndPlayTileFx(SND_1F_SPLAT, tile); + if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); + BuildRoadOutsideStation(tile, dir); + /* For a drive-through road stop build connecting road for other entrance. */ + if (HasBit(p2, 1)) BuildRoadOutsideStation(tile, ReverseDiagDir(dir)); +} + static void PlaceRoadStop(TileIndex tile, uint32 p2, uint32 cmd) { - uint32 p1 = _road_station_picker_orientation; + uint8 ddir = _road_station_picker_orientation; SB(p2, 16, 16, INVALID_STATION); // no station to join - if (p1 >= DIAGDIR_END) { - SetBit(p2, 1); // It's a drive-through stop - p1 -= DIAGDIR_END; // Adjust picker result to actual direction + if (ddir >= DIAGDIR_END) { + SetBit(p2, 1); // It's a drive-through stop. + ddir -= DIAGDIR_END; // Adjust picker result to actual direction. } - CommandContainer cmdcont = { tile, p1, p2, cmd, CcRoadDepot, "" }; + p2 |= ddir << 6; // Set the DiagDirecion into p2 bits 6 and 7. + + CommandContainer cmdcont = { tile, 0, p2, cmd, CcRoadStop, "" }; ShowSelectStationIfNeeded(cmdcont, TileArea(tile, 1, 1)); } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1586,17 +1586,18 @@ static RoadStop **FindRoadStopSpot(bool } } -/** Build a bus or truck stop - * @param tile tile to build the stop at - * @param flags operation to perform - * @param p1 entrance direction (DiagDirection) - * @param p2 bit 0: 0 for Bus stops, 1 for truck stops - * bit 1: 0 for normal, 1 for drive-through - * bit 2..3: the roadtypes - * bit 5: allow stations directly adjacent to other stations. - * bit 16..31: station ID to join (NEW_STATION if build new one) - * @param text unused - * @return the cost of this operation or an error +/** Build a bus or truck stop. + * @param tile Tile to build the stop at. + * @param flags Operation to perform. + * @param p1 Unused. + * @param p2 bit 0: 0 For bus stops, 1 for truck stops. + * bit 1: 0 For normal stops, 1 for drive-through. + * bit 2..3: The roadtypes. + * bit 5: Allow stations directly adjacent to other stations. + * bit 6..7: Entrance direction (DiagDirection). + * bit 16..31: Station ID to join (NEW_STATION if build new one). + * @param text Unused. + * @return The cost of this operation or an error. */ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { @@ -1618,16 +1619,18 @@ CommandCost CmdBuildRoadStop(TileIndex t /* Trams only have drive through stops */ if (!is_drive_through && HasBit(rts, ROADTYPE_TRAM)) return CMD_ERROR; - /* Saveguard the parameters */ - if (!IsValidDiagDirection((DiagDirection)p1)) return CMD_ERROR; - /* If it is a drive-through stop check for valid axis */ - if (is_drive_through && !IsValidAxis((Axis)p1)) return CMD_ERROR; + DiagDirection ddir = (DiagDirection)GB(p2, 6, 2); + + /* Safeguard the parameters. */ + if (!IsValidDiagDirection(ddir)) return CMD_ERROR; + /* If it is a drive-through stop, check for valid axis. */ + if (is_drive_through && !IsValidAxis((Axis)ddir)) return CMD_ERROR; /* Road bits in the wrong direction */ - if (build_over_road && (GetAllRoadBits(tile) & ((Axis)p1 == AXIS_X ? ROAD_Y : ROAD_X)) != 0) return_cmd_error(STR_ERROR_DRIVE_THROUGH_DIRECTION); + if (build_over_road && (GetAllRoadBits(tile) & (DiagDirToAxis(ddir) == AXIS_X ? ROAD_Y : ROAD_X)) != 0) return_cmd_error(STR_ERROR_DRIVE_THROUGH_DIRECTION); if (!CheckIfAuthorityAllowsNewStation(tile, flags)) return CMD_ERROR; - CommandCost cost = CheckFlatLandRoadStop(tile, flags, is_drive_through ? 5 << p1 : 1 << p1, build_over_road, rts); + CommandCost cost = CheckFlatLandRoadStop(tile, flags, is_drive_through ? 5 << ddir : 1 << ddir, build_over_road, rts); if (cost.Failed()) return cost; Station *st = NULL; @@ -1683,10 +1686,10 @@ CommandCost CmdBuildRoadStop(TileIndex t RoadStopType rs_type = type ? ROADSTOP_TRUCK : ROADSTOP_BUS; if (is_drive_through) { - MakeDriveThroughRoadStop(tile, st->owner, road_owner, tram_owner, st->index, rs_type, rts, (Axis)p1); + MakeDriveThroughRoadStop(tile, st->owner, road_owner, tram_owner, st->index, rs_type, rts, DiagDirToAxis(ddir)); road_stop->MakeDriveThrough(); } else { - MakeRoadStop(tile, st->owner, st->index, rs_type, rts, (DiagDirection)p1); + MakeRoadStop(tile, st->owner, st->index, rs_type, rts, ddir); } st->UpdateVirtCoord();