From cb573a152399d2f8a88f82ad704ff0057bd28540 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Thu, 24 Feb 2022 21:13:46 +0000 Subject: [PATCH] Add road stop property to set cost multipliers --- docs/newgrf-roadstops.html | 7 +++++++ src/newgrf.cpp | 8 ++++++++ src/newgrf_extension.cpp | 1 + src/newgrf_extension.h | 1 + src/newgrf_roadstop.h | 15 +++++++++++++++ src/station_cmd.cpp | 17 ++++++++++++++--- src/table/newgrf_debug_data.h | 2 ++ src/waypoint_cmd.cpp | 8 +++++++- 8 files changed, 55 insertions(+), 4 deletions(-) diff --git a/docs/newgrf-roadstops.html b/docs/newgrf-roadstops.html index fa52e667fe..88ab9f947c 100644 --- a/docs/newgrf-roadstops.html +++ b/docs/newgrf-roadstops.html @@ -162,6 +162,13 @@ Each set of flags is 1 byte, the total property length is 6 bytes.
Each set of flags has the format described in the bridge_pillar_flags property section.

+

Road stop cost multipliers (15, or mappable property: roadstop_cost_multipliers)

+

This property sets the build and removal cost multipliers.
+ The first byte is the build cost multiplier.
+ The second byte is the removal cost multiplier.
+ The total property length is 2 bytes.
+ A value of 16 produces a build or removal cost the same as non-NewGRF road stops.. +

The 6 road stop views/rotations are described below.
diff --git a/src/newgrf.cpp b/src/newgrf.cpp index adf027ce1b..799c2c082e 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -5088,6 +5088,14 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, const } break; + case A0RPI_ROADSTOP_COST_MULTIPLIERS: + if (MappedPropertyLengthMismatch(buf, 2, mapping_entry)) break; + FALLTHROUGH; + case 0x15: // Cost multipliers + rs->build_cost_multiplier = buf->ReadByte(); + rs->clear_cost_multiplier = buf->ReadByte(); + break; + default: ret = CIR_UNKNOWN; break; diff --git a/src/newgrf_extension.cpp b/src/newgrf_extension.cpp index 54c3a1bc00..af67203680 100644 --- a/src/newgrf_extension.cpp +++ b/src/newgrf_extension.cpp @@ -103,6 +103,7 @@ extern const GRFPropertyMapDefinition _grf_action0_remappable_properties[] = { GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_GENERAL_FLAGS, "roadstop_general_flags"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_MIN_BRIDGE_HEIGHT, "roadstop_min_bridge_height"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_DISALLOWED_BRIDGE_PILLARS, "roadstop_disallowed_bridge_pillars"), + GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_COST_MULTIPLIERS, "roadstop_cost_multipliers"), GRFPropertyMapDefinition(), }; diff --git a/src/newgrf_extension.h b/src/newgrf_extension.h index 530f75ddb0..630da1aed8 100644 --- a/src/newgrf_extension.h +++ b/src/newgrf_extension.h @@ -52,6 +52,7 @@ enum Action0RemapPropertyIds { A0RPI_ROADSTOP_GENERAL_FLAGS, A0RPI_ROADSTOP_MIN_BRIDGE_HEIGHT, A0RPI_ROADSTOP_DISALLOWED_BRIDGE_PILLARS, + A0RPI_ROADSTOP_COST_MULTIPLIERS, }; diff --git a/src/newgrf_roadstop.h b/src/newgrf_roadstop.h index b0879c4647..81f73b07a3 100644 --- a/src/newgrf_roadstop.h +++ b/src/newgrf_roadstop.h @@ -145,6 +145,21 @@ struct RoadStopSpec { byte bridge_height[6]; ///< Minimum height for a bridge above, 0 for none byte bridge_disallowed_pillars[6]; ///< Disallowed pillar flags for a bridge above + uint8 build_cost_multiplier = 16; ///< Build cost multiplier per tile. + uint8 clear_cost_multiplier = 16; ///< Clear cost multiplier per tile. + + /** + * Get the cost for building a road stop of this type. + * @return The cost for building. + */ + Money GetBuildCost(Price category) const { return GetPrice(category, this->build_cost_multiplier, this->grf_prop.grffile, -4); } + + /** + * Get the cost for clearing a road stop of this type. + * @return The cost for clearing. + */ + Money GetClearCost(Price category) const { return GetPrice(category, this->clear_cost_multiplier, this->grf_prop.grffile, -4); } + static const RoadStopSpec *Get(uint16 index); }; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index bbcf2226a6..5b59272dbe 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2124,7 +2124,13 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin if (ret.Failed()) return ret; /* Total road stop cost. */ - CommandCost cost(EXPENSES_CONSTRUCTION, roadstop_area.w * roadstop_area.h * _price[type ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS]); + Money unit_cost; + if (roadstopspec != nullptr) { + unit_cost = roadstopspec->GetBuildCost(type ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS); + } else { + unit_cost = _price[type ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS]; + } + CommandCost cost(EXPENSES_CONSTRUCTION, roadstop_area.w * roadstop_area.h * unit_cost); StationID est = INVALID_STATION; ret = CheckFlatLandRoadStop(roadstop_area, roadstopspec, flags, is_drive_through ? 5 << axis : 1 << ddir, is_drive_through, type ? STATION_TRUCK : STATION_BUS, axis, &est, rt, false); if (ret.Failed()) return ret; @@ -2266,6 +2272,8 @@ CommandCost RemoveRoadWaypointStop(TileIndex tile, DoCommandFlag flags, int repl if (ret.Failed()) return ret; } + const RoadStopSpec *spec = GetRoadStopSpec(tile); + if (flags & DC_EXEC) { /* Update company infrastructure counts. */ for (RoadTramType rtt : _roadtramtypes) { @@ -2306,7 +2314,7 @@ CommandCost RemoveRoadWaypointStop(TileIndex tile, DoCommandFlag flags, int repl NotifyRoadLayoutChanged(false); } - return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_STATION_TRUCK]); + return CommandCost(EXPENSES_CONSTRUCTION, spec != nullptr ? spec->GetClearCost(PR_CLEAR_STATION_TRUCK) : _price[PR_CLEAR_STATION_TRUCK]); } /** @@ -2352,6 +2360,8 @@ CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags, int replacement_ if (ret.Failed()) return ret; } + const RoadStopSpec *spec = GetRoadStopSpec(tile); + if (flags & DC_EXEC) { ZoningMarkDirtyStationCoverageArea(st); if (*primary_stop == cur_stop) { @@ -2419,7 +2429,8 @@ CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags, int replacement_ NotifyRoadLayoutChanged(false); } - return CommandCost(EXPENSES_CONSTRUCTION, _price[is_truck ? PR_CLEAR_STATION_TRUCK : PR_CLEAR_STATION_BUS]); + Price category = is_truck ? PR_CLEAR_STATION_TRUCK : PR_CLEAR_STATION_BUS; + return CommandCost(EXPENSES_CONSTRUCTION, spec != nullptr ? spec->GetClearCost(category) : _price[category]); } /** diff --git a/src/table/newgrf_debug_data.h b/src/table/newgrf_debug_data.h index b98688f554..5e3f70ac37 100644 --- a/src/table/newgrf_debug_data.h +++ b/src/table/newgrf_debug_data.h @@ -1435,6 +1435,8 @@ class NIHRoadStop : public NIHelper { output.print(buffer); seprintf(buffer, lastof(buffer), " spec: callback mask: %X, flags: %X, intl flags: %X", spec->callback_mask, spec->flags, spec->internal_flags); output.print(buffer); + seprintf(buffer, lastof(buffer), " spec: build: %u, clear: %u", spec->build_cost_multiplier, spec->clear_cost_multiplier); + output.print(buffer); seprintf(buffer, lastof(buffer), " animation: frames: %u, status: %u, speed: %u, triggers: 0x%X", spec->animation.frames, spec->animation.status, spec->animation.speed, spec->animation.triggers); output.print(buffer); diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index a54daa3aa8..1b2af0b5af 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -378,7 +378,13 @@ CommandCost CmdBuildRoadWaypoint(TileIndex start_tile, DoCommandFlag flags, uint TileArea roadstop_area(start_tile, width, height); /* Total road stop cost. */ - CommandCost cost(EXPENSES_CONSTRUCTION, roadstop_area.w * roadstop_area.h * _price[PR_BUILD_STATION_TRUCK]); + Money unit_cost; + if (spec != nullptr) { + unit_cost = spec->GetBuildCost(PR_BUILD_STATION_TRUCK); + } else { + unit_cost = _price[PR_BUILD_STATION_TRUCK]; + } + CommandCost cost(EXPENSES_CONSTRUCTION, roadstop_area.w * roadstop_area.h * unit_cost); StationID est = INVALID_STATION; extern CommandCost CheckFlatLandRoadStop(TileArea tile_area, const RoadStopSpec *spec, DoCommandFlag flags, uint invalid_dirs, bool is_drive_through, StationType station_type, Axis axis, StationID *station, RoadType rt, bool require_road); CommandCost ret = CheckFlatLandRoadStop(roadstop_area, spec, flags, 5 << axis, true, STATION_ROADWAYPOINT, axis, &est, INVALID_ROADTYPE, true);