Changeset - r25442:980b1ae46e00
[Not reviewed]
master
0 1 0
PeterN - 4 years ago 2021-05-12 17:17:57
peter1138@openttd.org
Fix #9242: Tree tick handler did not scale by map size. (#9246)

This means that random tree generation density is higher on small maps and lower on large maps. This difference is enough to make the Lumber Mill impractical to use on large maps.

This change skips ticks on maps smaller than 256x256 and increases iterations or shortens the interval on maps larger than 256x256.
1 file changed with 33 insertions and 7 deletions:
0 comments (0 inline, 0 general)
src/tree_cmd.cpp
Show inline comments
 
@@ -22,6 +22,7 @@
 
#include "company_base.h"
 
#include "core/random_func.hpp"
 
#include "newgrf_generic.h"
 
#include "date_func.h"
 

	
 
#include "table/strings.h"
 
#include "table/tree_land.h"
 
@@ -803,6 +804,23 @@ static void TileLoop_Trees(TileIndex til
 
	MarkTileDirtyByTile(tile);
 
}
 

	
 
/**
 
 * Decrement the tree tick counter.
 
 * The interval is scaled by map size to allow for the same density regardless of size.
 
 * Adjustment for map sizes below the standard 256 * 256 are handled earlier.
 
 * @return true if the counter was decremented past zero
 
 */
 
bool DecrementTreeCounter()
 
{
 
	/* Ensure _trees_tick_ctr can be decremented past zero only once for the largest map size. */
 
	static_assert(2 * (MAX_MAP_SIZE_BITS - MIN_MAP_SIZE_BITS) - 4 <= std::numeric_limits<byte>::digits);
 

	
 
	/* byte underflow */
 
	byte old_trees_tick_ctr = _trees_tick_ctr;
 
	_trees_tick_ctr -= ScaleByMapSize(1);
 
	return old_trees_tick_ctr <= _trees_tick_ctr;
 
}
 

	
 
void OnTick_Trees()
 
{
 
	/* Don't spread trees if that's not allowed */
 
@@ -812,16 +830,24 @@ void OnTick_Trees()
 
	TileIndex tile;
 
	TreeType tree;
 

	
 
	/* Skip some tree ticks for map sizes below 256 * 256. 64 * 64 is 16 times smaller, so
 
	 * this is the maximum number of ticks that are skipped. Number of ticks to skip is
 
	 * inversely proportional to map size, so that is handled to create a mask. */
 
	int skip = ScaleByMapSize(16);
 
	if (skip < 16 && (_tick_counter & (16 / skip - 1)) != 0) return;
 

	
 
	/* place a tree at a random rainforest spot */
 
	if (_settings_game.game_creation.landscape == LT_TROPIC &&
 
			(r = Random(), tile = RandomTileSeed(r), GetTropicZone(tile) == TROPICZONE_RAINFOREST) &&
 
			CanPlantTreesOnTile(tile, false) &&
 
			(tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TREE_INVALID) {
 
		PlantTreesOnTile(tile, tree, 0, 0);
 
	if (_settings_game.game_creation.landscape == LT_TROPIC) {
 
		for (uint c = ScaleByMapSize(1); c > 0; c--) {
 
			if ((r = Random(), tile = RandomTileSeed(r), GetTropicZone(tile) == TROPICZONE_RAINFOREST) &&
 
				CanPlantTreesOnTile(tile, false) &&
 
				(tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TREE_INVALID) {
 
				PlantTreesOnTile(tile, tree, 0, 0);
 
			}
 
		}
 
	}
 

	
 
	/* byte underflow */
 
	if (--_trees_tick_ctr != 0 || _settings_game.construction.extra_tree_placement == ETP_SPREAD_RAINFOREST) return;
 
	if (!DecrementTreeCounter() || _settings_game.construction.extra_tree_placement == ETP_SPREAD_RAINFOREST) return;
 

	
 
	/* place a tree at a random spot */
 
	r = Random();
0 comments (0 inline, 0 general)