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);