| 396 | |
| 397 | template <Commands Tcmd, typename Tret, typename... Targs> |
| 398 | bool ScriptObject::ScriptDoCommandHelper<Tcmd, Tret(*)(DoCommandFlags, Targs...)>::Execute(Script_SuspendCallbackProc *callback, std::tuple<Targs...> args) |
| 399 | { |
| 400 | auto [err, estimate_only, asynchronous, networking] = ScriptObject::DoCommandPrep(); |
| 401 | if (err) return false; |
| 402 | |
| 403 | if (!::GetCommandFlags<Tcmd>().Test(CommandFlag::StrCtrl)) { |
| 404 | ScriptObjectInternal::SanitizeStringsHelper(args, std::index_sequence_for<Targs...>{}); |
| 405 | } |
| 406 | |
| 407 | TileIndex tile{}; |
| 408 | if constexpr (std::is_same_v<TileIndex, std::tuple_element_t<0, decltype(args)>>) { |
| 409 | tile = std::get<0>(args); |
| 410 | } |
| 411 | |
| 412 | /* Do not even think about executing out-of-bounds tile-commands. */ |
| 413 | if (tile != 0 && (tile >= Map::Size() || (!IsValidTile(tile) && !GetCommandFlags<Tcmd>().Test(CommandFlag::AllTiles)))) return false; |
| 414 | |
| 415 | /* Only set ClientID parameters when the command does not come from the network. */ |
| 416 | if constexpr (::GetCommandFlags<Tcmd>().Test(CommandFlag::ClientID)) ScriptObjectInternal::SetClientIds(args, std::index_sequence_for<Targs...>{}); |
| 417 | |
| 418 | /* Store the command for command callback validation. */ |
| 419 | if (!estimate_only && networking) ScriptObject::SetLastCommand(EndianBufferWriter<CommandDataBuffer>::FromValue(args), Tcmd); |
| 420 | |
| 421 | /* Try to perform the command. */ |
| 422 | Tret res = ::Command<Tcmd>::Unsafe((StringID)0, (!asynchronous && networking) ? ScriptObject::GetDoCommandCallback() : nullptr, false, estimate_only, tile, args); |
| 423 | |
| 424 | if constexpr (std::is_same_v<Tret, CommandCost>) { |
| 425 | return ScriptObject::DoCommandProcessResult(res, callback, estimate_only, asynchronous); |
| 426 | } else { |
| 427 | ScriptObject::SetLastCommandResData(EndianBufferWriter<CommandDataBuffer>::FromValue(ScriptObjectInternal::RemoveFirstTupleElement(res))); |
| 428 | return ScriptObject::DoCommandProcessResult(std::get<0>(res), callback, estimate_only, asynchronous); |
| 429 | } |
| 430 | } |
| 431 | |
| 432 | /** |
| 433 | * Internally used class to automate the ScriptObject reference counting. |
nothing calls this directly
no test coverage detected