* Place some trees in a radius around a tile. * The trees are placed in an quasi-normal distribution around the indicated tile, meaning that while * the radius does define a square, the distribution inside the square will be roughly circular. * @note This function the interactive RNG and must only be used in editor and map generation. * @param tile Tile to place trees around. * @param tr
| 420 | * @return Number of trees actually placed. |
| 421 | */ |
| 422 | uint PlaceTreeGroupAroundTile(TileIndex tile, TreeType treetype, uint radius, uint count, bool set_zone) |
| 423 | { |
| 424 | assert(_game_mode == GM_EDITOR); // Due to InteractiveRandom being used in this function |
| 425 | assert(treetype < TREE_TOYLAND + TREE_COUNT_TOYLAND); |
| 426 | const bool allow_desert = treetype == TREE_CACTUS; |
| 427 | uint planted = 0; |
| 428 | |
| 429 | for (; count > 0; count--) { |
| 430 | /* Simple quasi-normal distribution with range [-radius; radius) */ |
| 431 | auto mkcoord = [&]() -> int32_t { |
| 432 | const uint32_t rand = InteractiveRandom(); |
| 433 | 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); |
| 434 | const int32_t scu = dist * radius / 512; |
| 435 | return scu - radius; |
| 436 | }; |
| 437 | const int32_t xofs = mkcoord(); |
| 438 | const int32_t yofs = mkcoord(); |
| 439 | const TileIndex tile_to_plant = TileAddWrap(tile, xofs, yofs); |
| 440 | if (tile_to_plant != INVALID_TILE) { |
| 441 | if (IsTileType(tile_to_plant, MP_TREES) && GetTreeCount(tile_to_plant) < 4) { |
| 442 | AddTreeCount(tile_to_plant, 1); |
| 443 | SetTreeGrowth(tile_to_plant, TreeGrowthStage::Growing1); |
| 444 | MarkTileDirtyByTile(tile_to_plant, 0); |
| 445 | planted++; |
| 446 | } else if (CanPlantTreesOnTile(tile_to_plant, allow_desert)) { |
| 447 | PlantTreesOnTile(tile_to_plant, treetype, 0, TreeGrowthStage::Grown); |
| 448 | MarkTileDirtyByTile(tile_to_plant, 0); |
| 449 | planted++; |
| 450 | } |
| 451 | } |
| 452 | } |
| 453 | |
| 454 | if (set_zone && IsInsideMM(treetype, TREE_RAINFOREST, TREE_CACTUS)) { |
| 455 | for (TileIndex t : TileArea(tile).Expand(radius)) { |
| 456 | if (GetTileType(t) != MP_VOID && DistanceSquare(tile, t) < radius * radius) SetTropicZone(t, TROPICZONE_RAINFOREST); |
| 457 | } |
| 458 | } |
| 459 | |
| 460 | return planted; |
| 461 | } |
| 462 | |
| 463 | /** |
| 464 | * Place new trees. |
no test coverage detected