Changeset - r20742:35845025ed4c
[Not reviewed]
master
0 9 0
zuu - 11 years ago 2013-09-19 18:48:05
zuu@openttd.org
(svn r25785) -Feature: [Script] Allow AIs and GS to found towns. Allow GS to rename towns
9 files changed with 106 insertions and 4 deletions:
0 comments (0 inline, 0 general)
src/command.cpp
Show inline comments
 
@@ -280,8 +280,8 @@ static const Command _command_proc_table
 
	DEF_CMD(CmdSellShareInCompany,                             0, CMDT_MONEY_MANAGEMENT      ), // CMD_SELL_SHARE_IN_COMPANY
 
	DEF_CMD(CmdBuyCompany,                                     0, CMDT_MONEY_MANAGEMENT      ), // CMD_BUY_COMANY
 

	
 
	DEF_CMD(CmdFoundTown,                            CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_FOUND_TOWN; founding random town can fail only in exec run
 
	DEF_CMD(CmdRenameTown,                            CMD_SERVER, CMDT_OTHER_MANAGEMENT      ), // CMD_RENAME_TOWN
 
	DEF_CMD(CmdFoundTown,                CMD_DEITY | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_FOUND_TOWN; founding random town can fail only in exec run
 
	DEF_CMD(CmdRenameTown,                CMD_DEITY | CMD_SERVER, CMDT_OTHER_MANAGEMENT      ), // CMD_RENAME_TOWN
 
	DEF_CMD(CmdDoTownAction,                                   0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_DO_TOWN_ACTION
 
	DEF_CMD(CmdTownCargoGoal,                          CMD_DEITY, CMDT_OTHER_MANAGEMENT      ), // CMD_TOWN_CARGO_GOAL
 
	DEF_CMD(CmdTownGrowthRate,                         CMD_DEITY, CMDT_OTHER_MANAGEMENT      ), // CMD_TOWN_GROWTH_RATE
src/script/api/ai/ai_town.hpp.sq
Show inline comments
 
@@ -44,6 +44,10 @@ void SQAITown_Register(Squirrel *engine)
 
	SQAITown.DefSQConst(engine, ScriptTown::ROAD_LAYOUT_2x2,              "ROAD_LAYOUT_2x2");
 
	SQAITown.DefSQConst(engine, ScriptTown::ROAD_LAYOUT_3x3,              "ROAD_LAYOUT_3x3");
 
	SQAITown.DefSQConst(engine, ScriptTown::ROAD_LAYOUT_INVALID,          "ROAD_LAYOUT_INVALID");
 
	SQAITown.DefSQConst(engine, ScriptTown::TOWN_SIZE_SMALL,              "TOWN_SIZE_SMALL");
 
	SQAITown.DefSQConst(engine, ScriptTown::TOWN_SIZE_MEDIUM,             "TOWN_SIZE_MEDIUM");
 
	SQAITown.DefSQConst(engine, ScriptTown::TOWN_SIZE_LARGE,              "TOWN_SIZE_LARGE");
 
	SQAITown.DefSQConst(engine, ScriptTown::TOWN_SIZE_INVALID,            "TOWN_SIZE_INVALID");
 

	
 
	SQAITown.DefSQStaticMethod(engine, &ScriptTown::GetTownCount,                      "GetTownCount",                      1, ".");
 
	SQAITown.DefSQStaticMethod(engine, &ScriptTown::IsValidTown,                       "IsValidTown",                       2, ".i");
 
@@ -67,6 +71,7 @@ void SQAITown_Register(Squirrel *engine)
 
	SQAITown.DefSQStaticMethod(engine, &ScriptTown::GetExclusiveRightsDuration,        "GetExclusiveRightsDuration",        2, ".i");
 
	SQAITown.DefSQStaticMethod(engine, &ScriptTown::IsActionAvailable,                 "IsActionAvailable",                 3, ".ii");
 
	SQAITown.DefSQStaticMethod(engine, &ScriptTown::PerformTownAction,                 "PerformTownAction",                 3, ".ii");
 
	SQAITown.DefSQStaticMethod(engine, &ScriptTown::FoundTown,                         "FoundTown",                         6, ".iibi.");
 
	SQAITown.DefSQStaticMethod(engine, &ScriptTown::GetRating,                         "GetRating",                         3, ".ii");
 
	SQAITown.DefSQStaticMethod(engine, &ScriptTown::GetAllowedNoise,                   "GetAllowedNoise",                   2, ".i");
 
	SQAITown.DefSQStaticMethod(engine, &ScriptTown::GetRoadLayout,                     "GetRoadLayout",                     2, ".i");
src/script/api/ai_changelog.hpp
Show inline comments
 
@@ -22,6 +22,7 @@
 
 * API additions:
 
 * \li AIStation::HasCargoRating
 
 * \li AITile::GetTerrainType
 
 * \li AITown::FoundTown
 
 *
 
 * Other changes:
 
 * \li AIStation::GetCargoRating does return -1 for cargo-station combinations that
src/script/api/game/game_town.hpp.sq
Show inline comments
 
@@ -44,10 +44,15 @@ void SQGSTown_Register(Squirrel *engine)
 
	SQGSTown.DefSQConst(engine, ScriptTown::ROAD_LAYOUT_2x2,              "ROAD_LAYOUT_2x2");
 
	SQGSTown.DefSQConst(engine, ScriptTown::ROAD_LAYOUT_3x3,              "ROAD_LAYOUT_3x3");
 
	SQGSTown.DefSQConst(engine, ScriptTown::ROAD_LAYOUT_INVALID,          "ROAD_LAYOUT_INVALID");
 
	SQGSTown.DefSQConst(engine, ScriptTown::TOWN_SIZE_SMALL,              "TOWN_SIZE_SMALL");
 
	SQGSTown.DefSQConst(engine, ScriptTown::TOWN_SIZE_MEDIUM,             "TOWN_SIZE_MEDIUM");
 
	SQGSTown.DefSQConst(engine, ScriptTown::TOWN_SIZE_LARGE,              "TOWN_SIZE_LARGE");
 
	SQGSTown.DefSQConst(engine, ScriptTown::TOWN_SIZE_INVALID,            "TOWN_SIZE_INVALID");
 

	
 
	SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetTownCount,                      "GetTownCount",                      1, ".");
 
	SQGSTown.DefSQStaticMethod(engine, &ScriptTown::IsValidTown,                       "IsValidTown",                       2, ".i");
 
	SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetName,                           "GetName",                           2, ".i");
 
	SQGSTown.DefSQStaticMethod(engine, &ScriptTown::SetName,                           "SetName",                           3, ".i.");
 
	SQGSTown.DefSQStaticMethod(engine, &ScriptTown::SetText,                           "SetText",                           3, ".i.");
 
	SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetPopulation,                     "GetPopulation",                     2, ".i");
 
	SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetHouseCount,                     "GetHouseCount",                     2, ".i");
 
@@ -71,6 +76,7 @@ void SQGSTown_Register(Squirrel *engine)
 
	SQGSTown.DefSQStaticMethod(engine, &ScriptTown::IsActionAvailable,                 "IsActionAvailable",                 3, ".ii");
 
	SQGSTown.DefSQStaticMethod(engine, &ScriptTown::PerformTownAction,                 "PerformTownAction",                 3, ".ii");
 
	SQGSTown.DefSQStaticMethod(engine, &ScriptTown::ExpandTown,                        "ExpandTown",                        3, ".ii");
 
	SQGSTown.DefSQStaticMethod(engine, &ScriptTown::FoundTown,                         "FoundTown",                         6, ".iibi.");
 
	SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetRating,                         "GetRating",                         3, ".ii");
 
	SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetAllowedNoise,                   "GetAllowedNoise",                   2, ".i");
 
	SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetRoadLayout,                     "GetRoadLayout",                     2, ".i");
src/script/api/game_changelog.hpp
Show inline comments
 
@@ -27,6 +27,8 @@
 
 * \li GSStation::HasCargoRating
 
 * \li GSStoryPage
 
 * \li GSTile::GetTerrainType
 
 * \li GSTown::FoundTown
 
 * \li GSTown::SetName
 
 *
 
 * Other changes:
 
 * \li GSGoal::New can now create up to 64000 concurrent goals. The old limit was 256 goals.
src/script/api/script_town.cpp
Show inline comments
 
@@ -14,6 +14,7 @@
 
#include "script_map.hpp"
 
#include "script_error.hpp"
 
#include "../../town.h"
 
#include "../../townname_func.h"
 
#include "../../string_func.h"
 
#include "../../strings_func.h"
 
#include "../../station_base.h"
 
@@ -38,6 +39,21 @@
 
	return GetString(STR_TOWN_NAME);
 
}
 

	
 
/* static */ bool ScriptTown::SetName(TownID town_id, Text *name)
 
{
 
	CCountedPtr<Text> counter(name);
 

	
 
	const char *text = NULL;
 
	if (name != NULL) {
 
		const char *text = name->GetDecodedText();
 
		EnforcePreconditionEncodedText(false, text);
 
		EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_TOWN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG);
 
	}
 
	EnforcePrecondition(false, IsValidTown(town_id));
 

	
 
	return ScriptObject::DoCommand(0, town_id, 0, CMD_RENAME_TOWN, text);
 
}
 

	
 
/* static */ bool ScriptTown::SetText(TownID town_id, Text *text)
 
{
 
	CCountedPtr<Text> counter(text);
 
@@ -238,6 +254,33 @@
 
	return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id, houses, CMD_EXPAND_TOWN);
 
}
 

	
 
/* static */ bool ScriptTown::FoundTown(TileIndex tile, TownSize size, bool city, RoadLayout layout, Text *name)
 
{
 
	CCountedPtr<Text> counter(name);
 

	
 
	EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY || _settings_game.economy.found_town != TF_FORBIDDEN);
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, size == TOWN_SIZE_SMALL || size == TOWN_SIZE_MEDIUM || size == TOWN_SIZE_LARGE)
 
	EnforcePrecondition(false, size != TOWN_SIZE_LARGE || ScriptObject::GetCompany() == OWNER_DEITY);
 
	if (ScriptObject::GetCompany() == OWNER_DEITY || _settings_game.economy.found_town == TF_CUSTOM_LAYOUT) {
 
		EnforcePrecondition(false, layout == ROAD_LAYOUT_ORIGINAL || layout == ROAD_LAYOUT_BETTER_ROADS || layout == ROAD_LAYOUT_2x2 || layout == ROAD_LAYOUT_3x3);
 
	} else {
 
		/* The layout parameter is ignored for AIs when custom layouts is disabled. */
 
		layout = (RoadLayout) (byte)_settings_game.economy.town_layout;
 
	}
 

	
 
	const char *text = NULL;
 
	if (name != NULL) {
 
		text = name->GetDecodedText();
 
		EnforcePreconditionEncodedText(false, text);
 
		EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_TOWN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG);
 
	}
 
	uint32 townnameparts;
 
	GenerateTownName(&townnameparts);
 

	
 
	return ScriptObject::DoCommand(tile, size | (city ? 1 << 2 : 0) | layout << 3, townnameparts, CMD_FOUND_TOWN, text);
 
}
 

	
 
/* static */ ScriptTown::TownRating ScriptTown::GetRating(TownID town_id, ScriptCompany::CompanyID company_id)
 
{
 
	if (!IsValidTown(town_id)) return TOWN_RATING_INVALID;
src/script/api/script_town.hpp
Show inline comments
 
@@ -106,6 +106,17 @@ public:
 
	};
 

	
 
	/**
 
	 * Possible town construction sizes.
 
	 */
 
	enum TownSize {
 
		TOWN_SIZE_SMALL   = ::TSZ_SMALL,  ///< Small town.
 
		TOWN_SIZE_MEDIUM  = ::TSZ_MEDIUM, ///< Medium town.
 
		TOWN_SIZE_LARGE   = ::TSZ_LARGE,  ///< Large town.
 

	
 
		TOWN_SIZE_INVALID = -1,  ///< Invalid town size.
 
	};
 

	
 
	/**
 
	 * Gets the number of towns.
 
	 * @return The number of towns.
 
	 */
 
@@ -127,6 +138,16 @@ public:
 
	static char *GetName(TownID town_id);
 

	
 
	/**
 
	 * Rename a town.
 
	 * @param town_id The town to rename
 
	 * @param name The new name of the town. If NULL or an empty string is passed, the town name will be reset to the default name.
 
	 * @pre IsValidTown(town_id).
 
	 * @return True if the action succeeded.
 
	 * @api -ai
 
	 */
 
	static bool SetName(TownID town_id, Text *name);
 

	
 
	/**
 
	 * Set the custom text of a town, shown in the GUI.
 
	 * @param town_id The town to set the custom text of.
 
	 * @param text The text to set it to (can be either a raw string, or a ScriptText object).
 
@@ -356,6 +377,25 @@ public:
 
	static bool ExpandTown(TownID town_id, int houses);
 

	
 
	/**
 
	 * Found a new town.
 
	 * @param tile The location of the new town.
 
	 * @param size The town size of the new town.
 
	 * @param city True if the new town should be a city.
 
	 * @param layout The town layout of the new town.
 
	 * @param name The name of the new town. Pass NULL to use a random town name.
 
	 * @game @pre no company mode in scope || ScriptSettings.GetValue("economy.found_town") != 0.
 
	 * @ai @pre ScriptSettings.GetValue("economy.found_town") != 0.
 
	 * @game @pre no company mode in scope || size != TOWN_SIZE_LARGE.
 
	 * @ai @pre size != TOWN_SIZE_LARGE.
 
	 * @pre size != TOWN_SIZE_INVALID.
 
	 * @pre layout != ROAD_LAYOUT_INVALID.
 
	 * @return True if the action succeeded.
 
	 * @game @note Companies are restricted by the advanced setting that controls if funding towns is allowed or not. If custom road layout is forbidden and there is a company mode in scope, the layout parameter will be ignored.
 
	 * @ai @note AIs are restricted by the advanced setting that controls if funding towns is allowed or not. If custom road layout is forbidden, the layout parameter will be ignored.
 
	 */
 
	static bool FoundTown(TileIndex tile, TownSize size, bool city, RoadLayout layout, Text *name);
 

	
 
	/**
 
	 * Get the rating of a company within a town.
 
	 * @param town_id The town to get the rating for.
 
	 * @param company_id The company to get the rating for.
src/script/api/template/template_town.hpp.sq
Show inline comments
 
@@ -19,6 +19,8 @@ namespace SQConvert {
 
	template <> inline int Return<ScriptTown::TownRating>(HSQUIRRELVM vm, ScriptTown::TownRating res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> inline ScriptTown::RoadLayout GetParam(ForceType<ScriptTown::RoadLayout>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptTown::RoadLayout)tmp; }
 
	template <> inline int Return<ScriptTown::RoadLayout>(HSQUIRRELVM vm, ScriptTown::RoadLayout res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> inline ScriptTown::TownSize GetParam(ForceType<ScriptTown::TownSize>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptTown::TownSize)tmp; }
 
	template <> inline int Return<ScriptTown::TownSize>(HSQUIRRELVM vm, ScriptTown::TownSize res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow ScriptTown to be used as Squirrel parameter */
 
	template <> inline ScriptTown *GetParam(ForceType<ScriptTown *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (ScriptTown *)instance; }
src/town_cmd.cpp
Show inline comments
 
@@ -1621,14 +1621,17 @@ CommandCost CmdFoundTown(TileIndex tile,
 
	if (size >= TSZ_END) return CMD_ERROR;
 
	if (layout >= NUM_TLS) return CMD_ERROR;
 

	
 
	/* Some things are allowed only in the scenario editor */
 
	if (_game_mode != GM_EDITOR) {
 
	/* Some things are allowed only in the scenario editor and for game scripts. */
 
	if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) {
 
		if (_settings_game.economy.found_town == TF_FORBIDDEN) return CMD_ERROR;
 
		if (size == TSZ_LARGE) return CMD_ERROR;
 
		if (random) return CMD_ERROR;
 
		if (_settings_game.economy.found_town != TF_CUSTOM_LAYOUT && layout != _settings_game.economy.town_layout) {
 
			return CMD_ERROR;
 
		}
 
	} else if (_current_company == OWNER_DEITY && random) {
 
		/* Random parameter is not allowed for Game Scripts. */
 
		return CMD_ERROR;
 
	}
 

	
 
	if (StrEmpty(text)) {
0 comments (0 inline, 0 general)