Changeset - r24300:dc74d00736ca
[Not reviewed]
master
0 2 0
dP - 4 years ago 2020-05-18 13:12:20
dp@dpointer.org
Fix: Make subsidies scan tiles for town acceptance and production instead of using desync-prone town caches
2 files changed with 19 insertions and 10 deletions:
0 comments (0 inline, 0 general)
src/subsidy.cpp
Show inline comments
 
@@ -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;
src/subsidy_base.h
Show inline comments
 
@@ -57,5 +57,6 @@ static const uint SUBSIDY_PAX_MIN_POPULA
 
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 */
0 comments (0 inline, 0 general)