30#include "table/strings.h"
80 default:
return false;
114 switch (clearground) {
124 default: NOT_REACHED();
127 MakeTree(tile, treetype, count, growth, ground, density);
144 case LandscapeType::Temperate:
147 case LandscapeType::Arctic:
150 case LandscapeType::Tropic:
203 float step = (M_PI * 2) / std::size(shape);
206 for (
Point &vertex : shape) {
209 float deviation = std::accumulate(std::begin(harmonics), std::end(harmonics), 0.f, [theta](
float d,
const BlobHarmonic &harmonic) ->
float {
210 return d + sinf((theta + harmonic.phase) * harmonic.frequency) * harmonic.amplitude;
214 float adjusted_radius = (radius / 2.f) + (deviation / 2);
217 vertex.x = cosf(theta) * adjusted_radius;
218 vertex.y = sinf(theta) * adjusted_radius;
236 static constexpr float PHASE_DIVISOR =
static_cast<float>(INT32_MAX / M_PI * 2);
240 std::initializer_list<BlobHarmonic> harmonics = {
241 {radius / 2,
Random() / PHASE_DIVISOR, 1},
242 {radius / 4,
Random() / PHASE_DIVISOR, 2},
243 {radius / 8,
Random() / PHASE_DIVISOR, 3},
244 {radius / 16,
Random() / PHASE_DIVISOR, 4},
261 const int s = ((v1.x - v3.x) * (y - v3.y)) - ((v1.y - v3.y) * (x - v3.x));
262 const int t = ((v2.x - v1.x) * (y - v1.y)) - ((v2.y - v1.y) * (x - v1.x));
264 if ((s < 0) != (t < 0) && s != 0 && t != 0)
return false;
266 const int d = (v3.x - v2.x) * (y - v2.y) - (v3.y - v2.y) * (x - v2.x);
267 return (d < 0) == (s + t <= 0);
280 for (
auto it = std::begin(shape); it != std::end(shape); ) {
281 const Point &v1 = *it;
283 const Point &v2 = (it == std::end(shape)) ? shape.front() : *it;
299 static constexpr uint GROVE_SEGMENTS = 16;
300 static constexpr uint GROVE_RADIUS = 16;
303 std::array<Point, GROVE_SEGMENTS> grove;
314 int x =
GB(r, 0, 5) - GROVE_RADIUS;
315 int y =
GB(r, 8, 5) - GROVE_RADIUS;
325 }
while (--num_groups);
341 int x =
GB(r, 0, 5) - 16;
342 int y =
GB(r, 8, 5) - 16;
347 if (
abs(x) +
abs(y) > 16)
continue;
431 assert(_game_mode == GM_EDITOR);
436 for (; count > 0; count--) {
438 auto mkcoord = [&]() -> int32_t {
439 const uint32_t rand = InteractiveRandom();
440 const int32_t dist = GB<int32_t>(rand, 0, 8) + GB<int32_t>(rand, 8, 8) + GB<int32_t>(rand, 16, 8) + GB<int32_t>(rand, 24, 8);
441 const int32_t scu = dist * radius / 512;
444 const int32_t xofs = mkcoord();
445 const int32_t yofs = mkcoord();
485 default: NOT_REACHED();
497 for (; i != 0; i--) {
521 int limit = (c ==
nullptr ? INT32_MAX :
GB(c->
tree_limit, 16, 16));
530 msg = STR_ERROR_TREE_ALREADY_HERE;
536 msg = STR_ERROR_TREE_PLANT_LIMIT_REACHED;
546 cost.
AddCost(_price[PR_BUILD_TREES] * 2);
551 msg = STR_ERROR_CAN_T_BUILD_ON_WATER;
558 msg = STR_ERROR_SITE_UNSUITABLE;
571 msg = STR_ERROR_TREE_WRONG_TERRAIN_FOR_TREE_TYPE;
577 msg = STR_ERROR_TREE_PLANT_LIMIT_REACHED;
587 if (ret.
Failed())
return ret;
598 if (t !=
nullptr)
ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM, flags);
617 cost.
AddCost(_price[PR_BUILD_TREES]);
622 msg = STR_ERROR_SITE_UNSUITABLE;
627 if (limit < 0)
break;
641static void DrawTile_Trees(
TileInfo *ti)
663 assert(index <
lengthof(_tree_layout_sprite));
666 const TreePos *d = _tree_layout_xy[
GB(tmp, 2, 2)];
676 for (uint i = 0; i < trees; i++) {
691 for (; trees > 0; trees--) {
692 uint min = te[0].x + te[0].y;
695 for (uint i = 1; i < trees; i++) {
696 if ((uint)(te[i].x + te[i].y) < min) {
697 min = te[i].x + te[i].y;
702 AddSortableSpriteToDraw(te[mi].sprite, te[mi].pal, ti->
x + te[mi].x, ti->
y + te[mi].y, 16 - te[mi].x, 16 - te[mi].y, 0x30, z,
IsTransparencySet(
TO_TREES), -te[mi].x, -te[mi].y);
705 te[mi] = te[trees - 1];
712static int GetSlopePixelZ_Trees(
TileIndex tile, uint x, uint y,
bool)
730 if (t !=
nullptr)
ChangeTownRating(t, RATING_TREE_DOWN_STEP, RATING_TREE_MINIMUM, flags);
746 td.
str = STR_LAI_TREE_NAME_RAINFOREST;
748 td.
str = tt ==
TREE_CACTUS ? STR_LAI_TREE_NAME_CACTUS_PLANTS : STR_LAI_TREE_NAME_TREES;
754static void TileLoopTreesDesert(
TileIndex tile)
765 static const SoundFx forest_sounds[] = {
781static void TileLoopTreesAlps(
TileIndex tile)
792 uint density = std::min<uint>(k, 3);
812static bool CanPlantExtraTrees(
TileIndex tile)
819static void TileLoop_Trees(
TileIndex tile)
825 case LandscapeType::Tropic: TileLoopTreesDesert(tile);
break;
826 case LandscapeType::Arctic: TileLoopTreesAlps(tile);
break;
850 static const uint32_t TREE_UPDATE_FREQUENCY = 16;
851 if (cycle % TREE_UPDATE_FREQUENCY != TREE_UPDATE_FREQUENCY - 1)
return;
866 if (
GetTreeCount(tile) < 4 && CanPlantExtraTrees(tile)) {
874 if (!CanPlantExtraTrees(tile))
break;
898 if (!CanPlantExtraTrees(tile)) {
1007void InitializeTrees()
1020 GetSlopePixelZ_Trees,
1024 GetTileTrackStatus_Trees,
1028 ChangeTileOwner_Trees,
1031 GetFoundation_Trees,
1032 TerraformTile_Trees,
constexpr uint CountBits(T value)
Counts the number of set bits in a variable.
debug_inline static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
bool IsBridgeAbove(Tile t)
checks if a bridge is set above the ground of this tile
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Common return value for all commands.
void AddCost(const Money &cost)
Adds the given cost to the cost of the command.
Money GetCost() const
The costs as made up to this moment.
bool Failed() const
Did this command fail?
static std::unique_ptr< TileIterator > Create(TileIndex corner1, TileIndex corner2, bool diagonal)
Create either an OrthogonalTileIterator or DiagonalTileIterator given the diagonal parameter.
static TickCounter counter
Monotonic counter, in ticks, since start of game.
Functions related to clear (MP_CLEAR) land.
Tables with sprites for clear land and fences.
Map accessors for 'clear' tiles.
bool IsClearGround(Tile t, ClearGround ct)
Set the type of clear tile.
void MakeSnow(Tile t, uint density=0)
Make a snow tile.
void MakeClear(Tile t, ClearGround g, uint density)
Make a clear tile.
ClearGround GetClearGround(Tile t)
Get the type of clear tile.
bool IsSnowTile(Tile t)
Test if a tile is covered with snow.
uint GetClearDensity(Tile t)
Get the density of a non-field clear tile.
Functions related to commands.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
@ Execute
execute the given command
Definition of stuff that is very close to a company, like the company struct itself.
CompanyID _current_company
Company currently doing an action.
Functions related to companies.
Direction
Defines the 8 directions on the map.
@ DIR_END
Used to iterate.
DiagDirection
Enumeration for diagonal directions.
@ EXPENSES_CONSTRUCTION
Construction costs.
@ EXPENSES_OTHER
Other expenses.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23)
Functions related to world/map generation.
void IncreaseGeneratingWorldProgress(GenWorldProgress cls)
Increases the current stage of the world generation with one.
@ GWP_TREE
Generate trees.
void SetGeneratingWorldProgress(GenWorldProgress cls, uint total)
Set the total of a stage of the world generation.
static constexpr uint MAP_HEIGHT_LIMIT_ORIGINAL
Original map height limit.
All geometry types in OpenTTD.
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
uint32_t PaletteID
The number of the palette.
uint8_t GetSnowLine()
Get the current snow line, either variable or static.
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
uint GetPartialPixelZ(int x, int y, Slope corners)
Determines height at given coordinate of a slope.
Functions related to OTTD's landscape.
Command definitions related to landscape (slopes etc.).
@ Random
Randomise borders.
uint DistanceSquare(TileIndex t0, TileIndex t1)
Gets the 'Square' distance between the two given tiles.
TileIndex TileAddWrap(TileIndex tile, int addx, int addy)
This function checks if we add addx/addy to tile, if we do wrap around the edges.
TileIndex RandomTileSeed(uint32_t r)
Get a random tile out of a given seed.
#define RandomTile()
Get a valid random tile.
TileIndexDiff TileOffsByDir(Direction dir)
Convert a Direction to a TileIndexDiff.
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
static const uint MIN_MAP_SIZE_BITS
Minimal and maximal map width and height.
static const uint MAX_MAP_SIZE_BITS
Maximal size of map is equal to 2 ^ MAX_MAP_SIZE_BITS.
constexpr bool IsInsideBS(const T x, const size_t base, const size_t size)
Checks if a value is between a window started at some base point.
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
constexpr T abs(const T a)
Returns the absolute value of (scalar) variable.
constexpr T Delta(const T a, const T b)
Returns the (absolute) difference between two (scalar) variables.
Functions related to generic callbacks.
void AmbientSoundEffect(TileIndex tile)
Play an ambient sound effect for an empty tile.
Pseudo random number generator.
bool Chance16I(const uint32_t a, const uint32_t b, const uint32_t r)
Checks if a given randomize-number is below a given probability.
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
ClientSettings _settings_client
The current settings for this game.
bool IsSlopeWithOneCornerRaised(Slope s)
Tests if a specific slope has exactly one corner raised.
uint SlopeToSpriteOffset(Slope s)
Returns the Sprite offset for a given Slope.
static constexpr int GetSlopeMaxPixelZ(Slope s)
Returns the height of the highest corner of a slope relative to TileZ (= minimal height)
Slope
Enumeration for the slope-type.
Foundation
Enumeration for Foundations.
@ FOUNDATION_NONE
The tile has no foundation, the slope remains unchanged.
Functions related to sound.
SoundFx
Sound effects from baseset.
@ SND_39_ARCTIC_SNOW_2
57 == 0x39 Tree ambient: arctic snow (2): heavy wind
@ SND_44_RAINFOREST_3
68 == 0x44 Tree ambient: rainforest ambient (3): monkeys
@ SND_34_ARCTIC_SNOW_1
52 == 0x34 Tree ambient: arctic snow (1): wind
@ SND_43_RAINFOREST_2
67 == 0x43 Tree ambient: rainforest ambient (2): lion
@ SND_42_RAINFOREST_1
66 == 0x42 Tree ambient: rainforest ambient (1): bird (1)
@ SND_48_RAINFOREST_4
72 == 0x48 Tree ambient: rainforest ambient (4): bird (2)
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
SoundSettings sound
sound effect settings
uint32_t tree_limit
Amount of trees we can (still) plant (times 65536).
uint8_t extra_tree_placement
(dis)allow building extra trees in-game
uint8_t map_height_limit
the maximum allowed heightlevel
uint8_t dist_local_authority
distance for town local authority, default 20
uint8_t tree_placer
the tree placer algorithm
LandscapeType landscape
the landscape we're currently in
EconomySettings economy
settings to change the economy
ConstructionSettings construction
construction of things in-game
GameCreationSettings game_creation
settings used during the creation of a game (map)
static uint ScaleBySize(uint n)
Scales the given value by the map size, where the given value is for a 256 by 256 map.
static debug_inline uint Size()
Get the size of the map.
OrthogonalTileArea & Expand(int rad)
Expand a tile area by rad tiles in each direction, keeping within map bounds.
Combination of a palette sprite and a 'real' sprite.
SpriteID sprite
The 'real' sprite.
PaletteID pal
The palette (use PAL_NONE) if not needed)
Coordinates of a point in 2D.
static bool IsValidID(auto index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
static Titem * GetIfValid(auto index)
Returns Titem with given index.
bool ambient
Play ambient, industry and town sounds.
Tile description for the 'land area information' tool.
StringID str
Description of the tile.
std::array< Owner, 4 > owner
Name of the owner(s)
Tile information, used while rendering the tile.
int x
X position of the tile in unit coordinates.
Slope tileh
Slope of the tile.
TileIndex tile
Tile index.
int y
Y position of the tile in unit coordinates.
Set of callback functions for performing tile operations of a given tile type.
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
static debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
std::tuple< Slope, int > GetTilePixelSlope(TileIndex tile)
Return the slope of a given tile.
TropicZone GetTropicZone(Tile tile)
Get the tropic zone.
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Slope GetTileSlope(TileIndex tile)
Return the slope of a given tile inside the map.
void SetTropicZone(Tile tile, TropicZone type)
Set the tropic zone.
@ TROPICZONE_RAINFOREST
Rainforest tile.
@ TROPICZONE_DESERT
Tile is desert.
@ TROPICZONE_NORMAL
Normal tropiczone.
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
@ MP_TREES
Tile got trees.
@ MP_CLEAR
A tile without any structures, i.e. grass, rocks, farm fields etc.
@ MP_VOID
Invisible tiles at the SW and SE border.
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Definition of the tick-based game-timer.
void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
Changes town rating of the current company.
Town * ClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest (in distance or ownership) to a given tile, within a given threshold.
bool IsTransparencySet(TransparencyOption to)
Check if the transparency option bit is set and if we aren't in the game menu (there's never transpar...
bool IsInvisibilitySet(TransparencyOption to)
Check if the invisibility option bit is set and if we aren't in the game menu (there's never transpar...
TransportType
Available types of transport.
uint PlaceTreeGroupAroundTile(TileIndex tile, TreeType treetype, uint radius, uint count, bool set_zone)
Place some trees in a radius around a tile.
static void PlantTreesOnTile(TileIndex tile, TreeType treetype, uint count, TreeGrowthStage growth)
Creates a tree tile Ground type and density is preserved.
static TreeType GetRandomTreeType(TileIndex tile, uint seed)
Get a random TreeType for the given tile based on a given seed.
static bool IsPointInTriangle(int x, int y, const Point &v1, const Point &v2, const Point &v3)
Returns true if the given coordinates lie within a triangle.
void GenerateTrees()
Place new trees.
static void CreateStarShapedPolygon(int radius, std::span< const BlobHarmonic > harmonics, std::span< Point > shape)
Creates a star-shaped polygon originating from (0, 0) as defined by the given harmonics.
static const uint16_t EDITOR_TREE_DIV
Game editor tree generation divisor factor.
static bool CanPlantTreesOnTile(TileIndex tile, bool allow_desert)
Tests if a tile can be converted to MP_TREES This is true for clear ground without farms or rocks.
void PlaceTreesRandomly()
Place some trees randomly.
static const uint16_t DEFAULT_TREE_STEPS
Default number of attempts for placing trees.
static const uint16_t DEFAULT_RAINFOREST_TREE_STEPS
Default number of attempts for placing extra trees at rainforest in tropic.
static bool IsPointInStarShapedPolygon(int x, int y, std::span< Point > shape)
Returns true if the given coordinates lie within a star shaped polygon.
static void PlantRandomTree(bool rainforest)
Place a random tree on a random tile.
CommandCost CmdPlantTree(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, uint8_t tree_to_plant, bool diagonal)
Plant a tree.
static void PlaceTreeAtSameHeight(TileIndex tile, int height)
Place a tree at the same height as an existing tree.
static void CreateRandomStarShapedPolygon(int radius, std::span< Point > shape)
Creates a random star-shaped polygon originating from (0, 0).
uint8_t _trees_tick_ctr
Determines when to consider building more trees.
TreePlacer
List of tree placer algorithm.
@ TP_IMPROVED
A 'improved' algorithm.
@ TP_NONE
No tree placer algorithm.
@ TP_ORIGINAL
The original algorithm.
static void PlaceTree(TileIndex tile, uint32_t r)
Make a random tree tile of the given tile.
static void PlaceTreeGroups(uint num_groups)
Creates a number of tree groups.
ExtraTreePlacement
Where to place trees while in-game?
@ ETP_SPREAD_RAINFOREST
Grow trees on tiles that have them, only spread to new ones in rainforests.
@ ETP_NO_SPREAD
Grow trees on tiles that have them but don't spread to new ones.
@ ETP_NO_GROWTH_NO_SPREAD
Don't grow trees and don't spread them at all.
@ ETP_SPREAD_ALL
Grow trees and spread them without restrictions.
bool DecrementTreeCounter()
Decrement the tree tick counter.
Command definitions related to tree tiles.
Sprites to use and how to display them for tree tiles.
Map accessors for tree tiles.
static const uint TREE_COUNT_RAINFOREST
number of tree types for the 'rainforest part' of a sub-tropic map.
uint GetTreeCount(Tile t)
Returns the number of trees on a tile.
TreeGrowthStage GetTreeGrowth(Tile t)
Returns the tree growth stage.
static const uint TREE_COUNT_SUB_TROPICAL
number of tree types for the 'sub-tropic part' of a sub-tropic map.
static const uint TREE_COUNT_TOYLAND
number of tree types on a toyland map.
void MakeTree(Tile t, TreeType type, uint count, TreeGrowthStage growth, TreeGround ground, uint density)
Make a tree-tile.
void SetTreeGrowth(Tile t, TreeGrowthStage g)
Sets the tree growth stage of a tile.
TreeGround GetTreeGround(Tile t)
Returns the groundtype for tree tiles.
TreeType
List of tree types along all landscape types.
@ TREE_RAINFOREST
tree on the 'green part' on a sub-tropical map
@ TREE_TOYLAND
tree on a toyland map
@ TREE_SUB_ARCTIC
tree on a sub_arctic landscape
@ TREE_SUB_TROPICAL
tree on a sub-tropical map, non-rainforest, non-desert
@ TREE_TEMPERATE
temperate tree
@ TREE_CACTUS
a cactus for the 'desert part' on a sub-tropical map
@ TREE_INVALID
An invalid tree.
void AddTreeCount(Tile t, int c)
Add a amount to the tree-count value of a tile with trees.
TreeGround
Enumeration for ground types of tiles with trees.
@ TREE_GROUND_GRASS
normal grass
@ TREE_GROUND_ROUGH_SNOW
A snow tile that is rough underneath.
@ TREE_GROUND_SNOW_DESERT
a desert or snow tile, depend on landscape
@ TREE_GROUND_ROUGH
some rough tile
static const uint TREE_COUNT_SUB_ARCTIC
number of tree types on a sub arctic map.
TreeType GetTreeType(Tile t)
Returns the treetype of a tile.
void SetTreeGroundDensity(Tile t, TreeGround g, uint d)
Set the density and ground type of a tile with trees.
void AddTreeGrowth(Tile t, int a)
Add a value to the tree growth stage.
uint GetTreeDensity(Tile t)
Returns the 'density' of a tile with trees.
TreeGrowthStage
Enumeration for tree growth stages.
@ Growing1
First stage of growth.
static const uint TREE_COUNT_TEMPERATE
number of tree types on a temperate map.
void StartSpriteCombine()
Starts a block of sprites, which are "combined" into a single bounding box.
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w, int h, int dz, int z, bool transparent, int bb_offset_x, int bb_offset_y, int bb_offset_z, const SubSprite *sub)
Draw a (transparent) sprite at given coordinates with a given bounding box.
void EndSpriteCombine()
Terminates a block of sprites started by StartSpriteCombine.
void DrawGroundSprite(SpriteID image, PaletteID pal, const SubSprite *sub, int extra_offs_x, int extra_offs_y)
Draws a ground sprite for the current tile.
Functions related to (drawing on) viewports.
Functions related to water (management)
void TileLoop_Water(TileIndex tile)
Let a water tile floods its diagonal adjoining tiles called from tunnelbridge_cmd,...
void ClearNeighbourNonFloodingStates(TileIndex tile)
Clear non-flooding state of the tiles around a tile.
void MakeShore(Tile t)
Helper function to make a coast tile.
bool IsCoast(Tile t)
Is it a coast tile?