| 1444 | } |
| 1445 | |
| 1446 | static bool ConStartAI(std::span<std::string_view> argv) |
| 1447 | { |
| 1448 | if (argv.empty() || argv.size() > 3) { |
| 1449 | IConsolePrint(CC_HELP, "Start a new AI. Usage: 'start_ai [<AI>] [<settings>]'."); |
| 1450 | IConsolePrint(CC_HELP, "Start a new AI. If <AI> is given, it starts that specific AI (if found)."); |
| 1451 | IConsolePrint(CC_HELP, "If <settings> is given, it is parsed and the AI settings are set to that."); |
| 1452 | return true; |
| 1453 | } |
| 1454 | |
| 1455 | if (_game_mode != GM_NORMAL) { |
| 1456 | IConsolePrint(CC_ERROR, "AIs can only be managed in a game."); |
| 1457 | return true; |
| 1458 | } |
| 1459 | |
| 1460 | if (Company::GetNumItems() == CompanyPool::MAX_SIZE) { |
| 1461 | IConsolePrint(CC_ERROR, "Can't start a new AI (no more free slots)."); |
| 1462 | return true; |
| 1463 | } |
| 1464 | if (_networking && !_network_server) { |
| 1465 | IConsolePrint(CC_ERROR, "Only the server can start a new AI."); |
| 1466 | return true; |
| 1467 | } |
| 1468 | if (_networking && !_settings_game.ai.ai_in_multiplayer) { |
| 1469 | IConsolePrint(CC_ERROR, "AIs are not allowed in multiplayer by configuration."); |
| 1470 | IConsolePrint(CC_ERROR, "Switch AI -> AI in multiplayer to True."); |
| 1471 | return true; |
| 1472 | } |
| 1473 | if (!AI::CanStartNew()) { |
| 1474 | IConsolePrint(CC_ERROR, "Can't start a new AI."); |
| 1475 | return true; |
| 1476 | } |
| 1477 | |
| 1478 | int n = 0; |
| 1479 | /* Find the next free slot */ |
| 1480 | for (const Company *c : Company::Iterate()) { |
| 1481 | if (c->index != n) break; |
| 1482 | n++; |
| 1483 | } |
| 1484 | |
| 1485 | AIConfig *config = AIConfig::GetConfig((CompanyID)n); |
| 1486 | if (argv.size() >= 2) { |
| 1487 | config->Change(argv[1], -1, false); |
| 1488 | |
| 1489 | /* If the name is not found, and there is a dot in the name, |
| 1490 | * try again with the assumption everything right of the dot is |
| 1491 | * the version the user wants to load. */ |
| 1492 | if (!config->HasScript()) { |
| 1493 | StringConsumer consumer{std::string_view{argv[1]}}; |
| 1494 | auto name = consumer.ReadUntilChar('.', StringConsumer::SKIP_ONE_SEPARATOR); |
| 1495 | if (consumer.AnyBytesLeft()) { |
| 1496 | auto version = consumer.TryReadIntegerBase<uint32_t>(10); |
| 1497 | if (!version.has_value()) { |
| 1498 | IConsolePrint(CC_ERROR, "The version is not a valid number."); |
| 1499 | return true; |
| 1500 | } |
| 1501 | config->Change(name, *version, true); |
| 1502 | } |
| 1503 | } |
nothing calls this directly
no test coverage detected