* Construct multiple objects in an area * @param flags of operation to conduct * @param tile end tile of area dragging * @param start_tile start tile of area dragging * @param type the object type to build * @param view the view for the object * @param diagonal Whether to use the Orthogonal (0) or Diagonal (1) iterator. * @return the cost of this operation or an error */
| 395 | * @return the cost of this operation or an error |
| 396 | */ |
| 397 | CommandCost CmdBuildObjectArea(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, ObjectType type, uint8_t view, bool diagonal) |
| 398 | { |
| 399 | if (start_tile >= Map::Size()) return CMD_ERROR; |
| 400 | |
| 401 | if (type >= ObjectSpec::Count()) return CMD_ERROR; |
| 402 | const ObjectSpec *spec = ObjectSpec::Get(type); |
| 403 | if (view >= spec->views) return CMD_ERROR; |
| 404 | |
| 405 | if (spec->size != OBJECT_SIZE_1X1) return CMD_ERROR; |
| 406 | |
| 407 | Money money = GetAvailableMoneyForCommand(); |
| 408 | CommandCost cost(EXPENSES_CONSTRUCTION); |
| 409 | CommandCost last_error = CMD_ERROR; |
| 410 | bool had_success = false; |
| 411 | |
| 412 | const Company *c = Company::GetIfValid(_current_company); |
| 413 | int limit = (c == nullptr ? INT32_MAX : GB(c->build_object_limit, 16, 16)); |
| 414 | |
| 415 | std::unique_ptr<TileIterator> iter = TileIterator::Create(tile, start_tile, diagonal); |
| 416 | for (; *iter != INVALID_TILE; ++(*iter)) { |
| 417 | TileIndex t = *iter; |
| 418 | CommandCost ret = Command<CMD_BUILD_OBJECT>::Do(DoCommandFlags{flags}.Reset(DoCommandFlag::Execute), t, type, view); |
| 419 | |
| 420 | /* If we've reached the limit, stop building (or testing). */ |
| 421 | if (c != nullptr && limit-- <= 0) break; |
| 422 | |
| 423 | if (ret.Failed()) { |
| 424 | last_error = std::move(ret); |
| 425 | continue; |
| 426 | } |
| 427 | |
| 428 | had_success = true; |
| 429 | if (flags.Test(DoCommandFlag::Execute)) { |
| 430 | money -= ret.GetCost(); |
| 431 | |
| 432 | /* If we run out of money, stop building. */ |
| 433 | if (ret.GetCost() > 0 && money < 0) break; |
| 434 | Command<CMD_BUILD_OBJECT>::Do(flags, t, type, view); |
| 435 | } |
| 436 | cost.AddCost(ret.GetCost()); |
| 437 | } |
| 438 | |
| 439 | return had_success ? cost : last_error; |
| 440 | } |
| 441 | |
| 442 | static Foundation GetFoundation_Object(TileIndex tile, Slope tileh); |
| 443 |