* Process the result of a command test run and execution run. * @param cmd Command that was executed. * @param cmd_flags Command flags. * @param res_test Command result of test run. * @param tes_exec Command result of real run. * @param extra_cash Additional cash required for successful command execution. * @param tile Tile of command execution. * @param[in,out] cur_company Backup of curren
| 340 | * @return Final command result. |
| 341 | */ |
| 342 | CommandCost CommandHelperBase::InternalExecuteProcessResult(Commands cmd, CommandFlags cmd_flags, [[maybe_unused]] const CommandCost &res_test, const CommandCost &res_exec, Money extra_cash, TileIndex tile, Backup<CompanyID> &cur_company) |
| 343 | { |
| 344 | BasePersistentStorageArray::SwitchMode(PSM_LEAVE_COMMAND); |
| 345 | |
| 346 | if (cmd == CMD_COMPANY_CTRL) { |
| 347 | cur_company.Trash(); |
| 348 | /* We are a new company -> Switch to new local company. |
| 349 | * We were closed down -> Switch to spectator |
| 350 | * Some other company opened/closed down -> The outside function will switch back */ |
| 351 | _current_company = _local_company; |
| 352 | } else { |
| 353 | /* Make sure nothing bad happened, like changing the current company. */ |
| 354 | assert(cmd_flags.Any({CommandFlag::Spectator, CommandFlag::Server}) ? _current_company == COMPANY_SPECTATOR : cur_company.Verify()); |
| 355 | cur_company.Restore(); |
| 356 | } |
| 357 | |
| 358 | /* If the test and execution can differ we have to check the |
| 359 | * return of the command. Otherwise we can check whether the |
| 360 | * test and execution have yielded the same result, |
| 361 | * i.e. cost and error state are the same. */ |
| 362 | bool test_and_exec_can_differ = cmd_flags.Test(CommandFlag::NoTest); |
| 363 | if (!test_and_exec_can_differ) { |
| 364 | assert(res_test.GetCost() == res_exec.GetCost() && res_test.Failed() == res_exec.Failed()); // sanity check |
| 365 | } else if (res_exec.Failed()) { |
| 366 | return res_exec; |
| 367 | } |
| 368 | |
| 369 | /* If we're needing more money and we haven't done |
| 370 | * anything yet, ask for the money! */ |
| 371 | if (extra_cash != 0 && res_exec.GetCost() == 0) { |
| 372 | /* It could happen we removed rail, thus gained money, and deleted something else. |
| 373 | * So make sure the signal buffer is empty even in this case */ |
| 374 | UpdateSignalsInBuffer(); |
| 375 | return CommandCostWithParam(STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY, extra_cash); |
| 376 | } |
| 377 | |
| 378 | /* update last build coordinate of company. */ |
| 379 | if (tile != 0) { |
| 380 | Company *c = Company::GetIfValid(_current_company); |
| 381 | if (c != nullptr) c->last_build_coordinate = tile; |
| 382 | } |
| 383 | |
| 384 | SubtractMoneyFromCompany(res_exec); |
| 385 | |
| 386 | /* Record if there was a command issues during pause; ignore pause/other setting related changes. */ |
| 387 | if (_pause_mode.Any() && _command_proc_table[cmd].type != CommandType::ServerSetting) _pause_mode.Set(PauseMode::CommandDuringPause); |
| 388 | |
| 389 | /* update signals if needed */ |
| 390 | UpdateSignalsInBuffer(); |
| 391 | |
| 392 | return res_exec; |
| 393 | } |
| 394 | |
| 395 | |
| 396 | /** |
nothing calls this directly
no test coverage detected