summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordP <dp@dpointer.org>2020-05-18 16:12:20 +0300
committerNiels Martin Hansen <nielsm@indvikleren.dk>2020-06-28 18:23:59 +0200
commit380fd8cab41bce0954bcd38eba5befe7057c8fa2 (patch)
treecda207cc0b27766bcfb388eeecdccea7281e7f4b /src
parentca2604c4e2cc972c2081db91a5e7b0bcdd092203 (diff)
downloadopenttd-380fd8cab41bce0954bcd38eba5befe7057c8fa2.tar.xz
Fix: Make subsidies scan tiles for town acceptance and production instead of using desync-prone town caches
Diffstat (limited to 'src')
-rw-r--r--src/subsidy.cpp28
-rw-r--r--src/subsidy_base.h1
2 files changed, 19 insertions, 10 deletions
diff --git a/src/subsidy.cpp b/src/subsidy.cpp
index e3913a289..25651a91e 100644
--- a/src/subsidy.cpp
+++ b/src/subsidy.cpp
@@ -328,20 +328,27 @@ bool FindSubsidyTownCargoRoute()
const Town *src_town = Town::GetRandom();
if (src_town->cache.population < SUBSIDY_CARGO_MIN_POPULATION) return false;
- CargoTypes town_cargo_produced = src_town->cargo_produced;
+ CargoArray town_cargo_produced = GetProductionAroundTiles(src_town->xy, 1, 1, SUBSIDY_TOWN_CARGO_RADIUS);
/* Passenger subsidies are not handled here. */
- ClrBit(town_cargo_produced, CT_PASSENGERS);
+ town_cargo_produced[CT_PASSENGERS] = 0;
+
+ uint8 cargo_count = 0;
+ for (CargoID i = 0; i < NUM_CARGO; i++) {
+ if (town_cargo_produced[i] > 0) cargo_count++;
+ }
/* No cargo produced at all? */
- if (town_cargo_produced == 0) return false;
+ if (cargo_count == 0) return false;
/* Choose a random cargo that is produced in the town. */
- uint8 cargo_number = RandomRange(CountBits(town_cargo_produced));
+ uint8 cargo_number = RandomRange(cargo_count);
CargoID cid;
- FOR_EACH_SET_CARGO_ID(cid, town_cargo_produced) {
- if (cargo_number == 0) break;
- cargo_number--;
+ for (cid = 0; cid < NUM_CARGO; cid++) {
+ if (town_cargo_produced[cid] > 0) {
+ if (cargo_number == 0) break;
+ cargo_number--;
+ }
}
/* Avoid using invalid NewGRF cargoes. */
@@ -416,17 +423,18 @@ bool FindSubsidyIndustryCargoRoute()
*/
bool FindSubsidyCargoDestination(CargoID cid, SourceType src_type, SourceID src)
{
- /* Choose a random destination. Only consider towns if they can accept the cargo. */
- SourceType dst_type = (HasBit(_town_cargoes_accepted, cid) && Chance16(1, 2)) ? ST_TOWN : ST_INDUSTRY;
+ /* Choose a random destination. */
+ SourceType dst_type = Chance16(1, 2) ? ST_TOWN : ST_INDUSTRY;
SourceID dst;
switch (dst_type) {
case ST_TOWN: {
/* Select a random town. */
const Town *dst_town = Town::GetRandom();
+ CargoArray town_cargo_accepted = GetAcceptanceAroundTiles(dst_town->xy, 1, 1, SUBSIDY_TOWN_CARGO_RADIUS);
/* Check if the town can accept this cargo. */
- if (!HasBit(dst_town->cargo_accepted_total, cid)) return false;
+ if (town_cargo_accepted[cid] >= 8) return false;
dst = dst_town->index;
break;
diff --git a/src/subsidy_base.h b/src/subsidy_base.h
index ef26f6416..ef9276433 100644
--- a/src/subsidy_base.h
+++ b/src/subsidy_base.h
@@ -57,5 +57,6 @@ static const uint SUBSIDY_PAX_MIN_POPULATION = 400; ///< Min. population of to
static const uint SUBSIDY_CARGO_MIN_POPULATION = 900; ///< Min. population of destination town for cargo route
static const uint SUBSIDY_MAX_PCT_TRANSPORTED = 42; ///< Subsidy will be created only for towns/industries with less % transported
static const uint SUBSIDY_MAX_DISTANCE = 70; ///< Max. length of subsidised route (DistanceManhattan)
+static const uint SUBSIDY_TOWN_CARGO_RADIUS = 6; ///< Extent of a tile area around town center when scanning for town cargo acceptance and production (6 ~= min catchmement + min station / 2)
#endif /* SUBSIDY_BASE_H */