Changeset - r26641:01889b29735a
[Not reviewed]
master
0 4 0
Loïc Guilloux - 18 months ago 2022-12-15 20:43:07
glx22@users.noreply.github.com
Fix #10206: Disable scripts in intro game (#10241)
4 files changed with 11 insertions and 2 deletions:
0 comments (0 inline, 0 general)
src/ai/ai_instance.cpp
Show inline comments
 
@@ -40,48 +40,51 @@ AIInstance::AIInstance() :
 
void AIInstance::Initialize(AIInfo *info)
 
{
 
	this->versionAPI = info->GetAPIVersion();
 

	
 
	/* Register the AIController (including the "import" command) */
 
	SQAIController_Register(this->engine);
 

	
 
	ScriptInstance::Initialize(info->GetMainScript(), info->GetInstanceName(), _current_company);
 
}
 

	
 
void AIInstance::RegisterAPI()
 
{
 
	ScriptInstance::RegisterAPI();
 

	
 
	/* Register all classes */
 
	SQAI_RegisterAll(this->engine);
 

	
 
	if (!this->LoadCompatibilityScripts(this->versionAPI, AI_DIR)) this->Died();
 
}
 

	
 
void AIInstance::Died()
 
{
 
	ScriptInstance::Died();
 

	
 
	/* Intro is not supposed to use AI, but it may have 'dummy' AI which instant dies. */
 
	if (_game_mode == GM_MENU) return;
 

	
 
	ShowAIDebugWindow(_current_company);
 

	
 
	const AIInfo *info = AIConfig::GetConfig(_current_company, AIConfig::SSS_FORCE_GAME)->GetInfo();
 
	if (info != nullptr) {
 
		ShowErrorMessage(STR_ERROR_AI_PLEASE_REPORT_CRASH, INVALID_STRING_ID, WL_WARNING);
 

	
 
		if (info->GetURL() != nullptr) {
 
			ScriptLog::Info("Please report the error to the following URL:");
 
			ScriptLog::Info(info->GetURL());
 
		}
 
	}
 
}
 

	
 
void AIInstance::LoadDummyScript()
 
{
 
	ScriptAllocatorScope alloc_scope(this->engine);
 
	extern void Script_CreateDummy(HSQUIRRELVM vm, StringID string, const char *type);
 
	Script_CreateDummy(this->engine->GetVM(), STR_ERROR_AI_NO_AI_FOUND, "AI");
 
}
 

	
 
int AIInstance::GetSetting(const char *name)
 
{
 
	return AIConfig::GetConfig(_current_company)->GetSetting(name);
 
}
src/ai/ai_scanner.cpp
Show inline comments
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file ai_scanner.cpp allows scanning AI scripts */
 

	
 
#include "../stdafx.h"
 
#include "../debug.h"
 
#include "../network/network.h"
 
#include "../openttd.h"
 
#include "../core/random_func.hpp"
 

	
 
#include "../script/squirrel_class.hpp"
 
#include "ai_info.hpp"
 
#include "ai_scanner.hpp"
 

	
 
#include "../safeguards.h"
 

	
 

	
 
AIScannerInfo::AIScannerInfo() :
 
	ScriptScanner(),
 
	info_dummy(nullptr)
 
{
 
}
 

	
 
void AIScannerInfo::Initialize()
 
{
 
	ScriptScanner::Initialize("AIScanner");
 

	
 
	ScriptAllocatorScope alloc_scope(this->engine);
 

	
 
	/* Create the dummy AI */
 
	this->main_script = "%_dummy";
 
	extern void Script_CreateDummyInfo(HSQUIRRELVM vm, const char *type, const char *dir);
 
@@ -38,48 +39,53 @@ void AIScannerInfo::Initialize()
 
}
 

	
 
void AIScannerInfo::SetDummyAI(class AIInfo *info)
 
{
 
	this->info_dummy = info;
 
}
 

	
 
AIScannerInfo::~AIScannerInfo()
 
{
 
	delete this->info_dummy;
 
}
 

	
 
void AIScannerInfo::GetScriptName(ScriptInfo *info, char *name, const char *last)
 
{
 
	seprintf(name, last, "%s", info->GetName());
 
}
 

	
 
void AIScannerInfo::RegisterAPI(class Squirrel *engine)
 
{
 
	AIInfo::RegisterAPI(engine);
 
}
 

	
 
AIInfo *AIScannerInfo::SelectRandomAI() const
 
{
 
	if (_game_mode == GM_MENU) {
 
		Debug(script, 0, "The intro game should not use AI, loading 'dummy' AI.");
 
		return this->info_dummy;
 
	}
 

	
 
	uint num_random_ais = 0;
 
	for (const auto &item : info_single_list) {
 
		AIInfo *i = static_cast<AIInfo *>(item.second);
 
		if (i->UseAsRandomAI()) num_random_ais++;
 
	}
 

	
 
	if (num_random_ais == 0) {
 
		Debug(script, 0, "No suitable AI found, loading 'dummy' AI.");
 
		return this->info_dummy;
 
	}
 

	
 
	/* Find a random AI */
 
	uint pos;
 
	if (_networking) {
 
		pos = InteractiveRandomRange(num_random_ais);
 
	} else {
 
		pos = RandomRange(num_random_ais);
 
	}
 

	
 
	/* Find the Nth item from the array */
 
	ScriptInfoList::const_iterator it = this->info_single_list.begin();
 

	
 
#define GetAIInfo(it) static_cast<AIInfo *>((*it).second)
 
	while (!GetAIInfo(it)->UseAsRandomAI()) it++;
src/saveload/ai_sl.cpp
Show inline comments
 
@@ -56,49 +56,49 @@ static void SaveReal_AIPL(int *index_ptr
 
	/* If the AI was active, store its data too */
 
	if (Company::IsValidAiID(index)) AI::Save(index);
 
}
 

	
 
struct AIPLChunkHandler : ChunkHandler {
 
	AIPLChunkHandler() : ChunkHandler('AIPL', CH_TABLE) {}
 

	
 
	void Load() const override
 
	{
 
		const std::vector<SaveLoad> slt = SlCompatTableHeader(_ai_company_desc, _ai_company_sl_compat);
 

	
 
		/* Free all current data */
 
		for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
 
			AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->Change(nullptr);
 
		}
 

	
 
		CompanyID index;
 
		while ((index = (CompanyID)SlIterateArray()) != (CompanyID)-1) {
 
			if (index >= MAX_COMPANIES) SlErrorCorrupt("Too many AI configs");
 

	
 
			_ai_saveload_is_random = false;
 
			_ai_saveload_version = -1;
 
			SlObject(nullptr, slt);
 

	
 
			if (_networking && !_network_server) {
 
			if (_game_mode == GM_MENU || (_networking && !_network_server)) {
 
				if (Company::IsValidAiID(index)) AIInstance::LoadEmpty();
 
				continue;
 
			}
 

	
 
			AIConfig *config = AIConfig::GetConfig(index, AIConfig::SSS_FORCE_GAME);
 
			if (_ai_saveload_name.empty()) {
 
				/* A random AI. */
 
				config->Change(nullptr, -1, false, true);
 
			} else {
 
				config->Change(_ai_saveload_name.c_str(), _ai_saveload_version, false, _ai_saveload_is_random);
 
				if (!config->HasScript()) {
 
					/* No version of the AI available that can load the data. Try to load the
 
					 * latest version of the AI instead. */
 
					config->Change(_ai_saveload_name.c_str(), -1, false, _ai_saveload_is_random);
 
					if (!config->HasScript()) {
 
						if (_ai_saveload_name.compare("%_dummy") != 0) {
 
							Debug(script, 0, "The savegame has an AI by the name '{}', version {} which is no longer available.", _ai_saveload_name, _ai_saveload_version);
 
							Debug(script, 0, "A random other AI will be loaded in its place.");
 
						} else {
 
							Debug(script, 0, "The savegame had no AIs available at the time of saving.");
 
							Debug(script, 0, "A random available AI will be loaded now.");
 
						}
 
					} else {
 
						Debug(script, 0, "The savegame has an AI by the name '{}', version {} which is no longer available.", _ai_saveload_name, _ai_saveload_version);
src/saveload/game_sl.cpp
Show inline comments
 
@@ -48,49 +48,49 @@ static void SaveReal_GSDT(int *index_ptr
 
	}
 

	
 
	_game_saveload_is_random = config->IsRandom();
 
	_game_saveload_settings = config->SettingsToString();
 

	
 
	SlObject(nullptr, _game_script_desc);
 
	Game::Save();
 
}
 

	
 
struct GSDTChunkHandler : ChunkHandler {
 
	GSDTChunkHandler() : ChunkHandler('GSDT', CH_TABLE) {}
 

	
 
	void Load() const override
 
	{
 
		const std::vector<SaveLoad> slt = SlCompatTableHeader(_game_script_desc, _game_script_sl_compat);
 

	
 
		/* Free all current data */
 
		GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME)->Change(nullptr);
 

	
 
		if (SlIterateArray() == -1) return;
 

	
 
		_game_saveload_version = -1;
 
		SlObject(nullptr, slt);
 

	
 
		if (_networking && !_network_server) {
 
		if (_game_mode == GM_MENU || (_networking && !_network_server)) {
 
			GameInstance::LoadEmpty();
 
			if (SlIterateArray() != -1) SlErrorCorrupt("Too many GameScript configs");
 
			return;
 
		}
 

	
 
		GameConfig *config = GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME);
 
		if (!_game_saveload_name.empty()) {
 
			config->Change(_game_saveload_name.c_str(), _game_saveload_version, false, _game_saveload_is_random);
 
			if (!config->HasScript()) {
 
				/* No version of the GameScript available that can load the data. Try to load the
 
				 * latest version of the GameScript instead. */
 
				config->Change(_game_saveload_name.c_str(), -1, false, _game_saveload_is_random);
 
				if (!config->HasScript()) {
 
					if (_game_saveload_name.compare("%_dummy") != 0) {
 
						Debug(script, 0, "The savegame has an GameScript by the name '{}', version {} which is no longer available.", _game_saveload_name, _game_saveload_version);
 
						Debug(script, 0, "This game will continue to run without GameScript.");
 
					} else {
 
						Debug(script, 0, "The savegame had no GameScript available at the time of saving.");
 
						Debug(script, 0, "This game will continue to run without GameScript.");
 
					}
 
				} else {
 
					Debug(script, 0, "The savegame has an GameScript by the name '{}', version {} which is no longer available.", _game_saveload_name, _game_saveload_version);
 
					Debug(script, 0, "The latest version of that GameScript has been loaded instead, but it'll not get the savegame data as it's incompatible.");
 
				}
0 comments (0 inline, 0 general)