Files @ r25968:3a653e5d3685
Branch filter:

Location: cpp/openttd-patchpack/source/src/ai/ai_scanner.cpp - annotation

SamuXarick
Fix: reduce cost of building canals over objects on sea

It is not like we will drain the sea first, to put water back in it after.
Besides, the cost for draining the sea isn't calculated for all other cases either.
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r21383:942c32fb8b0e
r21383:942c32fb8b0e
r10696:8dfe83e30d01
r18508:f893337ab5c7
r11380:8edd3e28a734
r23607:36c15679007d
r10696:8dfe83e30d01
r18508:f893337ab5c7
r10762:c26063cf0293
r18666:f05d7caba088
r18508:f893337ab5c7
r18666:f05d7caba088
r10696:8dfe83e30d01
r23730:3b11f535de42
r23730:3b11f535de42
r10696:8dfe83e30d01
r24529:3dec691db49a
r18512:1adfa053a958
r18512:1adfa053a958
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r18508:f893337ab5c7
r10696:8dfe83e30d01
r18508:f893337ab5c7
r16514:bf011466da17
r16514:bf011466da17
r18508:f893337ab5c7
r16514:bf011466da17
r10788:e413614a4b4e
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r21388:73c9c3b28ec1
r10696:8dfe83e30d01
r21388:73c9c3b28ec1
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r18508:f893337ab5c7
r10696:8dfe83e30d01
r18508:f893337ab5c7
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r18508:f893337ab5c7
r10696:8dfe83e30d01
r11720:a2a7bf20700e
r24500:deda806a71a7
r24500:deda806a71a7
r18508:f893337ab5c7
r11720:a2a7bf20700e
r11720:a2a7bf20700e
r11720:a2a7bf20700e
r25655:1030dcb7eb52
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r11720:a2a7bf20700e
r11720:a2a7bf20700e
r11720:a2a7bf20700e
r11720:a2a7bf20700e
r11720:a2a7bf20700e
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r18508:f893337ab5c7
r18545:ddf2ea86fdad
r18545:ddf2ea86fdad
r18545:ddf2ea86fdad
r11720:a2a7bf20700e
r11720:a2a7bf20700e
r18545:ddf2ea86fdad
r11720:a2a7bf20700e
r18545:ddf2ea86fdad
r18545:ddf2ea86fdad
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r18508:f893337ab5c7
r10696:8dfe83e30d01
r23607:36c15679007d
r23607:36c15679007d
r10762:c26063cf0293
r10762:c26063cf0293
r21386:3ba07c8f5bce
r10774:95163043f047
r10762:c26063cf0293
r10762:c26063cf0293
r10762:c26063cf0293
r18508:f893337ab5c7
r24498:e9114d9ab04a
r10762:c26063cf0293
r10762:c26063cf0293
r14377:f63ba65f9d57
r14377:f63ba65f9d57
r14377:f63ba65f9d57
r21387:4ac1de161213
r14377:f63ba65f9d57
r18508:f893337ab5c7
r24498:e9114d9ab04a
r14377:f63ba65f9d57
r10762:c26063cf0293
r24498:e9114d9ab04a
r24498:e9114d9ab04a
r24498:e9114d9ab04a
r10762:c26063cf0293
r10762:c26063cf0293
r24500:deda806a71a7
r24500:deda806a71a7
r18508:f893337ab5c7
r24500:deda806a71a7
r18508:f893337ab5c7
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10762:c26063cf0293
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r18508:f893337ab5c7
r18666:f05d7caba088
r18666:f05d7caba088
r18666:f05d7caba088
r18666:f05d7caba088
r18666:f05d7caba088
r21388:73c9c3b28ec1
r10696:8dfe83e30d01
r18508:f893337ab5c7
r21388:73c9c3b28ec1
r10696:8dfe83e30d01
r10793:5ba2151e71e9
r18508:f893337ab5c7
r16957:b73e503c5e41
r18508:f893337ab5c7
r16957:b73e503c5e41
r16957:b73e503c5e41
r18508:f893337ab5c7
r10793:5ba2151e71e9
r18508:f893337ab5c7
r18508:f893337ab5c7
r21387:4ac1de161213
r18508:f893337ab5c7
r10793:5ba2151e71e9
r18508:f893337ab5c7
r24500:deda806a71a7
r24500:deda806a71a7
r10793:5ba2151e71e9
r24500:deda806a71a7
r10793:5ba2151e71e9
/*
 * 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 "../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);
	Script_CreateDummyInfo(this->engine->GetVM(), "AI", "ai");
}

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
{
	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++;
	for (; pos > 0; pos--) {
		it++;
		while (!GetAIInfo(it)->UseAsRandomAI()) it++;
	}
	return GetAIInfo(it);
#undef GetAIInfo
}

AIInfo *AIScannerInfo::FindInfo(const char *nameParam, int versionParam, bool force_exact_match)
{
	if (this->info_list.size() == 0) return nullptr;
	if (nameParam == nullptr) return nullptr;

	char ai_name[1024];
	strecpy(ai_name, nameParam, lastof(ai_name));
	strtolower(ai_name);

	if (versionParam == -1) {
		/* We want to load the latest version of this AI; so find it */
		if (this->info_single_list.find(ai_name) != this->info_single_list.end()) return static_cast<AIInfo *>(this->info_single_list[ai_name]);
		return nullptr;
	}

	if (force_exact_match) {
		/* Try to find a direct 'name.version' match */
		char ai_name_tmp[1024];
		seprintf(ai_name_tmp, lastof(ai_name_tmp), "%s.%d", ai_name, versionParam);
		strtolower(ai_name_tmp);
		if (this->info_list.find(ai_name_tmp) != this->info_list.end()) return static_cast<AIInfo *>(this->info_list[ai_name_tmp]);
		return nullptr;
	}

	AIInfo *info = nullptr;
	int version = -1;

	/* See if there is a compatible AI which goes by that name, with the highest
	 *  version which allows loading the requested version */
	for (const auto &item : this->info_list) {
		AIInfo *i = static_cast<AIInfo *>(item.second);
		if (strcasecmp(ai_name, i->GetName()) == 0 && i->CanLoadFromVersion(versionParam) && (version == -1 || i->GetVersion() > version)) {
			version = item.second->GetVersion();
			info = i;
		}
	}

	return info;
}


void AIScannerLibrary::Initialize()
{
	ScriptScanner::Initialize("AIScanner");
}

void AIScannerLibrary::GetScriptName(ScriptInfo *info, char *name, const char *last)
{
	AILibrary *library = static_cast<AILibrary *>(info);
	seprintf(name, last, "%s.%s", library->GetCategory(), library->GetInstanceName());
}

void AIScannerLibrary::RegisterAPI(class Squirrel *engine)
{
	AILibrary::RegisterAPI(engine);
}

AILibrary *AIScannerLibrary::FindLibrary(const char *library, int version)
{
	/* Internally we store libraries as 'library.version' */
	char library_name[1024];
	seprintf(library_name, lastof(library_name), "%s.%d", library, version);
	strtolower(library_name);

	/* Check if the library + version exists */
	ScriptInfoList::iterator it = this->info_list.find(library_name);
	if (it == this->info_list.end()) return nullptr;

	return static_cast<AILibrary *>((*it).second);
}