Initial support for NewGRF road stops (bus and lorry stops)
This commit is contained in:
@@ -58,6 +58,7 @@
|
||||
#include "zoning.h"
|
||||
#include "tunnelbridge_map.h"
|
||||
#include "cheat_type.h"
|
||||
#include "newgrf_roadstop.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
@@ -2049,10 +2050,12 @@ static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID statio
|
||||
* bit 3: #Axis of the road for drive-through stops.
|
||||
* bit 5..10: The roadtype.
|
||||
* bit 16..31: Station ID to join (NEW_STATION if build new one).
|
||||
* @param p3 bit 0..7: Roadstop class.
|
||||
* bit 8..15: Roadstopspec index.
|
||||
* @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)
|
||||
CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
|
||||
{
|
||||
bool type = HasBit(p2, 0);
|
||||
bool is_drive_through = HasBit(p2, 1);
|
||||
@@ -2066,6 +2069,19 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
|
||||
uint8 width = (uint8)GB(p1, 0, 8);
|
||||
uint8 length = (uint8)GB(p1, 8, 8);
|
||||
|
||||
RoadStopClassID spec_class = Extract<RoadStopClassID, 0, 8>(p3);
|
||||
byte spec_index = GB(p3, 8, 8);
|
||||
|
||||
/* Check if the given station class is valid */
|
||||
if ((uint)spec_class >= RoadStopClass::GetClassCount() || spec_class == ROADSTOP_CLASS_WAYP) return CMD_ERROR;
|
||||
if (spec_index >= RoadStopClass::Get(spec_class)->GetSpecCount()) return CMD_ERROR;
|
||||
|
||||
const RoadStopSpec *roadstopspec = RoadStopClass::Get(spec_class)->GetSpec(spec_index);
|
||||
if (roadstopspec != nullptr) {
|
||||
if (type && roadstopspec->stop_type != ROADSTOPTYPE_FREIGHT && roadstopspec->stop_type != ROADSTOPTYPE_ALL) return CMD_ERROR;
|
||||
if (!type && roadstopspec->stop_type != ROADSTOPTYPE_PASSENGER && roadstopspec->stop_type != ROADSTOPTYPE_ALL) return CMD_ERROR;
|
||||
}
|
||||
|
||||
/* Check if the requested road stop is too big */
|
||||
if (width > _settings_game.station.station_spread || length > _settings_game.station.station_spread) return_cmd_error(STR_ERROR_STATION_TOO_SPREAD_OUT);
|
||||
/* Check for incorrect width / length. */
|
||||
@@ -2112,6 +2128,10 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
|
||||
ret = BuildStationPart(&st, flags, reuse, roadstop_area, STATIONNAMING_ROAD);
|
||||
if (ret.Failed()) return ret;
|
||||
|
||||
/* Check if we can allocate a custom stationspec to this station */
|
||||
int specindex = AllocateRoadStopSpecToStation(roadstopspec, st, (flags & DC_EXEC) != 0);
|
||||
if (specindex == -1) return_cmd_error(STR_ERROR_TOO_MANY_STATION_SPECS);
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
/* Check every tile in the area. */
|
||||
for (TileIndex cur_tile : roadstop_area) {
|
||||
@@ -2169,6 +2189,9 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
|
||||
}
|
||||
Company::Get(st->owner)->infrastructure.station++;
|
||||
|
||||
SetCustomRoadStopSpecIndex(cur_tile, specindex);
|
||||
if (roadstopspec != nullptr) st->SetRoadStopRandomBits(cur_tile, GB(Random(), 0, 4));
|
||||
|
||||
MarkTileDirtyByTile(cur_tile);
|
||||
UpdateRoadCachedOneWayStatesAroundTile(cur_tile);
|
||||
}
|
||||
@@ -2222,10 +2245,15 @@ CommandCost RemoveRoadWaypointStop(TileIndex tile, DoCommandFlag flags)
|
||||
Company::Get(wp->owner)->infrastructure.station--;
|
||||
DirtyCompanyInfrastructureWindows(wp->owner);
|
||||
|
||||
uint specindex = GetCustomRoadStopSpecIndex(tile);
|
||||
|
||||
DoClearSquare(tile);
|
||||
|
||||
wp->rect.AfterRemoveTile(wp, tile);
|
||||
|
||||
wp->RemoveRoadStopRandomBits(tile);
|
||||
DeallocateRoadStopSpecFromStation(wp, specindex);
|
||||
|
||||
MakeRoadWaypointStationAreaSmaller(wp, wp->road_waypoint_area);
|
||||
|
||||
UpdateStationSignCoord(wp);
|
||||
@@ -2311,6 +2339,8 @@ CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags)
|
||||
Company::Get(st->owner)->infrastructure.station--;
|
||||
DirtyCompanyInfrastructureWindows(st->owner);
|
||||
|
||||
uint specindex = GetCustomRoadStopSpecIndex(tile);
|
||||
|
||||
if (IsDriveThroughStopTile(tile)) {
|
||||
/* Clears the tile for us */
|
||||
cur_stop->ClearDriveThrough();
|
||||
@@ -2332,6 +2362,9 @@ CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags)
|
||||
|
||||
st->AfterStationTileSetChange(false, is_truck ? STATION_TRUCK: STATION_BUS);
|
||||
|
||||
st->RemoveRoadStopRandomBits(tile);
|
||||
DeallocateRoadStopSpecFromStation(st, specindex);
|
||||
|
||||
/* Update the tile area of the truck/bus stop */
|
||||
if (is_truck) {
|
||||
st->truck_station.Clear();
|
||||
@@ -3417,25 +3450,38 @@ draw_default_foundation:
|
||||
if (IsAnyRoadStop(ti->tile)) {
|
||||
RoadType road_rt = GetRoadTypeRoad(ti->tile);
|
||||
RoadType tram_rt = GetRoadTypeTram(ti->tile);
|
||||
const RoadTypeInfo* road_rti = road_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(road_rt);
|
||||
const RoadTypeInfo* tram_rti = tram_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(tram_rt);
|
||||
const RoadTypeInfo *road_rti = road_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(road_rt);
|
||||
const RoadTypeInfo *tram_rti = tram_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(tram_rt);
|
||||
|
||||
Axis axis = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? AXIS_X : AXIS_Y;
|
||||
DiagDirection dir = GetRoadStopDir(ti->tile);
|
||||
|
||||
const RoadStopSpec *stopspec = GetRoadStopSpec(ti->tile);
|
||||
if (stopspec != nullptr) {
|
||||
int view = dir;
|
||||
if (IsDriveThroughStopTile(ti->tile)) view += 4;
|
||||
st = BaseStation::GetByTile(ti->tile);
|
||||
RoadStopResolverObject object(stopspec, st, ti->tile, nullptr, GetStationType(ti->tile), view);
|
||||
const SpriteGroup *group = object.Resolve();
|
||||
const DrawTileSprites *dts = ((const TileLayoutSpriteGroup *)group)->ProcessRegisters(nullptr);
|
||||
t = dts;
|
||||
}
|
||||
|
||||
if (IsDriveThroughStopTile(ti->tile)) {
|
||||
Axis axis = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? AXIS_X : AXIS_Y;
|
||||
uint sprite_offset = axis == AXIS_X ? 1 : 0;
|
||||
if (stopspec == nullptr || (stopspec->draw_mode & ROADSTOP_DRAW_MODE_OVERLAY) != 0) {
|
||||
uint sprite_offset = axis == AXIS_X ? 1 : 0;
|
||||
DrawRoadOverlays(ti, PAL_NONE, road_rti, tram_rti, sprite_offset, sprite_offset);
|
||||
|
||||
DrawRoadOverlays(ti, PAL_NONE, road_rti, tram_rti, sprite_offset, sprite_offset);
|
||||
|
||||
DisallowedRoadDirections drd = GetDriveThroughStopDisallowedRoadDirections(ti->tile);
|
||||
if (drd != DRD_NONE) {
|
||||
DrawGroundSpriteAt(SPR_ONEWAY_BASE + drd - 1 + ((axis == AXIS_X) ? 0 : 3), PAL_NONE, 8, 8, 0);
|
||||
DisallowedRoadDirections drd = GetDriveThroughStopDisallowedRoadDirections(ti->tile);
|
||||
if (drd != DRD_NONE) {
|
||||
DrawGroundSpriteAt(SPR_ONEWAY_BASE + drd - 1 + ((axis == AXIS_X) ? 0 : 3), PAL_NONE, 8, 8, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Non-drivethrough road stops are only valid for roads. */
|
||||
assert_tile(road_rt != INVALID_ROADTYPE && tram_rt == INVALID_ROADTYPE, ti->tile);
|
||||
|
||||
if (road_rti->UsesOverlay()) {
|
||||
DiagDirection dir = GetRoadStopDir(ti->tile);
|
||||
if ((stopspec != nullptr && (stopspec->draw_mode & ROADSTOP_DRAW_MODE_ROAD) != 0) && road_rti->UsesOverlay()) {
|
||||
SpriteID ground = GetCustomRoadSprite(road_rti, ti->tile, ROTSG_ROADSTOP);
|
||||
DrawGroundSprite(ground + dir, PAL_NONE);
|
||||
}
|
||||
@@ -4519,6 +4565,7 @@ static uint UpdateStationWaiting(Station *st, CargoID type, uint amount, SourceT
|
||||
TriggerStationRandomisation(st, st->xy, SRT_NEW_CARGO, type);
|
||||
TriggerStationAnimation(st, st->xy, SAT_NEW_CARGO, type);
|
||||
AirportAnimationTrigger(st, AAT_STATION_NEW_CARGO, type);
|
||||
TriggerRoadStopRandomisation(st, st->xy, RSRT_NEW_CARGO, type);
|
||||
|
||||
SetWindowDirty(WC_STATION_VIEW, st->index);
|
||||
st->MarkTilesDirty(true);
|
||||
|
Reference in New Issue
Block a user