# HG changeset patch # User rubidium # Date 1173998782 0 # Node ID 9e0a193b2bec56b5c510a521e05c3bbf5f7783b7 # Parent 25b7d020a3a9a8fb3d430bd7e71c0237ac665383 (svn r9234) [NoAI] -Codechange: move away from the 'much' subdirectory approach for the API implementation. diff -r 25b7d020a3a9 -r 9e0a193b2bec source.list --- a/source.list Thu Mar 15 22:33:39 2007 +0000 +++ b/source.list Thu Mar 15 22:46:22 2007 +0000 @@ -309,15 +309,15 @@ ai/api/ai_map.hpp ai/api/ai_object.hpp ai/api/ai_town.hpp -ai/api/base/random.cpp -ai/api/cargo/query.cpp -ai/api/company/name.cpp -ai/api/company/money.cpp -ai/api/industry/query.cpp -ai/api/map/conversion.cpp -ai/api/map/query.cpp -ai/api/object/commands.cpp -ai/api/town/query.cpp + +# AI API Implementation +ai/api/ai_base.cpp +ai/api/ai_cargo.cpp +ai/api/ai_company.cpp +ai/api/ai_industry.cpp +ai/api/ai_map.cpp +ai/api/ai_object.cpp +ai/api/ai_town.cpp # NewGRF newgrf.cpp diff -r 25b7d020a3a9 -r 9e0a193b2bec src/ai/api/ai_base.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ai/api/ai_base.cpp Thu Mar 15 22:46:22 2007 +0000 @@ -0,0 +1,42 @@ +/* $Id$ */ + +/** @file ai_base.cpp handles the functions of the AIBase class */ + +#include "ai_base.hpp" + +#if defined(RANDOM_DEBUG) +uint32 AIBase::DoRandom(int line, const char *file) +#else +uint32 AIBase::Random() +#endif +{ + /* We pick RandomRange if we are in SP (so when saved, we do the same over and over) + * but we pick InteractiveRandomRange if we are a network_server or network-client. */ + if (_networking) return InteractiveRandom(); +#if defined(RANDOM_DEBUG) + return ::DoRandom(line, file); +#else + return ::Random(); +#endif +} + +#if defined(RANDOM_DEBUG) +uint AIBase::DoRandomRange(uint max, int line, const char *file) +#else +uint AIBase::RandomRange(uint max) +#endif +{ + /* We pick RandomRange if we are in SP (so when saved, we do the same over and over) + * but we pick InteractiveRandomRange if we are a network_server or network-client. */ + if (_networking) return InteractiveRandomRange(max); +#if defined(RANDOM_DEBUG) + return ::DoRandomRange(max, line, file); +#else + return ::RandomRange(max); +#endif +} + +bool AIBase::Chance(uint out, uint max) +{ + return (uint16)this->Random() <= (uint16)((65536 * out) / max); +} diff -r 25b7d020a3a9 -r 9e0a193b2bec src/ai/api/ai_cargo.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ai/api/ai_cargo.cpp Thu Mar 15 22:46:22 2007 +0000 @@ -0,0 +1,34 @@ +/* $Id$ */ + +/** @file ai_cargo.cpp handles the query-related of the AICargo class */ + +#include "ai_cargo.hpp" +#include "../../cargotype.h" +#include "../../player.h" // For economy.h +#include "../../economy.h" + +char *AICargo::GetCargoLabel(CargoID cargo_type) +{ + const CargoSpec *cargo = GetCargo(cargo_type); + if (cargo == NULL) return NULL; + + /* cargo->label is a uint32 packing a 4 character non-terminated string, + * like "PASS", "COAL", "OIL_". New ones can be defined by NewGRFs */ + char *cargo_label = MallocT(sizeof(cargo->label) + 1); + for (uint i = 0; i < sizeof(cargo->label); i++) { + cargo_label[i] = GB(cargo->label, (sizeof(cargo->label) - i - 1) * 8, 8); + } + cargo_label[sizeof(cargo->label)] = '\0'; + return cargo_label; +} + +bool AICargo::IsFreight(CargoID cargo_type) +{ + const CargoSpec *cargo = GetCargo(cargo_type); + return cargo != NULL && cargo->is_freight; +} + +int32 AICargo::GetCargoIncome(uint32 distance, uint32 days_in_transit, CargoID cargo_type) +{ + return GetTransportedGoodsIncome(1, distance, days_in_transit, cargo_type); +} diff -r 25b7d020a3a9 -r 9e0a193b2bec src/ai/api/ai_company.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ai/api/ai_company.cpp Thu Mar 15 22:46:22 2007 +0000 @@ -0,0 +1,76 @@ +/* $Id$ */ + +/** @file ai_company.cpp handles the money-related functions of the AICompany class */ + +#include "ai_company.hpp" +#include "../../player.h" +#include "../../economy.h" +#include "../../strings.h" + +bool AICompany::SetCompanyName(const char *name) +{ + if (name == NULL) return false; + + _cmd_text = name; + return !CmdFailed(this->DoCommand(0, 0, 0, DC_EXEC, CMD_CHANGE_PRESIDENT_NAME)); +} + +char *AICompany::GetCompanyName() +{ + static const int len = 64; + char *company_name = MallocT(len); + GetString(company_name, GetPlayer(_current_player)->name_1, &company_name[len - 1]); + + return company_name; +} + +int32 AICompany::GetCompanyValue() +{ + return GetPlayer(_current_player)->cur_economy.company_value; +} + +int32 AICompany::GetBankBalance() +{ + return GetPlayer(_current_player)->player_money; +} + +int32 AICompany::GetLoanAmount() +{ + return GetPlayer(_current_player)->current_loan; +} + +int32 AICompany::GetMaxLoanAmount() +{ + return _economy.max_loan; +} + +int32 AICompany::GetLoanInterval() +{ + return LOAN_INTERVAL; +} + +bool AICompany::SetLoanAmount(int32 loan) +{ + if (loan < 0 || + (loan % this->GetLoanInterval()) != 0 || + loan > this->GetMaxLoanAmount() || + (loan - this->GetLoanAmount() + this->GetBankBalance()) < 0) { + return false; + } + + /* When we get/repay everything at once (or the maximum we can repay), + * use the shortcut for that. Otherwise send several commands at once */ + if (loan == 0) { + return this->CmdSucceeded(this->DoCommand(0, 0, true, DC_EXEC, CMD_DECREASE_LOAN)); + } + if (loan == this->GetMaxLoanAmount()) { + return this->CmdSucceeded(this->DoCommand(0, 0, true, DC_EXEC, CMD_INCREASE_LOAN)); + } + + bool increase = loan > this->GetLoanAmount(); + for (uint diff_loan = abs(loan - this->GetLoanAmount()) / this->GetLoanInterval(); diff_loan > 0; diff_loan--) { + if (this->CmdFailed(this->DoCommand(0, 0, false, DC_EXEC, increase ? CMD_INCREASE_LOAN : CMD_DECREASE_LOAN))) return false; + } + + return true; +} diff -r 25b7d020a3a9 -r 9e0a193b2bec src/ai/api/ai_industry.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ai/api/ai_industry.cpp Thu Mar 15 22:46:22 2007 +0000 @@ -0,0 +1,41 @@ +/* $Id$ */ + +/** @file ai_industry.cpp handles the query-related of the AIIndustry class */ + +#include "ai_industry.hpp" +#include "../../industry.h" +#include "../../strings.h" +#include "../../variables.h" /* For SetDParam */ +#include "table/strings.h" + +IndustryID AIIndustry::GetMaxIndustryID() +{ + return ::GetMaxIndustryIndex(); +} + +int32 AIIndustry::GetIndustryCount() +{ + return ::GetNumIndustries(); +} + +bool AIIndustry::IsValidIndustry(IndustryID industry_id) +{ + return ::IsValidIndustryID(industry_id); +} + +char *AIIndustry::GetName(IndustryID industry_id) +{ + static const int len = 64; + char *industry_name = MallocT(len); + + SetDParam(0, industry_id); + GetString(industry_name, STR_INDUSTRY, &industry_name[len - 1]); + + return industry_name; +} + +TileIndex AIIndustry::GetLocation(IndustryID industry_id) +{ + const Industry *i = ::GetIndustry(industry_id); + return i->xy; +} diff -r 25b7d020a3a9 -r 9e0a193b2bec src/ai/api/ai_map.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ai/api/ai_map.cpp Thu Mar 15 22:46:22 2007 +0000 @@ -0,0 +1,35 @@ +/* $Id$ */ + +/** @file ai_map.cpp handles the query-related of the AIMap class */ + +#include "ai_map.hpp" + +bool AIMap::IsValidTile(TileIndex t) +{ + return t < this->GetMapSize(); +} + +TileIndex AIMap::GetMapSize() +{ + return ::MapSize(); +} + +uint32 AIMap::GetMapSizeX() +{ + return ::MapSizeX(); +} + +uint32 AIMap::GetMapSizeY() +{ + return ::MapSizeY(); +} + +uint32 AIMap::GetTileX(TileIndex t) +{ + return ::TileX(t); +} + +uint32 AIMap::GetTileY(TileIndex t) +{ + return ::TileY(t); +} diff -r 25b7d020a3a9 -r 9e0a193b2bec src/ai/api/ai_object.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ai/api/ai_object.cpp Thu Mar 15 22:46:22 2007 +0000 @@ -0,0 +1,61 @@ +/* $Id$ */ + +/** @file ai_object.cpp handles the commands-related functions of the AIObject class */ + +#include "ai_object.hpp" +#include "../../player.h" + +bool AIObject::CmdFailed(int32 res) +{ + return ::CmdFailed(res); +} + +bool AIObject::CmdSucceeded(int32 res) +{ + return !::CmdFailed(res); +} + +int32 AIObject::DoCommandCc(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc, CommandCallback *callback) +{ + PlayerID old_lp; + int32 res = 0; + const char* tmp_cmdtext; + + /* The test already resets _cmd_text, so backup the pointer */ + tmp_cmdtext = _cmd_text; + + /* First, do a test-run to see if we can do this */ + res = ::DoCommand(tile, p1, p2, flags & ~DC_EXEC, procc); + /* The command failed, or you didn't want to execute, or you are quering, return */ + if (this->CmdFailed(res) || !(flags & DC_EXEC) || (flags & DC_QUERY_COST)) return res; + + /* Restore _cmd_text */ + _cmd_text = tmp_cmdtext; + + /* If we did a DC_EXEC, and the command did not return an error, execute it + * over the network */ + if (flags & DC_AUTO) procc |= CMD_AUTO; + if (flags & DC_NO_WATER) procc |= CMD_NO_WATER; + +#ifdef ENABLE_NETWORK + /* Send the command */ + if (_networking) { + /* NetworkSend_Command needs _local_player to be set correctly, so + * adjust it, and put it back right after the function */ + old_lp = _local_player; + _local_player = _current_player; + + ::NetworkSend_Command(tile, p1, p2, procc, callback); + + /* Set _local_player back */ + _local_player = old_lp; + } else { +#else + { +#endif + /* For SinglePlayer we execute the command immediatly */ + ::DoCommandP(tile, p1, p2, callback, procc); + } + + return res; +} diff -r 25b7d020a3a9 -r 9e0a193b2bec src/ai/api/ai_town.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ai/api/ai_town.cpp Thu Mar 15 22:46:22 2007 +0000 @@ -0,0 +1,47 @@ +/* $Id$ */ + +/** @file ai_town.cpp handles the town-related functions of the AITown class */ + +#include "ai_town.hpp" +#include "../../town.h" +#include "../../strings.h" +#include "../../variables.h" /* For SetDParam */ +#include "table/strings.h" + +TownID AITown::GetMaxTownID() +{ + return ::GetMaxTownIndex(); +} + +int32 AITown::GetTownCount() +{ + return ::GetNumTowns(); +} + +bool AITown::IsValidTown(TownID town_id) +{ + return ::IsValidTownID(town_id); +} + +char *AITown::GetName(TownID town_id) +{ + static const int len = 64; + char *town_name = MallocT(len); + + SetDParam(0, town_id); + GetString(town_name, STR_TOWN, &town_name[len - 1]); + + return town_name; +} + +int32 AITown::GetPopulation(TownID town_id) +{ + const Town *t = ::GetTown(town_id); + return t->population; +} + +TileIndex AITown::GetLocation(TownID town_id) +{ + const Town *t = ::GetTown(town_id); + return t->xy; +} diff -r 25b7d020a3a9 -r 9e0a193b2bec src/ai/api/base/random.cpp --- a/src/ai/api/base/random.cpp Thu Mar 15 22:33:39 2007 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* $Id$ */ - -/** @file random.cpp handles the random functions of the AIBase class */ - -#include "../ai_base.hpp" - -#if defined(RANDOM_DEBUG) -uint32 AIBase::DoRandom(int line, const char *file) -#else -uint32 AIBase::Random() -#endif -{ - /* We pick RandomRange if we are in SP (so when saved, we do the same over and over) - * but we pick InteractiveRandomRange if we are a network_server or network-client. */ - if (_networking) return InteractiveRandom(); -#if defined(RANDOM_DEBUG) - return ::DoRandom(line, file); -#else - return ::Random(); -#endif -} - -#if defined(RANDOM_DEBUG) -uint AIBase::DoRandomRange(uint max, int line, const char *file) -#else -uint AIBase::RandomRange(uint max) -#endif -{ - /* We pick RandomRange if we are in SP (so when saved, we do the same over and over) - * but we pick InteractiveRandomRange if we are a network_server or network-client. */ - if (_networking) return InteractiveRandomRange(max); -#if defined(RANDOM_DEBUG) - return ::DoRandomRange(max, line, file); -#else - return ::RandomRange(max); -#endif -} - -bool AIBase::Chance(uint out, uint max) -{ - return (uint16)this->Random() <= (uint16)((65536 * out) / max); -} diff -r 25b7d020a3a9 -r 9e0a193b2bec src/ai/api/cargo/query.cpp --- a/src/ai/api/cargo/query.cpp Thu Mar 15 22:33:39 2007 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -/* $Id$ */ - -/** @file query.cpp handles the query-related of the AICargo class */ - -#include "../ai_cargo.hpp" -#include "../../../cargotype.h" -#include "../../../player.h" // For economy.h -#include "../../../economy.h" - -char *AICargo::GetCargoLabel(CargoID cargo_type) -{ - const CargoSpec *cargo = GetCargo(cargo_type); - if (cargo == NULL) return NULL; - - /* cargo->label is a uint32 packing a 4 character non-terminated string, - * like "PASS", "COAL", "OIL_". New ones can be defined by NewGRFs */ - char *cargo_label = MallocT(sizeof(cargo->label) + 1); - for (uint i = 0; i < sizeof(cargo->label); i++) { - cargo_label[i] = GB(cargo->label, (sizeof(cargo->label) - i - 1) * 8, 8); - } - cargo_label[sizeof(cargo->label)] = '\0'; - return cargo_label; -} - -bool AICargo::IsFreight(CargoID cargo_type) -{ - const CargoSpec *cargo = GetCargo(cargo_type); - return cargo != NULL && cargo->is_freight; -} - -int32 AICargo::GetCargoIncome(uint32 distance, uint32 days_in_transit, CargoID cargo_type) -{ - return GetTransportedGoodsIncome(1, distance, days_in_transit, cargo_type); -} diff -r 25b7d020a3a9 -r 9e0a193b2bec src/ai/api/company/money.cpp --- a/src/ai/api/company/money.cpp Thu Mar 15 22:33:39 2007 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* $Id$ */ - -/** @file money.cpp handles the money-related functions of the AICompany class */ - -#include "../ai_company.hpp" -#include "../../../player.h" -#include "../../../economy.h" - -int32 AICompany::GetCompanyValue() -{ - return GetPlayer(_current_player)->cur_economy.company_value; -} - -int32 AICompany::GetBankBalance() -{ - return GetPlayer(_current_player)->player_money; -} - -int32 AICompany::GetLoanAmount() -{ - return GetPlayer(_current_player)->current_loan; -} - -int32 AICompany::GetMaxLoanAmount() -{ - return _economy.max_loan; -} - -int32 AICompany::GetLoanInterval() -{ - return LOAN_INTERVAL; -} - -bool AICompany::SetLoanAmount(int32 loan) -{ - if (loan < 0 || - (loan % this->GetLoanInterval()) != 0 || - loan > this->GetMaxLoanAmount() || - (loan - this->GetLoanAmount() + this->GetBankBalance()) < 0) { - return false; - } - - /* When we get/repay everything at once (or the maximum we can repay), - * use the shortcut for that. Otherwise send several commands at once */ - if (loan == 0) { - return this->CmdSucceeded(this->DoCommand(0, 0, true, DC_EXEC, CMD_DECREASE_LOAN)); - } - if (loan == this->GetMaxLoanAmount()) { - return this->CmdSucceeded(this->DoCommand(0, 0, true, DC_EXEC, CMD_INCREASE_LOAN)); - } - - bool increase = loan > this->GetLoanAmount(); - for (uint diff_loan = abs(loan - this->GetLoanAmount()) / this->GetLoanInterval(); diff_loan > 0; diff_loan--) { - if (this->CmdFailed(this->DoCommand(0, 0, false, DC_EXEC, increase ? CMD_INCREASE_LOAN : CMD_DECREASE_LOAN))) return false; - } - - return true; -} diff -r 25b7d020a3a9 -r 9e0a193b2bec src/ai/api/company/name.cpp --- a/src/ai/api/company/name.cpp Thu Mar 15 22:33:39 2007 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -/* $Id$ */ - -/** @file name.cpp handles the company name-related functions of the AICompany class */ - -#include "../ai_company.hpp" -#include "../../../player.h" -#include "../../../strings.h" - -bool AICompany::SetCompanyName(const char *name) -{ - if (name == NULL) return false; - - _cmd_text = name; - return !CmdFailed(this->DoCommand(0, 0, 0, DC_EXEC, CMD_CHANGE_PRESIDENT_NAME)); -} - -char *AICompany::GetCompanyName() -{ - static const int len = 64; - char *company_name = MallocT(len); - GetString(company_name, GetPlayer(_current_player)->name_1, &company_name[len - 1]); - - return company_name; -} diff -r 25b7d020a3a9 -r 9e0a193b2bec src/ai/api/industry/query.cpp --- a/src/ai/api/industry/query.cpp Thu Mar 15 22:33:39 2007 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* $Id$ */ - -/** @file query.cpp handles the query-related of the AIIndustry class */ - -#include "../ai_industry.hpp" -#include "../../../industry.h" -#include "../../../strings.h" -#include "../../../variables.h" /* For SetDParam */ -#include "table/strings.h" - -IndustryID AIIndustry::GetMaxIndustryID() -{ - return ::GetMaxIndustryIndex(); -} - -int32 AIIndustry::GetIndustryCount() -{ - return ::GetNumIndustries(); -} - -bool AIIndustry::IsValidIndustry(IndustryID industry_id) -{ - return ::IsValidIndustryID(industry_id); -} - -char *AIIndustry::GetName(IndustryID industry_id) -{ - static const int len = 64; - char *industry_name = MallocT(len); - - SetDParam(0, industry_id); - GetString(industry_name, STR_INDUSTRY, &industry_name[len - 1]); - - return industry_name; -} - -TileIndex AIIndustry::GetLocation(IndustryID industry_id) -{ - const Industry *i = ::GetIndustry(industry_id); - return i->xy; -} diff -r 25b7d020a3a9 -r 9e0a193b2bec src/ai/api/map/conversion.cpp --- a/src/ai/api/map/conversion.cpp Thu Mar 15 22:33:39 2007 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -/* $Id$ */ - -/** @file conversion.cpp handles the conversion-related of the AIMap class */ - -#include "../ai_map.hpp" - -uint32 AIMap::GetTileX(TileIndex t) -{ - return ::TileX(t); -} - -uint32 AIMap::GetTileY(TileIndex t) -{ - return ::TileY(t); -} diff -r 25b7d020a3a9 -r 9e0a193b2bec src/ai/api/map/query.cpp --- a/src/ai/api/map/query.cpp Thu Mar 15 22:33:39 2007 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -/* $Id$ */ - -/** @file query.cpp handles the query-related of the AIMap class */ - -#include "../ai_map.hpp" - -bool AIMap::IsValidTile(TileIndex t) -{ - return t < this->GetMapSize(); -} - -TileIndex AIMap::GetMapSize() -{ - return ::MapSize(); -} - -uint32 AIMap::GetMapSizeX() -{ - return ::MapSizeX(); -} - -uint32 AIMap::GetMapSizeY() -{ - return ::MapSizeY(); -} diff -r 25b7d020a3a9 -r 9e0a193b2bec src/ai/api/object/commands.cpp --- a/src/ai/api/object/commands.cpp Thu Mar 15 22:33:39 2007 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/* $Id$ */ - -/** @file commands.cpp handles the commands-related functions of the AIObject class */ - -#include "../ai_object.hpp" -#include "../../../player.h" - -bool AIObject::CmdFailed(int32 res) -{ - return ::CmdFailed(res); -} - -bool AIObject::CmdSucceeded(int32 res) -{ - return !::CmdFailed(res); -} - -int32 AIObject::DoCommandCc(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc, CommandCallback *callback) -{ - PlayerID old_lp; - int32 res = 0; - const char* tmp_cmdtext; - - /* The test already resets _cmd_text, so backup the pointer */ - tmp_cmdtext = _cmd_text; - - /* First, do a test-run to see if we can do this */ - res = ::DoCommand(tile, p1, p2, flags & ~DC_EXEC, procc); - /* The command failed, or you didn't want to execute, or you are quering, return */ - if (this->CmdFailed(res) || !(flags & DC_EXEC) || (flags & DC_QUERY_COST)) return res; - - /* Restore _cmd_text */ - _cmd_text = tmp_cmdtext; - - /* If we did a DC_EXEC, and the command did not return an error, execute it - * over the network */ - if (flags & DC_AUTO) procc |= CMD_AUTO; - if (flags & DC_NO_WATER) procc |= CMD_NO_WATER; - -#ifdef ENABLE_NETWORK - /* Send the command */ - if (_networking) { - /* NetworkSend_Command needs _local_player to be set correctly, so - * adjust it, and put it back right after the function */ - old_lp = _local_player; - _local_player = _current_player; - - ::NetworkSend_Command(tile, p1, p2, procc, callback); - - /* Set _local_player back */ - _local_player = old_lp; - } else { -#else - { -#endif - /* For SinglePlayer we execute the command immediatly */ - ::DoCommandP(tile, p1, p2, callback, procc); - } - - return res; -} diff -r 25b7d020a3a9 -r 9e0a193b2bec src/ai/api/town/query.cpp --- a/src/ai/api/town/query.cpp Thu Mar 15 22:33:39 2007 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* $Id$ */ - -/** @file query.cpp handles the town-related functions of the AITown class */ - -#include "../ai_town.hpp" -#include "../../../town.h" -#include "../../../strings.h" -#include "../../../variables.h" /* For SetDParam */ -#include "table/strings.h" - -TownID AITown::GetMaxTownID() -{ - return ::GetMaxTownIndex(); -} - -int32 AITown::GetTownCount() -{ - return ::GetNumTowns(); -} - -bool AITown::IsValidTown(TownID town_id) -{ - return ::IsValidTownID(town_id); -} - -char *AITown::GetName(TownID town_id) -{ - static const int len = 64; - char *town_name = MallocT(len); - - SetDParam(0, town_id); - GetString(town_name, STR_TOWN, &town_name[len - 1]); - - return town_name; -} - -int32 AITown::GetPopulation(TownID town_id) -{ - const Town *t = ::GetTown(town_id); - return t->population; -} - -TileIndex AITown::GetLocation(TownID town_id) -{ - const Town *t = ::GetTown(town_id); - return t->xy; -}