Changeset - r28643:dde0de537357
[Not reviewed]
master
0 2 0
Peter Nelson - 4 months ago 2024-01-07 19:32:41
peter1138@openttd.org
Change: Towns generate cargo based on town production effect.

This replaces the fixed handling of passengers and mail.
2 files changed with 72 insertions and 40 deletions:
0 comments (0 inline, 0 general)
src/town_cmd.cpp
Show inline comments
 
@@ -541,9 +541,52 @@ static void TownGenerateCargo(Town *t, C
 
	amount = ScaleByCargoScale(amount, true);
 

	
 
	/* Actually generate cargo and update town statistics. */
 
	uint moved = MoveGoodsToStation(ct, amount, SourceType::Town, t->index, stations.GetStations());
 
	t->supplied[ct].new_max += amount;
 
	t->supplied[ct].new_act += moved;
 
	t->supplied[ct].new_act += MoveGoodsToStation(ct, amount, SourceType::Town, t->index, stations.GetStations());;
 
}
 

	
 
/**
 
 * Generate cargo for a house using the original algorithm.
 
 * @param t The current town.
 
 * @param tpe The town production effect.
 
 * @param rate The town's product rate for this production.
 
 * @param stations Available stations for this house.
 
 */
 
static void TownGenerateCargoOriginal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
 
{
 
	for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
 
		uint32_t r = Random();
 
		if (GB(r, 0, 8) < rate) {
 
			CargoID cid = cs->Index();
 
			uint amt = GB(r, 0, 8) / 8 + 1;
 

	
 
			TownGenerateCargo(t, cid, amt, stations, true);
 
		}
 
	}
 
}
 

	
 
/**
 
 * Generate cargo for a house using the binominal algorithm.
 
 * @param t The current town.
 
 * @param tpe The town production effect.
 
 * @param rate The town's product rate for this production.
 
 * @param stations Available stations for this house.
 
 */
 
static void TownGenerateCargoBinominal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
 
{
 
	for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
 
		CargoID cid = cs->Index();
 
		uint32_t r = Random();
 

	
 
		/* Make a bitmask with up to 32 bits set, one for each potential pax. */
 
		int genmax = (rate + 7) / 8;
 
		uint32_t genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1);
 

	
 
		/* Mask random value by potential pax and count number of actual pax. */
 
		uint amt = CountBits(r & genmask);
 

	
 
		TownGenerateCargo(t, cid, amt, stations, true);
 
	}
 
}
 

	
 
/**
 
@@ -600,15 +643,8 @@ static void TileLoop_Town(TileIndex tile
 
		switch (_settings_game.economy.town_cargogen_mode) {
 
			case TCGM_ORIGINAL:
 
				/* Original (quadratic) cargo generation algorithm */
 
				if (GB(r, 0, 8) < hs->population) {
 
					uint amt = GB(r, 0, 8) / 8 + 1;
 
					TownGenerateCargo(t, CT_PASSENGERS, amt, stations, true);
 
				}
 

	
 
				if (GB(r, 8, 8) < hs->mail_generation) {
 
					uint amt = GB(r, 8, 8) / 8 + 1;
 
					TownGenerateCargo(t, CT_MAIL, amt, stations, true);
 
				}
 
				TownGenerateCargoOriginal(t, TPE_PASSENGERS, hs->population, stations);
 
				TownGenerateCargoOriginal(t, TPE_MAIL, hs->mail_generation, stations);
 
				break;
 

	
 
			case TCGM_BITCOUNT:
 
@@ -616,20 +652,8 @@ static void TileLoop_Town(TileIndex tile
 
				/* Reduce generation rate to a 1/4, using tile bits to spread out distribution.
 
				 * As tick counter is incremented by 256 between each call, we ignore the lower 8 bits. */
 
				if (GB(TimerGameTick::counter, 8, 2) == GB(tile.base(), 0, 2)) {
 
					/* Make a bitmask with up to 32 bits set, one for each potential pax */
 
					int genmax = (hs->population + 7) / 8;
 
					uint32_t genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1);
 
					/* Mask random value by potential pax and count number of actual pax */
 
					uint amt = CountBits(r & genmask);
 
					/* Adjust and apply */
 
					TownGenerateCargo(t, CT_PASSENGERS, amt, stations, true);
 

	
 
					/* Do the same for mail, with a fresh random */
 
					r = Random();
 
					genmax = (hs->mail_generation + 7) / 8;
 
					genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1);
 
					amt = CountBits(r & genmask);
 
					TownGenerateCargo(t, CT_MAIL, amt, stations, true);
 
					TownGenerateCargoBinominal(t, TPE_PASSENGERS, hs->population, stations);
 
					TownGenerateCargoBinominal(t, TPE_MAIL, hs->mail_generation, stations);
 
				}
 
				break;
 

	
 
@@ -731,10 +755,14 @@ static void AddProducedCargo_Town(TileIn
 
		}
 
	} else {
 
		if (hs->population > 0) {
 
			produced[CT_PASSENGERS]++;
 
			for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_PASSENGERS]) {
 
				produced[cs->Index()]++;
 
			}
 
		}
 
		if (hs->mail_generation > 0) {
 
			produced[CT_MAIL]++;
 
			for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_MAIL]) {
 
				produced[cs->Index()]++;
 
			}
 
		}
 
	}
 
}
 
@@ -1883,8 +1911,12 @@ void UpdateTownRadius(Town *t)
 
 */
 
void UpdateTownMaxPass(Town *t)
 
{
 
	t->supplied[CT_PASSENGERS].old_max = ScaleByCargoScale(t->cache.population >> 3, true);
 
	t->supplied[CT_MAIL].old_max = ScaleByCargoScale(t->cache.population >> 4, true);
 
	for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_PASSENGERS]) {
 
		t->supplied[cs->Index()].old_max = ScaleByCargoScale(t->cache.population >> 3, true);
 
	}
 
	for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_MAIL]) {
 
		t->supplied[cs->Index()].old_max = ScaleByCargoScale(t->cache.population >> 4, true);
 
	}
 
}
 

	
 
static void UpdateTownGrowthRate(Town *t);
src/town_gui.cpp
Show inline comments
 
@@ -408,17 +408,17 @@ public:
 
		tr.top += GetCharacterHeight(FS_NORMAL);
 

	
 
		StringID str_last_period = TimerGameEconomy::UsingWallclockUnits() ? STR_TOWN_VIEW_CARGO_LAST_MINUTE_MAX : STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX;
 
		SetDParam(0, 1 << CT_PASSENGERS);
 
		SetDParam(1, this->town->supplied[CT_PASSENGERS].old_act);
 
		SetDParam(2, this->town->supplied[CT_PASSENGERS].old_max);
 
		DrawString(tr, str_last_period);
 
		tr.top += GetCharacterHeight(FS_NORMAL);
 

	
 
		SetDParam(0, 1 << CT_MAIL);
 
		SetDParam(1, this->town->supplied[CT_MAIL].old_act);
 
		SetDParam(2, this->town->supplied[CT_MAIL].old_max);
 
		DrawString(tr, str_last_period);
 
		tr.top += GetCharacterHeight(FS_NORMAL);
 
		for (auto tpe : {TPE_PASSENGERS, TPE_MAIL}) {
 
			for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
 
				CargoID cid = cs->Index();
 
				SetDParam(0, 1ULL << cid);
 
				SetDParam(1, this->town->supplied[cid].old_act);
 
				SetDParam(2, this->town->supplied[cid].old_max);
 
				DrawString(tr, str_last_period);
 
				tr.top += GetCharacterHeight(FS_NORMAL);
 
			}
 
		}
 

	
 
		bool first = true;
 
		for (int i = TAE_BEGIN; i < TAE_END; i++) {
 
@@ -539,7 +539,7 @@ public:
 
	 */
 
	uint GetDesiredInfoHeight(int width) const
 
	{
 
		uint aimed_height = 3 * GetCharacterHeight(FS_NORMAL);
 
		uint aimed_height = static_cast<uint>(1 + CargoSpec::town_production_cargoes[TPE_PASSENGERS].size() + CargoSpec::town_production_cargoes[TPE_MAIL].size()) * GetCharacterHeight(FS_NORMAL);
 

	
 
		bool first = true;
 
		for (int i = TAE_BEGIN; i < TAE_END; i++) {
0 comments (0 inline, 0 general)