summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tree_cmd.cpp40
1 files changed, 33 insertions, 7 deletions
diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp
index c0865ffc6..f1a5be7f9 100644
--- a/src/tree_cmd.cpp
+++ b/src/tree_cmd.cpp
@@ -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 tile)
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();