MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / CmdPlantTree

Function CmdPlantTree

src/tree_cmd.cpp:504–628  ·  view source on GitHub ↗

* Plant a tree. * @param flags type of operation * @param tile end tile of area-drag * @param start_tile start tile of area-drag of tree plantation * @param tree_to_plant tree type, TREE_INVALID means random. * @param diagonal Whether to use the Orthogonal (false) or Diagonal (true) iterator. * @return the cost of this operation or an error */

Source from the content-addressed store, hash-verified

502 * @return the cost of this operation or an error
503 */
504CommandCost CmdPlantTree(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, uint8_t tree_to_plant, bool diagonal)
505{
506 StringID msg = INVALID_STRING_ID;
507 CommandCost cost(EXPENSES_OTHER);
508
509 if (start_tile >= Map::Size()) return CMD_ERROR;
510 /* Check the tree type within the current climate */
511 if (tree_to_plant != TREE_INVALID && !IsInsideBS(tree_to_plant, _tree_base_by_landscape[to_underlying(_settings_game.game_creation.landscape)], _tree_count_by_landscape[to_underlying(_settings_game.game_creation.landscape)])) return CMD_ERROR;
512
513 Company *c = (_game_mode != GM_EDITOR) ? Company::GetIfValid(_current_company) : nullptr;
514 int limit = (c == nullptr ? INT32_MAX : GB(c->tree_limit, 16, 16));
515
516 std::unique_ptr<TileIterator> iter = TileIterator::Create(tile, start_tile, diagonal);
517 for (; *iter != INVALID_TILE; ++(*iter)) {
518 TileIndex current_tile = *iter;
519 switch (GetTileType(current_tile)) {
520 case MP_TREES:
521 /* no more space for trees? */
522 if (GetTreeCount(current_tile) == 4) {
523 msg = STR_ERROR_TREE_ALREADY_HERE;
524 continue;
525 }
526
527 /* Test tree limit. */
528 if (--limit < 1) {
529 msg = STR_ERROR_TREE_PLANT_LIMIT_REACHED;
530 break;
531 }
532
533 if (flags.Test(DoCommandFlag::Execute)) {
534 AddTreeCount(current_tile, 1);
535 MarkTileDirtyByTile(current_tile);
536 if (c != nullptr) c->tree_limit -= 1 << 16;
537 }
538 /* 2x as expensive to add more trees to an existing tile */
539 cost.AddCost(_price[PR_BUILD_TREES] * 2);
540 break;
541
542 case MP_WATER:
543 if (!IsCoast(current_tile) || IsSlopeWithOneCornerRaised(GetTileSlope(current_tile))) {
544 msg = STR_ERROR_CAN_T_BUILD_ON_WATER;
545 continue;
546 }
547 [[fallthrough]];
548
549 case MP_CLEAR: {
550 if (IsBridgeAbove(current_tile)) {
551 msg = STR_ERROR_SITE_UNSUITABLE;
552 continue;
553 }
554
555 TreeType treetype = (TreeType)tree_to_plant;
556 /* Be a bit picky about which trees go where. */
557 if (_settings_game.game_creation.landscape == LandscapeType::Tropic && treetype != TREE_INVALID && (
558 /* No cacti outside the desert */
559 (treetype == TREE_CACTUS && GetTropicZone(current_tile) != TROPICZONE_DESERT) ||
560 /* No rainforest trees outside the rainforest, except in the editor mode where it makes those tiles rainforest tile */
561 (IsInsideMM(treetype, TREE_RAINFOREST, TREE_CACTUS) && GetTropicZone(current_tile) != TROPICZONE_RAINFOREST && _game_mode != GM_EDITOR) ||

Callers

nothing calls this directly

Calls 15

IsInsideBSFunction · 0.85
to_underlyingFunction · 0.85
GBFunction · 0.85
GetTileTypeFunction · 0.85
GetTreeCountFunction · 0.85
AddTreeCountFunction · 0.85
IsCoastFunction · 0.85
GetTileSlopeFunction · 0.85
IsBridgeAboveFunction · 0.85
GetTropicZoneFunction · 0.85
IsInsideMMFunction · 0.85

Tested by

no test coverage detected