Update to 12.0-beta1
This commit is contained in:
@@ -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"
|
||||
@@ -377,7 +378,7 @@ void GenerateTrees()
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
StringID msg = INVALID_STRING_ID;
|
||||
CommandCost cost(EXPENSES_OTHER);
|
||||
@@ -391,11 +392,11 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
int limit = (c == nullptr ? INT32_MAX : GB(c->tree_limit, 16, 16));
|
||||
|
||||
TileArea ta(tile, p2);
|
||||
TILE_AREA_LOOP(tile, ta) {
|
||||
switch (GetTileType(tile)) {
|
||||
for (TileIndex current_tile : ta) {
|
||||
switch (GetTileType(current_tile)) {
|
||||
case MP_TREES:
|
||||
/* no more space for trees? */
|
||||
if (GetTreeCount(tile) == 4) {
|
||||
if (GetTreeCount(current_tile) == 4) {
|
||||
msg = STR_ERROR_TREE_ALREADY_HERE;
|
||||
continue;
|
||||
}
|
||||
@@ -407,8 +408,8 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
}
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
AddTreeCount(tile, 1);
|
||||
MarkTileDirtyByTile(tile);
|
||||
AddTreeCount(current_tile, 1);
|
||||
MarkTileDirtyByTile(current_tile);
|
||||
if (c != nullptr) c->tree_limit -= 1 << 16;
|
||||
}
|
||||
/* 2x as expensive to add more trees to an existing tile */
|
||||
@@ -416,14 +417,14 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
break;
|
||||
|
||||
case MP_WATER:
|
||||
if (!IsCoast(tile) || IsSlopeWithOneCornerRaised(GetTileSlope(tile))) {
|
||||
if (!IsCoast(current_tile) || IsSlopeWithOneCornerRaised(GetTileSlope(current_tile))) {
|
||||
msg = STR_ERROR_CAN_T_BUILD_ON_WATER;
|
||||
continue;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
|
||||
case MP_CLEAR: {
|
||||
if (IsBridgeAbove(tile)) {
|
||||
if (IsBridgeAbove(current_tile)) {
|
||||
msg = STR_ERROR_SITE_UNSUITABLE;
|
||||
continue;
|
||||
}
|
||||
@@ -432,11 +433,11 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
/* Be a bit picky about which trees go where. */
|
||||
if (_settings_game.game_creation.landscape == LT_TROPIC && treetype != TREE_INVALID && (
|
||||
/* No cacti outside the desert */
|
||||
(treetype == TREE_CACTUS && GetTropicZone(tile) != TROPICZONE_DESERT) ||
|
||||
(treetype == TREE_CACTUS && GetTropicZone(current_tile) != TROPICZONE_DESERT) ||
|
||||
/* No rain forest trees outside the rain forest, except in the editor mode where it makes those tiles rain forest tile */
|
||||
(IsInsideMM(treetype, TREE_RAINFOREST, TREE_CACTUS) && GetTropicZone(tile) != TROPICZONE_RAINFOREST && _game_mode != GM_EDITOR) ||
|
||||
(IsInsideMM(treetype, TREE_RAINFOREST, TREE_CACTUS) && GetTropicZone(current_tile) != TROPICZONE_RAINFOREST && _game_mode != GM_EDITOR) ||
|
||||
/* And no subtropical trees in the desert/rain forest */
|
||||
(IsInsideMM(treetype, TREE_SUB_TROPICAL, TREE_TOYLAND) && GetTropicZone(tile) != TROPICZONE_NORMAL))) {
|
||||
(IsInsideMM(treetype, TREE_SUB_TROPICAL, TREE_TOYLAND) && GetTropicZone(current_tile) != TROPICZONE_NORMAL))) {
|
||||
msg = STR_ERROR_TREE_WRONG_TERRAIN_FOR_TREE_TYPE;
|
||||
continue;
|
||||
}
|
||||
@@ -447,12 +448,12 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
break;
|
||||
}
|
||||
|
||||
if (IsTileType(tile, MP_CLEAR)) {
|
||||
if (IsTileType(current_tile, MP_CLEAR)) {
|
||||
/* Remove fields or rocks. Note that the ground will get barrened */
|
||||
switch (GetRawClearGround(tile)) {
|
||||
switch (GetRawClearGround(current_tile)) {
|
||||
case CLEAR_FIELDS:
|
||||
case CLEAR_ROCKS: {
|
||||
CommandCost ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
||||
CommandCost ret = DoCommand(current_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
||||
if (ret.Failed()) return ret;
|
||||
cost.AddCost(ret);
|
||||
break;
|
||||
@@ -463,24 +464,24 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
}
|
||||
|
||||
if (_game_mode != GM_EDITOR && Company::IsValidID(_current_company)) {
|
||||
Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
|
||||
Town *t = ClosestTownFromTile(current_tile, _settings_game.economy.dist_local_authority);
|
||||
if (t != nullptr) ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM, flags);
|
||||
}
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
if (treetype == TREE_INVALID) {
|
||||
treetype = GetRandomTreeType(tile, GB(Random(), 24, 8));
|
||||
treetype = GetRandomTreeType(current_tile, GB(Random(), 24, 8));
|
||||
if (treetype == TREE_INVALID) treetype = TREE_CACTUS;
|
||||
}
|
||||
|
||||
/* Plant full grown trees in scenario editor */
|
||||
PlantTreesOnTile(tile, treetype, 0, _game_mode == GM_EDITOR ? 3 : 0);
|
||||
MarkTileDirtyByTile(tile);
|
||||
PlantTreesOnTile(current_tile, treetype, 0, _game_mode == GM_EDITOR ? 3 : 0);
|
||||
MarkTileDirtyByTile(current_tile);
|
||||
if (c != nullptr) c->tree_limit -= 1 << 16;
|
||||
|
||||
/* When planting rainforest-trees, set tropiczone to rainforest in editor. */
|
||||
if (_game_mode == GM_EDITOR && IsInsideMM(treetype, TREE_RAINFOREST, TREE_CACTUS)) {
|
||||
SetTropicZone(tile, TROPICZONE_RAINFOREST);
|
||||
SetTropicZone(current_tile, TROPICZONE_RAINFOREST);
|
||||
}
|
||||
}
|
||||
cost.AddCost(_price[PR_BUILD_TREES]);
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user