Update to 12.0-beta1

This commit is contained in:
dP
2021-08-15 14:57:29 +03:00
parent ac7d3eba75
commit 9df4f2c4fc
666 changed files with 61302 additions and 20466 deletions

View File

@@ -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();