mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-12 10:30:28 +00:00
(svn r25785) -Feature: [Script] Allow AIs and GS to found towns. Allow GS to rename towns
This commit is contained in:
parent
953aa839b9
commit
67ab3108d6
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -105,6 +105,17 @@ public:
|
||||
ROAD_LAYOUT_INVALID = -1, ///< The layout for invalid towns.
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -126,6 +137,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.
|
||||
@ -355,6 +376,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.
|
||||
|
@ -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; }
|
||||
|
@ -1621,14 +1621,17 @@ CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user