Update to 14.0-beta1
This commit is contained in:
@@ -9,6 +9,8 @@ add_files(
|
||||
script_config.cpp
|
||||
script_config.hpp
|
||||
script_fatalerror.hpp
|
||||
script_gui.h
|
||||
script_gui.cpp
|
||||
script_info.cpp
|
||||
script_info.hpp
|
||||
script_info_dummy.cpp
|
||||
|
||||
@@ -146,10 +146,12 @@ add_files(
|
||||
script_accounting.hpp
|
||||
script_admin.hpp
|
||||
script_airport.hpp
|
||||
script_asyncmode.hpp
|
||||
script_base.hpp
|
||||
script_basestation.hpp
|
||||
script_bridge.hpp
|
||||
script_bridgelist.hpp
|
||||
script_timemode.hpp
|
||||
script_cargo.hpp
|
||||
script_cargolist.hpp
|
||||
script_cargomonitor.hpp
|
||||
@@ -180,6 +182,7 @@ add_files(
|
||||
script_league.hpp
|
||||
script_list.hpp
|
||||
script_log.hpp
|
||||
script_log_types.hpp
|
||||
script_map.hpp
|
||||
script_marine.hpp
|
||||
script_newgrf.hpp
|
||||
@@ -218,10 +221,12 @@ add_files(
|
||||
script_accounting.cpp
|
||||
script_admin.cpp
|
||||
script_airport.cpp
|
||||
script_asyncmode.cpp
|
||||
script_base.cpp
|
||||
script_basestation.cpp
|
||||
script_bridge.cpp
|
||||
script_bridgelist.cpp
|
||||
script_timemode.cpp
|
||||
script_cargo.cpp
|
||||
script_cargolist.cpp
|
||||
script_cargomonitor.cpp
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
|
||||
#include "../script_controller.hpp"
|
||||
|
||||
template <> const char *GetClassName<ScriptController, ST_AI>() { return "AIController"; }
|
||||
template <> const char *GetClassName<ScriptController, ScriptType::AI>() { return "AIController"; }
|
||||
|
||||
void SQAIController_Register(Squirrel *engine)
|
||||
{
|
||||
DefSQClass<ScriptController, ST_AI> SQAIController("AIController");
|
||||
DefSQClass<ScriptController, ScriptType::AI> SQAIController("AIController");
|
||||
SQAIController.PreRegister(engine);
|
||||
|
||||
SQAIController.DefSQStaticMethod(engine, &ScriptController::GetTick, "GetTick", 1, ".");
|
||||
|
||||
@@ -13,6 +13,28 @@
|
||||
* functions may still be available if you return an older API version
|
||||
* in GetAPIVersion() in info.nut.
|
||||
*
|
||||
* \b 14.0
|
||||
*
|
||||
* This version is not yet released. The following changes are not set in stone yet.
|
||||
*
|
||||
* API additions:
|
||||
* \li AITimeMode
|
||||
* \li AITown::ROAD_LAYOUT_RANDOM
|
||||
* \li AIVehicle::IsPrimaryVehicle
|
||||
*
|
||||
* API removals:
|
||||
* \li AIError::ERR_PRECONDITION_TOO_MANY_PARAMETERS, that error is never returned anymore.
|
||||
* \li AIInfo::CONFIG_RANDOM, no longer used.
|
||||
*
|
||||
* Other changes:
|
||||
* \li AIGroupList accepts an optional filter function
|
||||
* \li AIIndustryList accepts an optional filter function
|
||||
* \li AISignList accepts an optional filter function
|
||||
* \li AISubsidyList accepts an optional filter function
|
||||
* \li AITownList accepts an optional filter function
|
||||
* \li AIVehicleList accepts an optional filter function
|
||||
* \li AIInfo::AddSettings easy_value / medium_value / hard_value are replaced with default_value
|
||||
*
|
||||
* \b 13.0
|
||||
*
|
||||
* API additions:
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
|
||||
#include "../script_controller.hpp"
|
||||
|
||||
template <> const char *GetClassName<ScriptController, ST_GS>() { return "GSController"; }
|
||||
template <> const char *GetClassName<ScriptController, ScriptType::GS>() { return "GSController"; }
|
||||
|
||||
void SQGSController_Register(Squirrel *engine)
|
||||
{
|
||||
DefSQClass<ScriptController, ST_GS> SQGSController("GSController");
|
||||
DefSQClass<ScriptController, ScriptType::GS> SQGSController("GSController");
|
||||
SQGSController.PreRegister(engine);
|
||||
|
||||
SQGSController.DefSQStaticMethod(engine, &ScriptController::GetTick, "GetTick", 1, ".");
|
||||
|
||||
@@ -13,6 +13,94 @@
|
||||
* functions may still be available if you return an older API version
|
||||
* in GetAPIVersion() in info.nut.
|
||||
*
|
||||
* \b 14.0
|
||||
*
|
||||
* This version is not yet released. The following changes are not set in stone yet.
|
||||
*
|
||||
* API additions:
|
||||
* \li GSIndustry::GetConstructionDate
|
||||
* \li GSAsyncMode
|
||||
* \li GSCompanyMode::IsValid
|
||||
* \li GSCompanyMode::IsDeity
|
||||
* \li GSTimeMode
|
||||
* \li GSTown::ROAD_LAYOUT_RANDOM
|
||||
* \li GSVehicle::IsPrimaryVehicle
|
||||
* \li GSOrder::SetOrderJumpTo
|
||||
* \li GSOrder::SetOrderCondition
|
||||
* \li GSOrder::SetOrderCompareFunction
|
||||
* \li GSOrder::SetOrderCompareValue
|
||||
* \li GSOrder::SetStopLocation
|
||||
* \li GSOrder::SetOrderRefit
|
||||
* \li GSOrder::AppendOrder
|
||||
* \li GSOrder::AppendConditionalOrder
|
||||
* \li GSOrder::InsertOrder
|
||||
* \li GSOrder::InsertConditionalOrder
|
||||
* \li GSOrder::RemoveOrder
|
||||
* \li GSOrder::SetOrderFlags
|
||||
* \li GSOrder::MoveOrder
|
||||
* \li GSOrder::SkipToOrder
|
||||
* \li GSOrder::CopyOrders
|
||||
* \li GSOrder::ShareOrders
|
||||
* \li GSOrder::UnshareOrders
|
||||
* \li GSCompany::IsMine
|
||||
* \li GSCompany::SetPresidentGender
|
||||
* \li GSCompany::SetAutoRenewStatus
|
||||
* \li GSCompany::SetAutoRenewMonths
|
||||
* \li GSCompany::SetAutoRenewMoney
|
||||
* \li GSCompany::SetMaxLoanAmountForCompany
|
||||
* \li GSCompany::ResetMaxLoanAmountForCompany
|
||||
* \li GSGameSettings::IsDisabledVehicleType
|
||||
* \li GSGroup::GroupID
|
||||
* \li GSGroup::IsValidGroup
|
||||
* \li GSGroup::CreateGroup
|
||||
* \li GSGroup::DeleteGroup
|
||||
* \li GSGroup::GetVehicleType
|
||||
* \li GSGroup::SetName
|
||||
* \li GSGroup::GetName
|
||||
* \li GSGroup::SetParent
|
||||
* \li GSGroup::GetParent
|
||||
* \li GSGroup::EnableAutoReplaceProtection
|
||||
* \li GSGroup::GetAutoReplaceProtection
|
||||
* \li GSGroup::GetNumEngines
|
||||
* \li GSGroup::GetNumVehicles
|
||||
* \li GSGroup::MoveVehicle
|
||||
* \li GSGroup::EnableWagonRemoval
|
||||
* \li GSGroup::HasWagonRemoval
|
||||
* \li GSGroup::SetAutoReplace
|
||||
* \li GSGroup::GetEngineReplacement
|
||||
* \li GSGroup::StopAutoReplace
|
||||
* \li GSGroup::GetProfitThisYear
|
||||
* \li GSGroup::GetProfitLastYear
|
||||
* \li GSGroup::GetCurrentUsage
|
||||
* \li GSGroup::SetPrimaryColour
|
||||
* \li GSGroup::SetSecondaryColour
|
||||
* \li GSGroup::GetPrimaryColour
|
||||
* \li GSGroup::GetSecondaryColour
|
||||
* \li GSGroupList
|
||||
* \li GSVehicleList_Group
|
||||
* \li GSVehicleList_DefaultGroup
|
||||
* \li GSGoal::IsValidGoalDestination
|
||||
* \li GSGoal::SetDestination
|
||||
* \li GSIndustry::GetProductionLevel
|
||||
* \li GSIndustry::SetProductionLevel
|
||||
* \li GSStoryPage::IsValidStoryPageElementType
|
||||
* \li GSStoryPage::IsValidStoryPageButtonColour
|
||||
* \li GSStoryPage::IsValidStoryPageButtonFlags
|
||||
* \li GSStoryPage::IsValidStoryPageButtonCursor
|
||||
*
|
||||
* API removals:
|
||||
* \li GSError::ERR_PRECONDITION_TOO_MANY_PARAMETERS, that error is never returned anymore.
|
||||
* \li AIInfo::CONFIG_RANDOM, no longer used.
|
||||
*
|
||||
* Other changes:
|
||||
* \li GSGroupList accepts an optional filter function
|
||||
* \li GSIndustryList accepts an optional filter function
|
||||
* \li GSSignList accepts an optional filter function
|
||||
* \li GSSubsidyList accepts an optional filter function
|
||||
* \li GSTownList accepts an optional filter function
|
||||
* \li GSVehicleList accepts an optional filter function
|
||||
* \li GSInfo::AddSettings easy_value / medium_value / hard_value are replaced with default_value
|
||||
*
|
||||
* \b 13.0
|
||||
*
|
||||
* API additions:
|
||||
|
||||
@@ -13,12 +13,24 @@
|
||||
#include "../../network/network_admin.h"
|
||||
#include "../script_instance.hpp"
|
||||
#include "../../string_func.h"
|
||||
#include "../../3rdparty/nlohmann/json.hpp"
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
/* static */ bool ScriptAdmin::MakeJSON(HSQUIRRELVM vm, SQInteger index, int max_depth, std::string &data)
|
||||
/**
|
||||
* Convert a Squirrel structure into a JSON object.
|
||||
*
|
||||
* This function is not "static", so it can be tested in unittests.
|
||||
*
|
||||
* @param json The resulting JSON object.
|
||||
* @param vm The VM to operate on.
|
||||
* @param index The index we are currently working for.
|
||||
* @param depth The current depth in the squirrel struct.
|
||||
* @return True iff the conversion was successful.
|
||||
*/
|
||||
bool ScriptAdminMakeJSON(nlohmann::json &json, HSQUIRRELVM vm, SQInteger index, int depth = 0)
|
||||
{
|
||||
if (max_depth == 0) {
|
||||
if (depth == SQUIRREL_MAX_DEPTH) {
|
||||
ScriptLog::Error("Send parameters can only be nested to 25 deep. No data sent."); // SQUIRREL_MAX_DEPTH = 25
|
||||
return false;
|
||||
}
|
||||
@@ -28,9 +40,7 @@
|
||||
SQInteger res;
|
||||
sq_getinteger(vm, index, &res);
|
||||
|
||||
char buf[10];
|
||||
seprintf(buf, lastof(buf), "%d", (int32)res);
|
||||
data = buf;
|
||||
json = res;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -38,63 +48,52 @@
|
||||
const SQChar *buf;
|
||||
sq_getstring(vm, index, &buf);
|
||||
|
||||
size_t len = strlen(buf) + 1;
|
||||
if (len >= 255) {
|
||||
ScriptLog::Error("Maximum string length is 254 chars. No data sent.");
|
||||
return false;
|
||||
}
|
||||
|
||||
data = std::string("\"") + buf + "\"";
|
||||
json = std::string(buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
case OT_ARRAY: {
|
||||
data = "[ ";
|
||||
json = nlohmann::json::array();
|
||||
|
||||
bool first = true;
|
||||
sq_pushnull(vm);
|
||||
while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
|
||||
if (!first) data += ", ";
|
||||
if (first) first = false;
|
||||
nlohmann::json tmp;
|
||||
|
||||
std::string tmp;
|
||||
|
||||
bool res = MakeJSON(vm, -1, max_depth - 1, tmp);
|
||||
bool res = ScriptAdminMakeJSON(tmp, vm, -1, depth + 1);
|
||||
sq_pop(vm, 2);
|
||||
if (!res) {
|
||||
sq_pop(vm, 1);
|
||||
return false;
|
||||
}
|
||||
data += tmp;
|
||||
|
||||
json.push_back(tmp);
|
||||
}
|
||||
sq_pop(vm, 1);
|
||||
data += " ]";
|
||||
return true;
|
||||
}
|
||||
|
||||
case OT_TABLE: {
|
||||
data = "{ ";
|
||||
json = nlohmann::json::object();
|
||||
|
||||
bool first = true;
|
||||
sq_pushnull(vm);
|
||||
while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
|
||||
if (!first) data += ", ";
|
||||
if (first) first = false;
|
||||
/* Squirrel ensure the key is a string. */
|
||||
assert(sq_gettype(vm, -2) == OT_STRING);
|
||||
const SQChar *buf;
|
||||
sq_getstring(vm, -2, &buf);
|
||||
std::string key = std::string(buf);
|
||||
|
||||
std::string key;
|
||||
std::string value;
|
||||
|
||||
/* Store the key + value */
|
||||
bool res = MakeJSON(vm, -2, max_depth - 1, key) && MakeJSON(vm, -1, max_depth - 1, value);
|
||||
nlohmann::json value;
|
||||
bool res = ScriptAdminMakeJSON(value, vm, -1, depth + 1);
|
||||
sq_pop(vm, 2);
|
||||
if (!res) {
|
||||
sq_pop(vm, 1);
|
||||
return false;
|
||||
}
|
||||
data += key + ": " + value;
|
||||
|
||||
json[key] = value;
|
||||
}
|
||||
sq_pop(vm, 1);
|
||||
data += " }";
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -102,17 +101,12 @@
|
||||
SQBool res;
|
||||
sq_getbool(vm, index, &res);
|
||||
|
||||
if (res) {
|
||||
data = "true";
|
||||
return true;
|
||||
}
|
||||
|
||||
data = "false";
|
||||
json = res ? true : false;
|
||||
return true;
|
||||
}
|
||||
|
||||
case OT_NULL: {
|
||||
data = "null";
|
||||
json = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -130,16 +124,13 @@
|
||||
return sq_throwerror(vm, "ScriptAdmin::Send requires a table as first parameter. No data sent.");
|
||||
}
|
||||
|
||||
std::string json;
|
||||
ScriptAdmin::MakeJSON(vm, -1, SQUIRREL_MAX_DEPTH, json);
|
||||
|
||||
if (json.length() > NETWORK_GAMESCRIPT_JSON_LENGTH) {
|
||||
ScriptLog::Error("You are trying to send a table that is too large to the AdminPort. No data sent.");
|
||||
nlohmann::json json;
|
||||
if (!ScriptAdminMakeJSON(json, vm, -1)) {
|
||||
sq_pushinteger(vm, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
NetworkAdminGameScript(json);
|
||||
NetworkAdminGameScript(json.dump());
|
||||
|
||||
sq_pushinteger(vm, 1);
|
||||
return 1;
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#ifndef SCRIPT_ADMIN_HPP
|
||||
#define SCRIPT_ADMIN_HPP
|
||||
|
||||
#include <string>
|
||||
#include "script_object.hpp"
|
||||
|
||||
/**
|
||||
@@ -36,16 +35,6 @@ public:
|
||||
*/
|
||||
static bool Send(void *table);
|
||||
#endif /* DOXYGEN_API */
|
||||
|
||||
private:
|
||||
/**
|
||||
* Convert a Squirrel structure into a JSON string.
|
||||
* @param vm The VM to operate on.
|
||||
* @param index The index we are currently working for.
|
||||
* @param max_depth The maximal depth to follow the squirrel struct.
|
||||
* @param data The resulting json string.
|
||||
*/
|
||||
static bool MakeJSON(HSQUIRRELVM vm, SQInteger index, int max_depth, std::string &data);
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_ADMIN_HPP */
|
||||
|
||||
@@ -49,21 +49,21 @@
|
||||
return ::IsTileType(tile, MP_STATION) && ::IsAirport(tile);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptAirport::GetAirportWidth(AirportType type)
|
||||
/* static */ SQInteger ScriptAirport::GetAirportWidth(AirportType type)
|
||||
{
|
||||
if (!IsAirportInformationAvailable(type)) return -1;
|
||||
|
||||
return ::AirportSpec::Get(type)->size_x;
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptAirport::GetAirportHeight(AirportType type)
|
||||
/* static */ SQInteger ScriptAirport::GetAirportHeight(AirportType type)
|
||||
{
|
||||
if (!IsAirportInformationAvailable(type)) return -1;
|
||||
|
||||
return ::AirportSpec::Get(type)->size_y;
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptAirport::GetAirportCoverageRadius(AirportType type)
|
||||
/* static */ SQInteger ScriptAirport::GetAirportCoverageRadius(AirportType type)
|
||||
{
|
||||
if (!IsAirportInformationAvailable(type)) return -1;
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
|
||||
/* static */ bool ScriptAirport::BuildAirport(TileIndex tile, AirportType type, StationID station_id)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, IsValidAirportType(type));
|
||||
EnforcePrecondition(false, station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id));
|
||||
@@ -82,20 +82,21 @@
|
||||
|
||||
/* static */ bool ScriptAirport::RemoveAirport(TileIndex tile)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile))
|
||||
EnforcePrecondition(false, IsAirportTile(tile) || IsHangarTile(tile));
|
||||
|
||||
return ScriptObject::Command<CMD_LANDSCAPE_CLEAR>::Do(tile);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptAirport::GetNumHangars(TileIndex tile)
|
||||
/* static */ SQInteger ScriptAirport::GetNumHangars(TileIndex tile)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(-1);
|
||||
if (!::IsValidTile(tile)) return -1;
|
||||
if (!::IsTileType(tile, MP_STATION)) return -1;
|
||||
|
||||
const Station *st = ::Station::GetByTile(tile);
|
||||
if (st->owner != ScriptObject::GetCompany() && ScriptObject::GetCompany() != OWNER_DEITY) return -1;
|
||||
if (st->owner != ScriptObject::GetCompany() && ScriptCompanyMode::IsValid()) return -1;
|
||||
if ((st->facilities & FACIL_AIRPORT) == 0) return -1;
|
||||
|
||||
return st->airport.GetNumHangars();
|
||||
@@ -103,12 +104,13 @@
|
||||
|
||||
/* static */ TileIndex ScriptAirport::GetHangarOfAirport(TileIndex tile)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(INVALID_TILE);
|
||||
if (!::IsValidTile(tile)) return INVALID_TILE;
|
||||
if (!::IsTileType(tile, MP_STATION)) return INVALID_TILE;
|
||||
if (GetNumHangars(tile) < 1) return INVALID_TILE;
|
||||
|
||||
const Station *st = ::Station::GetByTile(tile);
|
||||
if (st->owner != ScriptObject::GetCompany() && ScriptObject::GetCompany() != OWNER_DEITY) return INVALID_TILE;
|
||||
if (st->owner != ScriptObject::GetCompany() && ScriptCompanyMode::IsValid()) return INVALID_TILE;
|
||||
if ((st->facilities & FACIL_AIRPORT) == 0) return INVALID_TILE;
|
||||
|
||||
return st->airport.GetHangarTile(0);
|
||||
@@ -126,11 +128,8 @@
|
||||
}
|
||||
|
||||
|
||||
/* static */ int ScriptAirport::GetNoiseLevelIncrease(TileIndex tile, AirportType type)
|
||||
/* static */ SQInteger ScriptAirport::GetNoiseLevelIncrease(TileIndex tile, AirportType type)
|
||||
{
|
||||
extern Town *AirportGetNearestTown(const AirportSpec *as, const TileIterator &it, uint &mindist);
|
||||
extern uint8 GetAirportNoiseLevelForDistance(const AirportSpec *as, uint distance);
|
||||
|
||||
if (!::IsValidTile(tile)) return -1;
|
||||
if (!IsAirportInformationAvailable(type)) return -1;
|
||||
|
||||
@@ -138,9 +137,8 @@
|
||||
if (!as->IsWithinMapBounds(0, tile)) return -1;
|
||||
|
||||
if (_settings_game.economy.station_noise_level) {
|
||||
AirportTileTableIterator it(as->table[0], tile);
|
||||
uint dist;
|
||||
AirportGetNearestTown(as, it, dist);
|
||||
AirportGetNearestTown(as, as->rotation[0], tile, AirportTileTableIterator(as->table[0], tile), dist);
|
||||
return GetAirportNoiseLevelForDistance(as, dist);
|
||||
}
|
||||
|
||||
@@ -149,8 +147,6 @@
|
||||
|
||||
/* static */ TownID ScriptAirport::GetNearestTown(TileIndex tile, AirportType type)
|
||||
{
|
||||
extern Town *AirportGetNearestTown(const AirportSpec *as, const TileIterator &it, uint &mindist);
|
||||
|
||||
if (!::IsValidTile(tile)) return INVALID_TOWN;
|
||||
if (!IsAirportInformationAvailable(type)) return INVALID_TOWN;
|
||||
|
||||
@@ -158,12 +154,12 @@
|
||||
if (!as->IsWithinMapBounds(0, tile)) return INVALID_TOWN;
|
||||
|
||||
uint dist;
|
||||
return AirportGetNearestTown(as, AirportTileTableIterator(as->table[0], tile), dist)->index;
|
||||
return AirportGetNearestTown(as, as->rotation[0], tile, AirportTileTableIterator(as->table[0], tile), dist)->index;
|
||||
}
|
||||
|
||||
/* static */ uint16 ScriptAirport::GetMaintenanceCostFactor(AirportType type)
|
||||
/* static */ SQInteger ScriptAirport::GetMaintenanceCostFactor(AirportType type)
|
||||
{
|
||||
if (!IsAirportInformationAvailable(type)) return INVALID_TOWN;
|
||||
if (!IsAirportInformationAvailable(type)) return 0;
|
||||
|
||||
return AirportSpec::Get(type)->maintenance_cost;
|
||||
}
|
||||
@@ -172,5 +168,5 @@
|
||||
{
|
||||
if (!IsAirportInformationAvailable(type)) return -1;
|
||||
|
||||
return (int64)GetMaintenanceCostFactor(type) * _price[PR_INFRASTRUCTURE_AIRPORT] >> 3;
|
||||
return (int64_t)GetMaintenanceCostFactor(type) * _price[PR_INFRASTRUCTURE_AIRPORT] >> 3;
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ public:
|
||||
* @pre IsAirportInformationAvailable(type).
|
||||
* @return The width in tiles.
|
||||
*/
|
||||
static int32 GetAirportWidth(AirportType type);
|
||||
static SQInteger GetAirportWidth(AirportType type);
|
||||
|
||||
/**
|
||||
* Get the height of this type of airport.
|
||||
@@ -104,7 +104,7 @@ public:
|
||||
* @pre IsAirportInformationAvailable(type).
|
||||
* @return The height in tiles.
|
||||
*/
|
||||
static int32 GetAirportHeight(AirportType type);
|
||||
static SQInteger GetAirportHeight(AirportType type);
|
||||
|
||||
/**
|
||||
* Get the coverage radius of this type of airport.
|
||||
@@ -112,7 +112,7 @@ public:
|
||||
* @pre IsAirportInformationAvailable(type).
|
||||
* @return The radius in tiles.
|
||||
*/
|
||||
static int32 GetAirportCoverageRadius(AirportType type);
|
||||
static SQInteger GetAirportCoverageRadius(AirportType type);
|
||||
|
||||
/**
|
||||
* Get the number of hangars of the airport.
|
||||
@@ -120,7 +120,7 @@ public:
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @return The number of hangars of the airport.
|
||||
*/
|
||||
static int32 GetNumHangars(TileIndex tile);
|
||||
static SQInteger GetNumHangars(TileIndex tile);
|
||||
|
||||
/**
|
||||
* Get the first hangar tile of the airport.
|
||||
@@ -142,7 +142,7 @@ public:
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @pre AirportAvailable(type).
|
||||
* @pre station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
* @exception ScriptError::ERR_FLAT_LAND_REQUIRED
|
||||
* @exception ScriptError::ERR_LOCAL_AUTHORITY_REFUSES
|
||||
@@ -156,7 +156,7 @@ public:
|
||||
* Removes an airport.
|
||||
* @param tile Any tile of the airport.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @return Whether the airport has been/can be removed or not.
|
||||
*/
|
||||
@@ -180,7 +180,7 @@ public:
|
||||
* @return The amount of noise added to the nearest town.
|
||||
* @note The noise will be added to the town with TownID GetNearestTown(tile, type).
|
||||
*/
|
||||
static int GetNoiseLevelIncrease(TileIndex tile, AirportType type);
|
||||
static SQInteger GetNoiseLevelIncrease(TileIndex tile, AirportType type);
|
||||
|
||||
/**
|
||||
* Get the TownID of the town whose local authority will influence
|
||||
@@ -198,7 +198,7 @@ public:
|
||||
* @pre IsAirportInformationAvailable(type)
|
||||
* @return Maintenance cost factor of the airport type.
|
||||
*/
|
||||
static uint16 GetMaintenanceCostFactor(AirportType type);
|
||||
static SQInteger GetMaintenanceCostFactor(AirportType type);
|
||||
|
||||
/**
|
||||
* Get the monthly maintenance cost of an airport type.
|
||||
|
||||
61
src/script/api/script_asyncmode.cpp
Normal file
61
src/script/api/script_asyncmode.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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 script_asyncmode.cpp Implementation of ScriptAsyncMode. */
|
||||
|
||||
#include "../../stdafx.h"
|
||||
#include "script_asyncmode.hpp"
|
||||
#include "../script_instance.hpp"
|
||||
#include "../script_fatalerror.hpp"
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
bool ScriptAsyncMode::AsyncModeProc()
|
||||
{
|
||||
/* In async mode we only return 'true', telling the DoCommand it
|
||||
* should stop run the command in asynchronous/fire-and-forget mode. */
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScriptAsyncMode::NonAsyncModeProc()
|
||||
{
|
||||
/* In non-async mode we only return 'false', normal operation. */
|
||||
return false;
|
||||
}
|
||||
|
||||
ScriptAsyncMode::ScriptAsyncMode(HSQUIRRELVM vm)
|
||||
{
|
||||
int nparam = sq_gettop(vm) - 1;
|
||||
if (nparam < 1) {
|
||||
throw sq_throwerror(vm, "You need to pass a boolean to the constructor");
|
||||
}
|
||||
|
||||
SQBool sqasync;
|
||||
if (SQ_FAILED(sq_getbool(vm, 2, &sqasync))) {
|
||||
throw sq_throwerror(vm, "Argument must be a boolean");
|
||||
}
|
||||
|
||||
this->last_mode = this->GetDoCommandAsyncMode();
|
||||
this->last_instance = this->GetDoCommandAsyncModeInstance();
|
||||
|
||||
this->SetDoCommandAsyncMode(sqasync ? &ScriptAsyncMode::AsyncModeProc : &ScriptAsyncMode::NonAsyncModeProc, this);
|
||||
}
|
||||
|
||||
void ScriptAsyncMode::FinalRelease()
|
||||
{
|
||||
if (this->GetDoCommandAsyncModeInstance() != this) {
|
||||
/* Ignore this error if the script is not alive. */
|
||||
if (ScriptObject::GetActiveInstance()->IsAlive()) {
|
||||
throw Script_FatalError("Asyncmode object was removed while it was not the latest *Mode object created.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScriptAsyncMode::~ScriptAsyncMode()
|
||||
{
|
||||
this->SetDoCommandAsyncMode(this->last_mode, this->last_instance);
|
||||
}
|
||||
63
src/script/api/script_asyncmode.hpp
Normal file
63
src/script/api/script_asyncmode.hpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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 script_asyncmode.hpp Switch the script instance to Async Mode. */
|
||||
|
||||
#ifndef SCRIPT_ASYNCMODE_HPP
|
||||
#define SCRIPT_ASYNCMODE_HPP
|
||||
|
||||
#include "script_object.hpp"
|
||||
|
||||
/**
|
||||
* Class to switch current mode to Async Mode.
|
||||
* If you create an instance of this class, the mode will be switched to
|
||||
* either Asynchronous or Non-Asynchronous mode.
|
||||
* The original mode is stored and recovered from when ever the instance is destroyed.
|
||||
* In Asynchronous mode all the commands you execute are queued for later execution. The
|
||||
* system checks if it would be able to execute your requests, and returns what
|
||||
* the cost would be. The actual cost and whether the command succeeded when the command
|
||||
* is eventually executed may differ from what was reported to the script.
|
||||
* @api game
|
||||
*/
|
||||
class ScriptAsyncMode : public ScriptObject {
|
||||
private:
|
||||
ScriptAsyncModeProc *last_mode; ///< The previous mode we were in.
|
||||
ScriptObject *last_instance; ///< The previous instance of the mode.
|
||||
|
||||
protected:
|
||||
static bool AsyncModeProc();
|
||||
static bool NonAsyncModeProc();
|
||||
|
||||
public:
|
||||
#ifndef DOXYGEN_API
|
||||
/**
|
||||
* The constructor wrapper from Squirrel.
|
||||
*/
|
||||
ScriptAsyncMode(HSQUIRRELVM vm);
|
||||
#else
|
||||
/**
|
||||
* Creating instance of this class switches the build mode to Asynchronous or Non-Asynchronous (normal).
|
||||
* @note When the instance is destroyed, it restores the mode that was
|
||||
* current when the instance was created!
|
||||
* @param asynchronous Whether the new mode should be Asynchronous, if true, or Non-Asynchronous, if false.
|
||||
*/
|
||||
ScriptAsyncMode(bool asynchronous);
|
||||
#endif /* DOXYGEN_API */
|
||||
|
||||
/**
|
||||
* Destroying this instance resets the asynchronous mode to the mode it was
|
||||
* in when the instance was created.
|
||||
*/
|
||||
~ScriptAsyncMode();
|
||||
|
||||
/**
|
||||
* @api -all
|
||||
*/
|
||||
void FinalRelease() override;
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_ASYNCMODE_HPP */
|
||||
@@ -10,44 +10,39 @@
|
||||
#include "../../stdafx.h"
|
||||
#include "script_base.hpp"
|
||||
#include "script_error.hpp"
|
||||
#include "../../network/network.h"
|
||||
#include "../../core/random_func.hpp"
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
/* static */ uint32 ScriptBase::Rand()
|
||||
/* static */ SQInteger ScriptBase::Rand()
|
||||
{
|
||||
/* 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();
|
||||
return ::Random();
|
||||
return ScriptObject::GetRandomizer().Next();
|
||||
}
|
||||
|
||||
/* static */ uint32 ScriptBase::RandItem(int unused_param)
|
||||
/* static */ SQInteger ScriptBase::RandItem(SQInteger)
|
||||
{
|
||||
return ScriptBase::Rand();
|
||||
}
|
||||
|
||||
/* static */ uint ScriptBase::RandRange(uint max)
|
||||
/* static */ SQInteger ScriptBase::RandRange(SQInteger max)
|
||||
{
|
||||
/* 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);
|
||||
return ::RandomRange(max);
|
||||
max = Clamp<SQInteger>(max, 0, UINT32_MAX);
|
||||
return ScriptObject::GetRandomizer().Next(max);
|
||||
}
|
||||
|
||||
/* static */ uint32 ScriptBase::RandRangeItem(int unused_param, uint max)
|
||||
/* static */ SQInteger ScriptBase::RandRangeItem(SQInteger, SQInteger max)
|
||||
{
|
||||
return ScriptBase::RandRange(max);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptBase::Chance(uint out, uint max)
|
||||
/* static */ bool ScriptBase::Chance(SQInteger out, SQInteger max)
|
||||
{
|
||||
out = Clamp<SQInteger>(out, 0, UINT32_MAX);
|
||||
max = Clamp<SQInteger>(max, 0, UINT32_MAX);
|
||||
EnforcePrecondition(false, out <= max);
|
||||
return ScriptBase::RandRange(max) < out;
|
||||
}
|
||||
|
||||
/* static */ bool ScriptBase::ChanceItem(int unused_param, uint out, uint max)
|
||||
/* static */ bool ScriptBase::ChanceItem(SQInteger, SQInteger out, SQInteger max)
|
||||
{
|
||||
return ScriptBase::Chance(out, max);
|
||||
}
|
||||
|
||||
@@ -18,60 +18,63 @@
|
||||
*
|
||||
* @note The random functions are not called Random and RandomRange, because
|
||||
* RANDOM_DEBUG does some tricky stuff, which messes with those names.
|
||||
* @note In MP we cannot use Random because that will cause desyncs (scripts are
|
||||
* ran on the server only, not on all clients). This means that
|
||||
* we use InteractiveRandom in MP. Rand() takes care of this for you.
|
||||
*/
|
||||
class ScriptBase : public ScriptObject {
|
||||
public:
|
||||
/**
|
||||
* Get a random value.
|
||||
* @return A random value between 0 and MAX(uint32).
|
||||
* @return A random value between 0 and MAX(uint32_t).
|
||||
*/
|
||||
static uint32 Rand();
|
||||
static SQInteger Rand();
|
||||
|
||||
/**
|
||||
* Get a random value.
|
||||
* @param unused_param This parameter is not used, but is needed to work with lists.
|
||||
* @return A random value between 0 and MAX(uint32).
|
||||
* @return A random value between 0 and MAX(uint32_t).
|
||||
*/
|
||||
static uint32 RandItem(int unused_param);
|
||||
static SQInteger RandItem(SQInteger unused_param);
|
||||
|
||||
/**
|
||||
* Get a random value in a range.
|
||||
* @param max The first number this function will never return (the maximum it returns is max - 1).
|
||||
* The value will be clamped to 0 .. MAX(uint32_t).
|
||||
* @return A random value between 0 .. max - 1.
|
||||
*/
|
||||
static uint RandRange(uint max);
|
||||
static SQInteger RandRange(SQInteger max);
|
||||
|
||||
/**
|
||||
* Get a random value in a range.
|
||||
* @param unused_param This parameter is not used, but is needed to work with lists.
|
||||
* @param max The first number this function will never return (the maximum it returns is max - 1).
|
||||
* The value will be clamped to 0 .. MAX(uint32_t).
|
||||
* @return A random value between 0 .. max - 1.
|
||||
*/
|
||||
static uint RandRangeItem(int unused_param, uint max);
|
||||
static SQInteger RandRangeItem(SQInteger unused_param, SQInteger max);
|
||||
|
||||
/**
|
||||
* Returns approximately 'out' times true when called 'max' times.
|
||||
* After all, it is a random function.
|
||||
* @param out How many times it should return true.
|
||||
* The value will be clamped to 0 .. MAX(uint32_t).
|
||||
* @param max Out of this many times.
|
||||
* The value will be clamped to 0 .. MAX(uint32_t).
|
||||
* @pre \a out is at most equal to \a max.
|
||||
* @return True if the chance worked out.
|
||||
*/
|
||||
static bool Chance(uint out, uint max);
|
||||
static bool Chance(SQInteger out, SQInteger max);
|
||||
|
||||
/**
|
||||
* Returns approximately 'out' times true when called 'max' times.
|
||||
* After all, it is a random function.
|
||||
* @param unused_param This parameter is not used, but is needed to work with lists.
|
||||
* @param out How many times it should return true.
|
||||
* The value will be clamped to 0 .. MAX(uint32_t).
|
||||
* @param max Out of this many times.
|
||||
* The value will be clamped to 0 .. MAX(uint32_t).
|
||||
* @pre \a out is at most equal to \a max.
|
||||
* @return True if the chance worked out.
|
||||
*/
|
||||
static bool ChanceItem(int unused_param, uint out, uint max);
|
||||
static bool ChanceItem(SQInteger unused_param, SQInteger out, SQInteger max);
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_BASE_HPP */
|
||||
|
||||
@@ -15,19 +15,21 @@
|
||||
#include "../../strings_func.h"
|
||||
#include "../../station_cmd.h"
|
||||
#include "../../waypoint_cmd.h"
|
||||
#include "../../timer/timer_game_calendar.h"
|
||||
#include "table/strings.h"
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
/* static */ bool ScriptBaseStation::IsValidBaseStation(StationID station_id)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
const BaseStation *st = ::BaseStation::GetIfValid(station_id);
|
||||
return st != nullptr && (st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY || st->owner == OWNER_NONE);
|
||||
return st != nullptr && (st->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity() || st->owner == OWNER_NONE);
|
||||
}
|
||||
|
||||
/* static */ char *ScriptBaseStation::GetName(StationID station_id)
|
||||
/* static */ std::optional<std::string> ScriptBaseStation::GetName(StationID station_id)
|
||||
{
|
||||
if (!IsValidBaseStation(station_id)) return nullptr;
|
||||
if (!IsValidBaseStation(station_id)) return std::nullopt;
|
||||
|
||||
::SetDParam(0, station_id);
|
||||
return GetString(::Station::IsValidID(station_id) ? STR_STATION_NAME : STR_WAYPOINT_NAME);
|
||||
@@ -37,10 +39,10 @@
|
||||
{
|
||||
CCountedPtr<Text> counter(name);
|
||||
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidBaseStation(station_id));
|
||||
EnforcePrecondition(false, name != nullptr);
|
||||
const char *text = name->GetDecodedText();
|
||||
const std::string &text = name->GetDecodedText();
|
||||
EnforcePreconditionEncodedText(false, text);
|
||||
EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_STATION_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG);
|
||||
|
||||
@@ -62,5 +64,5 @@
|
||||
{
|
||||
if (!IsValidBaseStation(station_id)) return ScriptDate::DATE_INVALID;
|
||||
|
||||
return (ScriptDate::Date)::BaseStation::Get(station_id)->build_date;
|
||||
return (ScriptDate::Date)::BaseStation::Get(station_id)->build_date.base();
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
* @pre IsValidBaseStation(station_id).
|
||||
* @return The name of the station.
|
||||
*/
|
||||
static char *GetName(StationID station_id);
|
||||
static std::optional<std::string> GetName(StationID station_id);
|
||||
|
||||
/**
|
||||
* Set the name this basestation.
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
* @param name The new name of the station (can be either a raw string, or a ScriptText object).
|
||||
* @pre IsValidBaseStation(station_id).
|
||||
* @pre name != null && len(name) != 0.
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE
|
||||
* @return True if the name was changed.
|
||||
*/
|
||||
|
||||
@@ -13,17 +13,17 @@
|
||||
#include "../script_instance.hpp"
|
||||
#include "../../bridge_map.h"
|
||||
#include "../../strings_func.h"
|
||||
#include "../../date_func.h"
|
||||
#include "../../landscape_cmd.h"
|
||||
#include "../../road_cmd.h"
|
||||
#include "../../tunnelbridge_cmd.h"
|
||||
#include "../../timer/timer_game_calendar.h"
|
||||
#include "table/strings.h"
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
/* static */ bool ScriptBridge::IsValidBridge(BridgeID bridge_id)
|
||||
{
|
||||
return bridge_id < MAX_BRIDGES && ::GetBridgeSpec(bridge_id)->avail_year <= _cur_year;
|
||||
return bridge_id < MAX_BRIDGES && ::GetBridgeSpec(bridge_id)->avail_year <= TimerGameCalendar::year;
|
||||
}
|
||||
|
||||
/* static */ bool ScriptBridge::IsBridgeTile(TileIndex tile)
|
||||
@@ -72,18 +72,19 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
|
||||
|
||||
/* static */ bool ScriptBridge::BuildBridge(ScriptVehicle::VehicleType vehicle_type, BridgeID bridge_id, TileIndex start, TileIndex end)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
EnforcePrecondition(false, start != end);
|
||||
EnforcePrecondition(false, ::IsValidTile(start) && ::IsValidTile(end));
|
||||
EnforcePrecondition(false, TileX(start) == TileX(end) || TileY(start) == TileY(end));
|
||||
EnforcePrecondition(false, vehicle_type == ScriptVehicle::VT_ROAD || vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_WATER);
|
||||
EnforcePrecondition(false, vehicle_type != ScriptVehicle::VT_RAIL || ScriptRail::IsRailTypeAvailable(ScriptRail::GetCurrentRailType()));
|
||||
EnforcePrecondition(false, vehicle_type != ScriptVehicle::VT_ROAD || ScriptRoad::IsRoadTypeAvailable(ScriptRoad::GetCurrentRoadType()));
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY || vehicle_type == ScriptVehicle::VT_ROAD);
|
||||
EnforcePrecondition(false, ScriptCompanyMode::IsValid() || vehicle_type == ScriptVehicle::VT_ROAD);
|
||||
|
||||
switch (vehicle_type) {
|
||||
case ScriptVehicle::VT_ROAD:
|
||||
ScriptObject::SetCallbackVariable(0, start);
|
||||
ScriptObject::SetCallbackVariable(1, end);
|
||||
ScriptObject::SetCallbackVariable(0, start.base());
|
||||
ScriptObject::SetCallbackVariable(1, end.base());
|
||||
return ScriptObject::Command<CMD_BUILD_BRIDGE>::Do(&::_DoCommandReturnBuildBridge1, end, start, TRANSPORT_ROAD, bridge_id, ScriptRoad::GetCurrentRoadType());
|
||||
case ScriptVehicle::VT_RAIL:
|
||||
return ScriptObject::Command<CMD_BUILD_BRIDGE>::Do(end, start, TRANSPORT_RAIL, bridge_id, ScriptRail::GetCurrentRailType());
|
||||
@@ -95,6 +96,8 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
|
||||
|
||||
/* static */ bool ScriptBridge::_BuildBridgeRoad1()
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
|
||||
/* Build the piece of road on the 'start' side of the bridge */
|
||||
TileIndex end = ScriptObject::GetCallbackVariable(0);
|
||||
TileIndex start = ScriptObject::GetCallbackVariable(1);
|
||||
@@ -107,6 +110,8 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
|
||||
|
||||
/* static */ bool ScriptBridge::_BuildBridgeRoad2()
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
|
||||
/* Build the piece of road on the 'end' side of the bridge */
|
||||
TileIndex end = ScriptObject::GetCallbackVariable(0);
|
||||
TileIndex start = ScriptObject::GetCallbackVariable(1);
|
||||
@@ -119,45 +124,47 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
|
||||
|
||||
/* static */ bool ScriptBridge::RemoveBridge(TileIndex tile)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsBridgeTile(tile));
|
||||
return ScriptObject::Command<CMD_LANDSCAPE_CLEAR>::Do(tile);
|
||||
}
|
||||
|
||||
/* static */ char *ScriptBridge::GetName(BridgeID bridge_id, ScriptVehicle::VehicleType vehicle_type)
|
||||
/* static */ std::optional<std::string> ScriptBridge::GetName(BridgeID bridge_id, ScriptVehicle::VehicleType vehicle_type)
|
||||
{
|
||||
EnforcePrecondition(nullptr, vehicle_type == ScriptVehicle::VT_ROAD || vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_WATER);
|
||||
if (!IsValidBridge(bridge_id)) return nullptr;
|
||||
EnforcePrecondition(std::nullopt, vehicle_type == ScriptVehicle::VT_ROAD || vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_WATER);
|
||||
if (!IsValidBridge(bridge_id)) return std::nullopt;
|
||||
|
||||
return GetString(vehicle_type == ScriptVehicle::VT_WATER ? STR_LAI_BRIDGE_DESCRIPTION_AQUEDUCT : ::GetBridgeSpec(bridge_id)->transport_name[vehicle_type]);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptBridge::GetMaxSpeed(BridgeID bridge_id)
|
||||
/* static */ SQInteger ScriptBridge::GetMaxSpeed(BridgeID bridge_id)
|
||||
{
|
||||
if (!IsValidBridge(bridge_id)) return -1;
|
||||
|
||||
return ::GetBridgeSpec(bridge_id)->speed; // km-ish/h
|
||||
}
|
||||
|
||||
/* static */ Money ScriptBridge::GetPrice(BridgeID bridge_id, uint length)
|
||||
/* static */ Money ScriptBridge::GetPrice(BridgeID bridge_id, SQInteger length)
|
||||
{
|
||||
if (!IsValidBridge(bridge_id)) return -1;
|
||||
|
||||
length = Clamp<SQInteger>(length, 0, INT32_MAX);
|
||||
|
||||
return ::CalcBridgeLenCostFactor(length) * _price[PR_BUILD_BRIDGE] * ::GetBridgeSpec(bridge_id)->price >> 8;
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptBridge::GetMaxLength(BridgeID bridge_id)
|
||||
/* static */ SQInteger ScriptBridge::GetMaxLength(BridgeID bridge_id)
|
||||
{
|
||||
if (!IsValidBridge(bridge_id)) return -1;
|
||||
|
||||
return std::min(::GetBridgeSpec(bridge_id)->max_length, _settings_game.construction.max_bridge_length) + 2;
|
||||
return std::min<SQInteger>(::GetBridgeSpec(bridge_id)->max_length, _settings_game.construction.max_bridge_length) + 2;
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptBridge::GetMinLength(BridgeID bridge_id)
|
||||
/* static */ SQInteger ScriptBridge::GetMinLength(BridgeID bridge_id)
|
||||
{
|
||||
if (!IsValidBridge(bridge_id)) return -1;
|
||||
|
||||
return ::GetBridgeSpec(bridge_id)->min_length + 2;
|
||||
return static_cast<SQInteger>(::GetBridgeSpec(bridge_id)->min_length) + 2;
|
||||
}
|
||||
|
||||
/* static */ TileIndex ScriptBridge::GetOtherBridgeEnd(TileIndex tile)
|
||||
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
* @pre vehicle_type == ScriptVehicle::VT_ROAD || vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_WATER
|
||||
* @return The name the bridge has.
|
||||
*/
|
||||
static char *GetName(BridgeID bridge_id, ScriptVehicle::VehicleType vehicle_type);
|
||||
static std::optional<std::string> GetName(BridgeID bridge_id, ScriptVehicle::VehicleType vehicle_type);
|
||||
|
||||
/**
|
||||
* Get the maximum speed of a bridge.
|
||||
@@ -80,16 +80,17 @@ public:
|
||||
* This is mph / 1.6, which is roughly km/h.
|
||||
* To get km/h multiply this number by 1.00584.
|
||||
*/
|
||||
static int32 GetMaxSpeed(BridgeID bridge_id);
|
||||
static SQInteger GetMaxSpeed(BridgeID bridge_id);
|
||||
|
||||
/**
|
||||
* Get the new cost of a bridge, excluding the road and/or rail.
|
||||
* @param bridge_id The bridge to get the new cost of.
|
||||
* @param length The length of the bridge.
|
||||
* The value will be clamped to 0 .. MAX(int32_t).
|
||||
* @pre IsValidBridge(bridge_id).
|
||||
* @return The new cost the bridge has.
|
||||
*/
|
||||
static Money GetPrice(BridgeID bridge_id, uint length);
|
||||
static Money GetPrice(BridgeID bridge_id, SQInteger length);
|
||||
|
||||
/**
|
||||
* Get the maximum length of a bridge.
|
||||
@@ -97,7 +98,7 @@ public:
|
||||
* @pre IsValidBridge(bridge_id).
|
||||
* @returns The maximum length the bridge has.
|
||||
*/
|
||||
static int32 GetMaxLength(BridgeID bridge_id);
|
||||
static SQInteger GetMaxLength(BridgeID bridge_id);
|
||||
|
||||
/**
|
||||
* Get the minimum length of a bridge.
|
||||
@@ -105,7 +106,7 @@ public:
|
||||
* @pre IsValidBridge(bridge_id).
|
||||
* @returns The minimum length the bridge has.
|
||||
*/
|
||||
static int32 GetMinLength(BridgeID bridge_id);
|
||||
static SQInteger GetMinLength(BridgeID bridge_id);
|
||||
|
||||
/**
|
||||
* Internal function to help BuildBridge in case of road.
|
||||
@@ -136,7 +137,7 @@ public:
|
||||
* @pre vehicle_type == ScriptVehicle::VT_WATER ||
|
||||
* (vehicle_type == ScriptVehicle::VT_ROAD && ScriptRoad::IsRoadTypeAvailable(ScriptRoad::GetCurrentRoadType())) ||
|
||||
* (vehicle_type == ScriptVehicle::VT_RAIL && ScriptRail::IsRailTypeAvailable(ScriptRail::GetCurrentRailType())).
|
||||
* @game @pre Outside CompanyMode: vehicle_type == ScriptVehicle::VT_ROAD.
|
||||
* @game @pre ScriptCompanyMode::IsValid() || vehicle_type == ScriptVehicle::VT_ROAD.
|
||||
* @exception ScriptError::ERR_ALREADY_BUILT
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
* @exception ScriptError::ERR_LAND_SLOPED_WRONG
|
||||
@@ -145,7 +146,7 @@ public:
|
||||
* @exception ScriptBridge::ERR_BRIDGE_CANNOT_END_IN_WATER
|
||||
* @exception ScriptBridge::ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT
|
||||
* @return Whether the bridge has been/can be build or not.
|
||||
* @game @note Building a bridge (without CompanyMode) results in a bridge owned by towns.
|
||||
* @game @note Building a bridge as deity (ScriptCompanyMode::IsDeity()) results in a bridge owned by towns.
|
||||
* @note No matter if the road pieces were build or not, if building the
|
||||
* bridge succeeded, this function returns true.
|
||||
*/
|
||||
@@ -155,7 +156,7 @@ public:
|
||||
* Removes a bridge, by executing it on either the start or end tile.
|
||||
* @param tile An end or start tile of the bridge.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @return Whether the bridge has been/can be removed or not.
|
||||
*/
|
||||
|
||||
@@ -21,11 +21,11 @@ ScriptBridgeList::ScriptBridgeList()
|
||||
}
|
||||
}
|
||||
|
||||
ScriptBridgeList_Length::ScriptBridgeList_Length(uint length)
|
||||
ScriptBridgeList_Length::ScriptBridgeList_Length(SQInteger length)
|
||||
{
|
||||
for (byte j = 0; j < MAX_BRIDGES; j++) {
|
||||
if (ScriptBridge::IsValidBridge(j)) {
|
||||
if (length >= (uint)ScriptBridge::GetMinLength(j) && length <= (uint)ScriptBridge::GetMaxLength(j)) this->AddItem(j);
|
||||
if (length >= ScriptBridge::GetMinLength(j) && length <= ScriptBridge::GetMaxLength(j)) this->AddItem(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
/**
|
||||
* @param length The length of the bridge you want to build.
|
||||
*/
|
||||
ScriptBridgeList_Length(uint length);
|
||||
ScriptBridgeList_Length(SQInteger length);
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_BRIDGELIST_HPP */
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "../../stdafx.h"
|
||||
#include "script_cargo.hpp"
|
||||
#include "../../economy_func.h"
|
||||
#include "../../core/alloc_func.hpp"
|
||||
#include "../../core/bitmath_func.hpp"
|
||||
#include "../../strings_func.h"
|
||||
#include "../../settings_type.h"
|
||||
@@ -24,29 +25,28 @@
|
||||
|
||||
/* static */ bool ScriptCargo::IsValidTownEffect(TownEffect towneffect_type)
|
||||
{
|
||||
return (towneffect_type >= (TownEffect)TE_BEGIN && towneffect_type < (TownEffect)TE_END);
|
||||
return (towneffect_type >= (TownEffect)TAE_BEGIN && towneffect_type < (TownEffect)TAE_END);
|
||||
}
|
||||
|
||||
/* static */ char *ScriptCargo::GetName(CargoID cargo_type)
|
||||
/* static */ std::optional<std::string> ScriptCargo::GetName(CargoID cargo_type)
|
||||
{
|
||||
if (!IsValidCargo(cargo_type)) return nullptr;
|
||||
if (!IsValidCargo(cargo_type)) return std::nullopt;
|
||||
|
||||
::SetDParam(0, 1ULL << cargo_type);
|
||||
return GetString(STR_JUST_CARGO_LIST);
|
||||
}
|
||||
|
||||
/* static */ char *ScriptCargo::GetCargoLabel(CargoID cargo_type)
|
||||
/* static */ std::optional<std::string> ScriptCargo::GetCargoLabel(CargoID cargo_type)
|
||||
{
|
||||
if (!IsValidCargo(cargo_type)) return nullptr;
|
||||
if (!IsValidCargo(cargo_type)) return std::nullopt;
|
||||
const CargoSpec *cargo = ::CargoSpec::Get(cargo_type);
|
||||
|
||||
/* cargo->label is a uint32 packing a 4 character non-terminated string,
|
||||
/* cargo->label is a uint32_t packing a 4 character non-terminated string,
|
||||
* like "PASS", "COAL", "OIL_". New ones can be defined by NewGRFs */
|
||||
char *cargo_label = MallocT<char>(sizeof(cargo->label) + 1);
|
||||
std::string cargo_label;
|
||||
for (uint i = 0; i < sizeof(cargo->label); i++) {
|
||||
cargo_label[i] = GB(cargo->label, (uint8)(sizeof(cargo->label) - i - 1) * 8, 8);
|
||||
cargo_label.push_back(GB(cargo->label, (uint8_t)(sizeof(cargo->label) - i - 1) * 8, 8));
|
||||
}
|
||||
cargo_label[sizeof(cargo->label)] = '\0';
|
||||
return cargo_label;
|
||||
}
|
||||
|
||||
@@ -67,13 +67,16 @@
|
||||
{
|
||||
if (!IsValidCargo(cargo_type)) return TE_NONE;
|
||||
|
||||
return (ScriptCargo::TownEffect)::CargoSpec::Get(cargo_type)->town_effect;
|
||||
return (ScriptCargo::TownEffect)::CargoSpec::Get(cargo_type)->town_acceptance_effect;
|
||||
}
|
||||
|
||||
/* static */ Money ScriptCargo::GetCargoIncome(CargoID cargo_type, uint32 distance, uint32 days_in_transit)
|
||||
/* static */ Money ScriptCargo::GetCargoIncome(CargoID cargo_type, SQInteger distance, SQInteger days_in_transit)
|
||||
{
|
||||
if (!IsValidCargo(cargo_type)) return -1;
|
||||
return ::GetTransportedGoodsIncome(1, distance, Clamp(days_in_transit * 2 / 5, 0, 255), cargo_type);
|
||||
|
||||
distance = Clamp<SQInteger>(distance, 0, UINT32_MAX);
|
||||
|
||||
return ::GetTransportedGoodsIncome(1, distance, Clamp(days_in_transit * 2 / 5, 0, UINT16_MAX), cargo_type);
|
||||
}
|
||||
|
||||
/* static */ ScriptCargo::DistributionType ScriptCargo::GetDistributionType(CargoID cargo_type)
|
||||
@@ -82,8 +85,11 @@
|
||||
return (ScriptCargo::DistributionType)_settings_game.linkgraph.GetDistributionType(cargo_type);
|
||||
}
|
||||
|
||||
/* static */ int64 ScriptCargo::GetWeight(CargoID cargo_type, uint32 amount)
|
||||
/* static */ SQInteger ScriptCargo::GetWeight(CargoID cargo_type, SQInteger amount)
|
||||
{
|
||||
if (!IsValidCargo(cargo_type)) return -1;
|
||||
|
||||
amount = Clamp<SQInteger>(amount, 0, UINT32_MAX);
|
||||
|
||||
return ::CargoSpec::Get(cargo_type)->WeightOfNUnits(amount);
|
||||
}
|
||||
|
||||
@@ -42,12 +42,12 @@ public:
|
||||
*/
|
||||
enum TownEffect {
|
||||
/* Note: these values represent part of the in-game TownEffect enum */
|
||||
TE_NONE = ::TE_NONE, ///< This cargo has no effect on a town
|
||||
TE_PASSENGERS = ::TE_PASSENGERS, ///< This cargo supplies passengers to a town
|
||||
TE_MAIL = ::TE_MAIL, ///< This cargo supplies mail to a town
|
||||
TE_GOODS = ::TE_GOODS, ///< This cargo supplies goods to a town
|
||||
TE_WATER = ::TE_WATER, ///< This cargo supplies water to a town
|
||||
TE_FOOD = ::TE_FOOD, ///< This cargo supplies food to a town
|
||||
TE_NONE = ::TAE_NONE, ///< This cargo has no effect on a town
|
||||
TE_PASSENGERS = ::TAE_PASSENGERS, ///< This cargo supplies passengers to a town
|
||||
TE_MAIL = ::TAE_MAIL, ///< This cargo supplies mail to a town
|
||||
TE_GOODS = ::TAE_GOODS, ///< This cargo supplies goods to a town
|
||||
TE_WATER = ::TAE_WATER, ///< This cargo supplies water to a town
|
||||
TE_FOOD = ::TAE_FOOD, ///< This cargo supplies food to a town
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -55,9 +55,9 @@ public:
|
||||
*/
|
||||
enum SpecialCargoID {
|
||||
/* Note: these values represent part of the in-game CargoTypes enum */
|
||||
CT_AUTO_REFIT = ::CT_AUTO_REFIT, ///< Automatically choose cargo type when doing auto-refitting.
|
||||
CT_NO_REFIT = ::CT_NO_REFIT, ///< Do not refit cargo of a vehicle.
|
||||
CT_INVALID = ::CT_INVALID, ///< An invalid cargo type.
|
||||
CT_AUTO_REFIT = ::CARGO_AUTO_REFIT, ///< Automatically choose cargo type when doing auto-refitting.
|
||||
CT_NO_REFIT = ::CARGO_NO_REFIT, ///< Do not refit cargo of a vehicle.
|
||||
CT_INVALID = ::INVALID_CARGO, ///< An invalid cargo type.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -90,7 +90,7 @@ public:
|
||||
* @pre IsValidCargo(cargo_type).
|
||||
* @return The name of the cargo type.
|
||||
*/
|
||||
static char *GetName(CargoID cargo_type);
|
||||
static std::optional<std::string> GetName(CargoID cargo_type);
|
||||
|
||||
/**
|
||||
* Gets the string representation of the cargo label.
|
||||
@@ -107,7 +107,7 @@ public:
|
||||
* - In other words: Only use the cargo label, if you know more about the behaviour
|
||||
* of a specific cargo from a specific industry set, than the API methods can tell you.
|
||||
*/
|
||||
static char *GetCargoLabel(CargoID cargo_type);
|
||||
static std::optional<std::string> GetCargoLabel(CargoID cargo_type);
|
||||
|
||||
/**
|
||||
* Checks whether the give cargo is a freight or not.
|
||||
@@ -142,10 +142,12 @@ public:
|
||||
* @param cargo_type The cargo to transport.
|
||||
* @pre ScriptCargo::IsValidCargo(cargo_type).
|
||||
* @param distance The distance the cargo travels from begin to end.
|
||||
* @param days_in_transit Amount of (game) days the cargo is in transit. The max value of this variable is 637. Any value higher returns the same as 637 would.
|
||||
* The value will be clamped to 0 .. MAX(uint32_t).
|
||||
* @param days_in_transit Amount of (game) days the cargo is in transit.
|
||||
* The max value of this variable is 637. Any value higher returns the same as 637 would.
|
||||
* @return The amount of money that would be earned by this trip.
|
||||
*/
|
||||
static Money GetCargoIncome(CargoID cargo_type, uint32 distance, uint32 days_in_transit);
|
||||
static Money GetCargoIncome(CargoID cargo_type, SQInteger distance, SQInteger days_in_transit);
|
||||
|
||||
/**
|
||||
* Get the cargo distribution type for a cargo.
|
||||
@@ -159,10 +161,11 @@ public:
|
||||
* cargo for the specified type.
|
||||
* @param cargo_type The cargo to check on.
|
||||
* @param amount The quantity of cargo.
|
||||
* The value will be clamped to 0 .. MAX(uint32_t).
|
||||
* @pre ScriptCargo::IsValidCargo(cargo_type).
|
||||
* @return The weight in tonnes for that quantity of cargo.
|
||||
*/
|
||||
static int64 GetWeight(CargoID cargo_type, uint32 amount);
|
||||
static SQInteger GetWeight(CargoID cargo_type, SQInteger amount);
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_CARGO_HPP */
|
||||
|
||||
@@ -29,10 +29,9 @@ ScriptCargoList_IndustryAccepting::ScriptCargoList_IndustryAccepting(IndustryID
|
||||
if (!ScriptIndustry::IsValidIndustry(industry_id)) return;
|
||||
|
||||
Industry *ind = ::Industry::Get(industry_id);
|
||||
for (uint i = 0; i < lengthof(ind->accepts_cargo); i++) {
|
||||
CargoID cargo_id = ind->accepts_cargo[i];
|
||||
if (cargo_id != CT_INVALID) {
|
||||
this->AddItem(cargo_id);
|
||||
for (const auto &a : ind->accepted) {
|
||||
if (::IsValidCargoID(a.cargo)) {
|
||||
this->AddItem(a.cargo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,10 +41,9 @@ ScriptCargoList_IndustryProducing::ScriptCargoList_IndustryProducing(IndustryID
|
||||
if (!ScriptIndustry::IsValidIndustry(industry_id)) return;
|
||||
|
||||
Industry *ind = ::Industry::Get(industry_id);
|
||||
for (uint i = 0; i < lengthof(ind->produced_cargo); i++) {
|
||||
CargoID cargo_id = ind->produced_cargo[i];
|
||||
if (cargo_id != CT_INVALID) {
|
||||
this->AddItem(cargo_id);
|
||||
for (const auto &p : ind->produced) {
|
||||
if (::IsValidCargoID(p.cargo)) {
|
||||
this->AddItem(p.cargo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
/* static */ int32 ScriptCargoMonitor::GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring)
|
||||
/* static */ SQInteger ScriptCargoMonitor::GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring)
|
||||
{
|
||||
CompanyID cid = static_cast<CompanyID>(company);
|
||||
if (cid >= MAX_COMPANIES) return -1;
|
||||
@@ -26,7 +26,7 @@
|
||||
return GetDeliveryAmount(monitor, keep_monitoring);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptCargoMonitor::GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring)
|
||||
/* static */ SQInteger ScriptCargoMonitor::GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring)
|
||||
{
|
||||
CompanyID cid = static_cast<CompanyID>(company);
|
||||
if (cid >= MAX_COMPANIES) return -1;
|
||||
@@ -37,7 +37,7 @@
|
||||
return GetDeliveryAmount(monitor, keep_monitoring);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptCargoMonitor::GetTownPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring)
|
||||
/* static */ SQInteger ScriptCargoMonitor::GetTownPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring)
|
||||
{
|
||||
CompanyID cid = static_cast<CompanyID>(company);
|
||||
if (cid >= MAX_COMPANIES) return -1;
|
||||
@@ -48,7 +48,7 @@
|
||||
return GetPickupAmount(monitor, keep_monitoring);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptCargoMonitor::GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring)
|
||||
/* static */ SQInteger ScriptCargoMonitor::GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring)
|
||||
{
|
||||
CompanyID cid = static_cast<CompanyID>(company);
|
||||
if (cid >= MAX_COMPANIES) return -1;
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
* @return Amount of delivered cargo of the given cargo type to the given town by the given company since the last call, or
|
||||
* \c -1 if a parameter is out-of-bound.
|
||||
*/
|
||||
static int32 GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring);
|
||||
static SQInteger GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring);
|
||||
|
||||
/**
|
||||
* Get the amount of cargo delivered to an industry by a company since the last query, and update the monitoring state.
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
* @return Amount of delivered cargo of the given cargo type to the given industry by the given company since the last call, or
|
||||
* \c -1 if a parameter is out-of-bound.
|
||||
*/
|
||||
static int32 GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring);
|
||||
static SQInteger GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring);
|
||||
|
||||
/**
|
||||
* Get the amount of cargo picked up (and delivered) from a town by a company since the last query, and update the monitoring state.
|
||||
@@ -74,7 +74,7 @@ public:
|
||||
* \c -1 if a parameter is out-of-bound.
|
||||
* @note Amounts of picked-up cargo are added during final delivery of it, to prevent users from getting credit for picking up without delivering it.
|
||||
*/
|
||||
static int32 GetTownPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring);
|
||||
static SQInteger GetTownPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring);
|
||||
|
||||
/**
|
||||
* Get the amount of cargo picked up (and delivered) from an industry by a company since the last query, and update the monitoring state.
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
* \c -1 if a parameter is out-of-bound.
|
||||
* @note Amounts of picked-up cargo are added during final delivery of it, to prevent users from getting credit for picking up without delivering it.
|
||||
*/
|
||||
static int32 GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring);
|
||||
static SQInteger GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring);
|
||||
|
||||
/** Stop monitoring everything. */
|
||||
static void StopAllMonitoring();
|
||||
|
||||
@@ -32,11 +32,11 @@ static NetworkClientInfo *FindClientInfo(ScriptClient::ClientID client)
|
||||
return (FindClientInfo(client) == nullptr ? ScriptClient::CLIENT_INVALID : client);
|
||||
}
|
||||
|
||||
/* static */ char *ScriptClient::GetName(ScriptClient::ClientID client)
|
||||
/* static */ std::optional<std::string> ScriptClient::GetName(ScriptClient::ClientID client)
|
||||
{
|
||||
NetworkClientInfo *ci = FindClientInfo(client);
|
||||
if (ci == nullptr) return nullptr;
|
||||
return stredup(ci->client_name.c_str());
|
||||
if (ci == nullptr) return std::nullopt;
|
||||
return ci->client_name;
|
||||
}
|
||||
|
||||
/* static */ ScriptCompany::CompanyID ScriptClient::GetCompany(ScriptClient::ClientID client)
|
||||
@@ -50,5 +50,5 @@ static NetworkClientInfo *FindClientInfo(ScriptClient::ClientID client)
|
||||
{
|
||||
NetworkClientInfo *ci = FindClientInfo(client);
|
||||
if (ci == nullptr) return ScriptDate::DATE_INVALID;
|
||||
return (ScriptDate::Date)ci->join_date;
|
||||
return (ScriptDate::Date)ci->join_date.base();
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ class ScriptClient : public ScriptObject {
|
||||
public:
|
||||
|
||||
/** Different constants related to ClientID. */
|
||||
enum ClientID : uint32 {
|
||||
enum ClientID : uint32_t {
|
||||
CLIENT_INVALID = 0, ///< Client is not part of anything
|
||||
CLIENT_SERVER = 1, ///< Servers always have this ID
|
||||
CLIENT_FIRST = 2, ///< The first client ID
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
* @pre ResolveClientID(client) != CLIENT_INVALID.
|
||||
* @return The name of the given client.
|
||||
*/
|
||||
static char *GetName(ClientID client);
|
||||
static std::optional<std::string> GetName(ClientID client);
|
||||
|
||||
/**
|
||||
* Get the company in which the given client is playing.
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
/* static */ bool ScriptCompany::IsMine(ScriptCompany::CompanyID company)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
return ResolveCompanyID(company) == ResolveCompanyID(COMPANY_SELF);
|
||||
}
|
||||
|
||||
@@ -47,18 +48,19 @@
|
||||
{
|
||||
CCountedPtr<Text> counter(name);
|
||||
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, name != nullptr);
|
||||
const char *text = name->GetDecodedText();
|
||||
const std::string &text = name->GetDecodedText();
|
||||
EnforcePreconditionEncodedText(false, text);
|
||||
EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_COMPANY_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG);
|
||||
|
||||
return ScriptObject::Command<CMD_RENAME_COMPANY>::Do(text);
|
||||
}
|
||||
|
||||
/* static */ char *ScriptCompany::GetName(ScriptCompany::CompanyID company)
|
||||
/* static */ std::optional<std::string> ScriptCompany::GetName(ScriptCompany::CompanyID company)
|
||||
{
|
||||
company = ResolveCompanyID(company);
|
||||
if (company == COMPANY_INVALID) return nullptr;
|
||||
if (company == COMPANY_INVALID) return std::nullopt;
|
||||
|
||||
::SetDParam(0, company);
|
||||
return GetString(STR_COMPANY_NAME);
|
||||
@@ -68,38 +70,34 @@
|
||||
{
|
||||
CCountedPtr<Text> counter(name);
|
||||
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, name != nullptr);
|
||||
const char *text = name->GetDecodedText();
|
||||
const std::string &text = name->GetDecodedText();
|
||||
EnforcePreconditionEncodedText(false, text);
|
||||
EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_PRESIDENT_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG);
|
||||
|
||||
return ScriptObject::Command<CMD_RENAME_PRESIDENT>::Do(text);
|
||||
}
|
||||
|
||||
/* static */ char *ScriptCompany::GetPresidentName(ScriptCompany::CompanyID company)
|
||||
/* static */ std::optional<std::string> ScriptCompany::GetPresidentName(ScriptCompany::CompanyID company)
|
||||
{
|
||||
company = ResolveCompanyID(company);
|
||||
if (company == COMPANY_INVALID) return std::nullopt;
|
||||
|
||||
static const int len = 64;
|
||||
char *president_name = MallocT<char>(len);
|
||||
if (company != COMPANY_INVALID) {
|
||||
::SetDParam(0, company);
|
||||
::GetString(president_name, STR_PRESIDENT_NAME, &president_name[len - 1]);
|
||||
} else {
|
||||
*president_name = '\0';
|
||||
}
|
||||
|
||||
return president_name;
|
||||
::SetDParam(0, company);
|
||||
return GetString(STR_PRESIDENT_NAME);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptCompany::SetPresidentGender(Gender gender)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, gender == GENDER_MALE || gender == GENDER_FEMALE);
|
||||
EnforcePrecondition(false, GetPresidentGender(ScriptCompany::COMPANY_SELF) != gender);
|
||||
|
||||
Randomizer &randomizer = ScriptObject::GetRandomizer();
|
||||
CompanyManagerFace cmf;
|
||||
GenderEthnicity ge = (GenderEthnicity)((gender == GENDER_FEMALE ? (1 << ::GENDER_FEMALE) : 0) | (::InteractiveRandom() & (1 << ETHNICITY_BLACK)));
|
||||
RandomCompanyManagerFaceBits(cmf, ge, false);
|
||||
GenderEthnicity ge = (GenderEthnicity)((gender == GENDER_FEMALE ? (1 << ::GENDER_FEMALE) : 0) | (randomizer.Next() & (1 << ETHNICITY_BLACK)));
|
||||
RandomCompanyManagerFaceBits(cmf, ge, false, randomizer);
|
||||
|
||||
return ScriptObject::Command<CMD_SET_COMPANY_MANAGER_FACE>::Do(cmf);
|
||||
}
|
||||
@@ -113,11 +111,12 @@
|
||||
return HasBit(ge, ::GENDER_FEMALE) ? GENDER_FEMALE : GENDER_MALE;
|
||||
}
|
||||
|
||||
/* static */ Money ScriptCompany::GetQuarterlyIncome(ScriptCompany::CompanyID company, uint32 quarter)
|
||||
/* static */ Money ScriptCompany::GetQuarterlyIncome(ScriptCompany::CompanyID company, SQInteger quarter)
|
||||
{
|
||||
company = ResolveCompanyID(company);
|
||||
if (company == COMPANY_INVALID) return -1;
|
||||
if (quarter > EARLIEST_QUARTER) return -1;
|
||||
if (quarter < CURRENT_QUARTER) return -1;
|
||||
|
||||
if (quarter == CURRENT_QUARTER) {
|
||||
return ::Company::Get(company)->cur_economy.income;
|
||||
@@ -125,11 +124,12 @@
|
||||
return ::Company::Get(company)->old_economy[quarter - 1].income;
|
||||
}
|
||||
|
||||
/* static */ Money ScriptCompany::GetQuarterlyExpenses(ScriptCompany::CompanyID company, uint32 quarter)
|
||||
/* static */ Money ScriptCompany::GetQuarterlyExpenses(ScriptCompany::CompanyID company, SQInteger quarter)
|
||||
{
|
||||
company = ResolveCompanyID(company);
|
||||
if (company == COMPANY_INVALID) return -1;
|
||||
if (quarter > EARLIEST_QUARTER) return -1;
|
||||
if (quarter < CURRENT_QUARTER) return -1;
|
||||
|
||||
if (quarter == CURRENT_QUARTER) {
|
||||
return ::Company::Get(company)->cur_economy.expenses;
|
||||
@@ -137,11 +137,12 @@
|
||||
return ::Company::Get(company)->old_economy[quarter - 1].expenses;
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptCompany::GetQuarterlyCargoDelivered(ScriptCompany::CompanyID company, uint32 quarter)
|
||||
/* static */ SQInteger ScriptCompany::GetQuarterlyCargoDelivered(ScriptCompany::CompanyID company, SQInteger quarter)
|
||||
{
|
||||
company = ResolveCompanyID(company);
|
||||
if (company == COMPANY_INVALID) return -1;
|
||||
if (quarter > EARLIEST_QUARTER) return -1;
|
||||
if (quarter < CURRENT_QUARTER) return -1;
|
||||
|
||||
if (quarter == CURRENT_QUARTER) {
|
||||
return ::Company::Get(company)->cur_economy.delivered_cargo.GetSum<OverflowSafeInt32>();
|
||||
@@ -149,21 +150,22 @@
|
||||
return ::Company::Get(company)->old_economy[quarter - 1].delivered_cargo.GetSum<OverflowSafeInt32>();
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptCompany::GetQuarterlyPerformanceRating(ScriptCompany::CompanyID company, uint32 quarter)
|
||||
/* static */ SQInteger ScriptCompany::GetQuarterlyPerformanceRating(ScriptCompany::CompanyID company, SQInteger quarter)
|
||||
{
|
||||
company = ResolveCompanyID(company);
|
||||
if (company == COMPANY_INVALID) return -1;
|
||||
if (quarter > EARLIEST_QUARTER) return -1;
|
||||
if (quarter == CURRENT_QUARTER) return -1;
|
||||
if (quarter <= CURRENT_QUARTER) return -1;
|
||||
|
||||
return ::Company::Get(company)->old_economy[quarter - 1].performance_history;
|
||||
}
|
||||
|
||||
/* static */ Money ScriptCompany::GetQuarterlyCompanyValue(ScriptCompany::CompanyID company, uint32 quarter)
|
||||
/* static */ Money ScriptCompany::GetQuarterlyCompanyValue(ScriptCompany::CompanyID company, SQInteger quarter)
|
||||
{
|
||||
company = ResolveCompanyID(company);
|
||||
if (company == COMPANY_INVALID) return -1;
|
||||
if (quarter > EARLIEST_QUARTER) return -1;
|
||||
if (quarter < CURRENT_QUARTER) return -1;
|
||||
|
||||
if (quarter == CURRENT_QUARTER) {
|
||||
return ::CalculateCompanyValue(::Company::Get(company));
|
||||
@@ -177,7 +179,7 @@
|
||||
company = ResolveCompanyID(company);
|
||||
if (company == COMPANY_INVALID) return -1;
|
||||
|
||||
return ::Company::Get(company)->money;
|
||||
return GetAvailableMoney((::CompanyID)company);
|
||||
}
|
||||
|
||||
/* static */ Money ScriptCompany::GetLoanAmount()
|
||||
@@ -190,7 +192,32 @@
|
||||
|
||||
/* static */ Money ScriptCompany::GetMaxLoanAmount()
|
||||
{
|
||||
return _economy.max_loan;
|
||||
if (ScriptCompanyMode::IsDeity()) return _economy.max_loan;
|
||||
|
||||
ScriptCompany::CompanyID company = ResolveCompanyID(COMPANY_SELF);
|
||||
if (company == COMPANY_INVALID) return -1;
|
||||
|
||||
return ::Company::Get(company)->GetMaxLoan();
|
||||
}
|
||||
|
||||
/* static */ bool ScriptCompany::SetMaxLoanAmountForCompany(CompanyID company, Money amount)
|
||||
{
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, amount >= 0 && amount <= (Money)MAX_LOAN_LIMIT);
|
||||
|
||||
company = ResolveCompanyID(company);
|
||||
EnforcePrecondition(false, company != COMPANY_INVALID);
|
||||
return ScriptObject::Command<CMD_SET_COMPANY_MAX_LOAN>::Do((::CompanyID)company, amount);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptCompany::ResetMaxLoanAmountForCompany(CompanyID company)
|
||||
{
|
||||
EnforceDeityMode(false);
|
||||
|
||||
company = ResolveCompanyID(company);
|
||||
EnforcePrecondition(false, company != COMPANY_INVALID);
|
||||
|
||||
return ScriptObject::Command<CMD_SET_COMPANY_MAX_LOAN>::Do((::CompanyID)company, COMPANY_MAX_LOAN_DEFAULT);
|
||||
}
|
||||
|
||||
/* static */ Money ScriptCompany::GetLoanInterval()
|
||||
@@ -200,9 +227,9 @@
|
||||
|
||||
/* static */ bool ScriptCompany::SetLoanAmount(Money loan)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, loan >= 0);
|
||||
EnforcePrecondition(false, ((int64)loan % GetLoanInterval()) == 0);
|
||||
EnforcePrecondition(false, ((int64_t)loan % GetLoanInterval()) == 0);
|
||||
EnforcePrecondition(false, loan <= GetMaxLoanAmount());
|
||||
EnforcePrecondition(false, (loan - GetLoanAmount() + GetBankBalance(COMPANY_SELF)) >= 0);
|
||||
|
||||
@@ -219,10 +246,10 @@
|
||||
|
||||
/* static */ bool ScriptCompany::SetMinimumLoanAmount(Money loan)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, loan >= 0);
|
||||
|
||||
Money over_interval = (int64)loan % GetLoanInterval();
|
||||
Money over_interval = (int64_t)loan % GetLoanInterval();
|
||||
if (over_interval != 0) loan += GetLoanInterval() - over_interval;
|
||||
|
||||
EnforcePrecondition(false, loan <= GetMaxLoanAmount());
|
||||
@@ -234,10 +261,8 @@
|
||||
|
||||
/* static */ bool ScriptCompany::ChangeBankBalance(CompanyID company, Money delta, ExpensesType expenses_type, TileIndex tile)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, expenses_type < (ExpensesType)::EXPENSES_END);
|
||||
EnforcePrecondition(false, (int64)delta >= INT32_MIN);
|
||||
EnforcePrecondition(false, (int64)delta <= INT32_MAX);
|
||||
EnforcePrecondition(false, tile == INVALID_TILE || ::IsValidTile(tile));
|
||||
|
||||
company = ResolveCompanyID(company);
|
||||
@@ -249,7 +274,7 @@
|
||||
|
||||
/* static */ bool ScriptCompany::BuildCompanyHQ(TileIndex tile)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
|
||||
return ScriptObject::Command<CMD_BUILD_OBJECT>::Do(tile, OBJECT_HQ, 0);
|
||||
@@ -266,6 +291,7 @@
|
||||
|
||||
/* static */ bool ScriptCompany::SetAutoRenewStatus(bool autorenew)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
return ScriptObject::Command<CMD_CHANGE_COMPANY_SETTING>::Do("company.engine_renew", autorenew ? 1 : 0);
|
||||
}
|
||||
|
||||
@@ -277,12 +303,15 @@
|
||||
return ::Company::Get(company)->settings.engine_renew;
|
||||
}
|
||||
|
||||
/* static */ bool ScriptCompany::SetAutoRenewMonths(int16 months)
|
||||
/* static */ bool ScriptCompany::SetAutoRenewMonths(SQInteger months)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
months = Clamp<SQInteger>(months, INT16_MIN, INT16_MAX);
|
||||
|
||||
return ScriptObject::Command<CMD_CHANGE_COMPANY_SETTING>::Do("company.engine_renew_months", months);
|
||||
}
|
||||
|
||||
/* static */ int16 ScriptCompany::GetAutoRenewMonths(CompanyID company)
|
||||
/* static */ SQInteger ScriptCompany::GetAutoRenewMonths(CompanyID company)
|
||||
{
|
||||
company = ResolveCompanyID(company);
|
||||
if (company == COMPANY_INVALID) return 0;
|
||||
@@ -292,8 +321,9 @@
|
||||
|
||||
/* static */ bool ScriptCompany::SetAutoRenewMoney(Money money)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, money >= 0);
|
||||
EnforcePrecondition(false, (int64)money <= UINT32_MAX);
|
||||
EnforcePrecondition(false, (int64_t)money <= UINT32_MAX);
|
||||
return ScriptObject::Command<CMD_CHANGE_COMPANY_SETTING>::Do("company.engine_renew_money", money);
|
||||
}
|
||||
|
||||
@@ -307,11 +337,13 @@
|
||||
|
||||
/* static */ bool ScriptCompany::SetPrimaryLiveryColour(LiveryScheme scheme, Colours colour)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
return ScriptObject::Command<CMD_SET_COMPANY_COLOUR>::Do((::LiveryScheme)scheme, true, (::Colours)colour);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptCompany::SetSecondaryLiveryColour(LiveryScheme scheme, Colours colour)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
return ScriptObject::Command<CMD_SET_COMPANY_COLOUR>::Do((::LiveryScheme)scheme, false, (::Colours)colour);
|
||||
}
|
||||
|
||||
|
||||
@@ -129,8 +129,8 @@ public:
|
||||
/**
|
||||
* Check if a CompanyID is your CompanyID, to ease up checks.
|
||||
* @param company The company index to check.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True if and only if this company is your CompanyID.
|
||||
* @api -game
|
||||
*/
|
||||
static bool IsMine(CompanyID company);
|
||||
|
||||
@@ -138,6 +138,7 @@ public:
|
||||
* Set the name of your company.
|
||||
* @param name The new name of the company (can be either a raw string, or a ScriptText object).
|
||||
* @pre name != null && len(name) != 0.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE
|
||||
* @return True if the name was changed.
|
||||
*/
|
||||
@@ -149,12 +150,13 @@ public:
|
||||
* @pre ResolveCompanyID(company) != COMPANY_INVALID.
|
||||
* @return The name of the given company.
|
||||
*/
|
||||
static char *GetName(CompanyID company);
|
||||
static std::optional<std::string> GetName(CompanyID company);
|
||||
|
||||
/**
|
||||
* Set the name of your president.
|
||||
* @param name The new name of the president (can be either a raw string, or a ScriptText object).
|
||||
* @pre name != null && len(name) != 0.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE
|
||||
* @return True if the name was changed.
|
||||
*/
|
||||
@@ -166,15 +168,15 @@ public:
|
||||
* @pre ResolveCompanyID(company) != COMPANY_INVALID.
|
||||
* @return The name of the president of the given company.
|
||||
*/
|
||||
static char *GetPresidentName(CompanyID company);
|
||||
static std::optional<std::string> GetPresidentName(CompanyID company);
|
||||
|
||||
/**
|
||||
* Set the gender of the president of your company.
|
||||
* @param gender The new gender for your president.
|
||||
* @pre GetPresidentGender(ScriptCompany.COMPANY_SELF) != gender.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True if the gender was changed.
|
||||
* @note When successful a random face will be created.
|
||||
* @api -game
|
||||
*/
|
||||
static bool SetPresidentGender(Gender gender);
|
||||
|
||||
@@ -192,7 +194,7 @@ public:
|
||||
* @pre GetLoanInterval() must be a multiplier of 'loan'.
|
||||
* @pre 'loan' must be below GetMaxLoanAmount().
|
||||
* @pre 'loan' - GetLoanAmount() + GetBankBalance() must be non-negative.
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True if the loan could be set to your requested amount.
|
||||
*/
|
||||
static bool SetLoanAmount(Money loan);
|
||||
@@ -202,7 +204,7 @@ public:
|
||||
* @param loan The amount to loan (any positive number).
|
||||
* @pre 'loan' must be non-negative.
|
||||
* @pre 'loan' must be below GetMaxLoanAmount().
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True if we could allocate a minimum of 'loan' loan.
|
||||
*/
|
||||
static bool SetMinimumLoanAmount(Money loan);
|
||||
@@ -215,12 +217,38 @@ public:
|
||||
static Money GetLoanAmount();
|
||||
|
||||
/**
|
||||
* Gets the maximum amount your company can loan.
|
||||
* Gets the maximum amount your company can loan. In deity mode returns the global max loan.
|
||||
* @return The maximum amount your company can loan.
|
||||
* @post GetLoanInterval() is always a multiplier of the return value.
|
||||
*/
|
||||
static Money GetMaxLoanAmount();
|
||||
|
||||
/**
|
||||
* Sets the max amount of money company can loan.
|
||||
* @param company The company ID.
|
||||
* @param amount Max loan amount. Will be rounded down to a multiple of GetLoanInterval().
|
||||
* @return True, if the max loan was changed.
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @pre amount >= 0.
|
||||
* @pre ResolveCompanyID(company) != COMPANY_INVALID.
|
||||
* @note You need to create your own news message to inform about max loan change.
|
||||
* @note Max loan value set with this method is not affected by inflation.
|
||||
* @api -ai
|
||||
*/
|
||||
static bool SetMaxLoanAmountForCompany(CompanyID company, Money amount);
|
||||
|
||||
/**
|
||||
* Makes the max amount of money company can loan follow the global max loan setting.
|
||||
* @param company The company ID.
|
||||
* @return True, if the max loan was reset.
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @pre amount >= 0 && amount <= MAX_LOAN_LIMIT.
|
||||
* @pre ResolveCompanyID(company) != COMPANY_INVALID.
|
||||
* @note You need to create your own news message to inform about max loan change.
|
||||
* @api -ai
|
||||
*/
|
||||
static bool ResetMaxLoanAmountForCompany(CompanyID company);
|
||||
|
||||
/**
|
||||
* Gets the interval/loan step.
|
||||
* @return The loan step.
|
||||
@@ -244,10 +272,8 @@ public:
|
||||
* @param expenses_type The account in the finances window that will register the cost.
|
||||
* @param tile The tile to show text effect on or ScriptMap::TILE_INVALID
|
||||
* @return True, if the bank balance was changed.
|
||||
* @game @pre No ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsDeity().
|
||||
* @pre ResolveCompanyID(company) != COMPANY_INVALID.
|
||||
* @pre delta >= -2**31
|
||||
* @pre delta < 2**31
|
||||
* @note You need to create your own news message to inform about costs/gifts that you create using this command.
|
||||
* @api -ai
|
||||
*/
|
||||
@@ -263,7 +289,7 @@ public:
|
||||
* @pre quarter <= EARLIEST_QUARTER.
|
||||
* @return The gross income of the company in the given quarter.
|
||||
*/
|
||||
static Money GetQuarterlyIncome(CompanyID company, uint32 quarter);
|
||||
static Money GetQuarterlyIncome(CompanyID company, SQInteger quarter);
|
||||
|
||||
/**
|
||||
* Get the expenses of the company in the given quarter.
|
||||
@@ -276,7 +302,7 @@ public:
|
||||
* @pre quarter <= EARLIEST_QUARTER.
|
||||
* @return The expenses of the company in the given quarter.
|
||||
*/
|
||||
static Money GetQuarterlyExpenses(CompanyID company, uint32 quarter);
|
||||
static Money GetQuarterlyExpenses(CompanyID company, SQInteger quarter);
|
||||
|
||||
/**
|
||||
* Get the amount of cargo delivered by the given company in the given quarter.
|
||||
@@ -286,7 +312,7 @@ public:
|
||||
* @pre quarter <= EARLIEST_QUARTER.
|
||||
* @return The amount of cargo delivered by the given company in the given quarter.
|
||||
*/
|
||||
static int32 GetQuarterlyCargoDelivered(CompanyID company, uint32 quarter);
|
||||
static SQInteger GetQuarterlyCargoDelivered(CompanyID company, SQInteger quarter);
|
||||
|
||||
/**
|
||||
* Get the performance rating of the given company in the given quarter.
|
||||
@@ -298,7 +324,7 @@ public:
|
||||
* @note The performance rating is calculated after every quarter, so the value for CURRENT_QUARTER is undefined.
|
||||
* @return The performance rating of the given company in the given quarter.
|
||||
*/
|
||||
static int32 GetQuarterlyPerformanceRating(CompanyID company, uint32 quarter);
|
||||
static SQInteger GetQuarterlyPerformanceRating(CompanyID company, SQInteger quarter);
|
||||
|
||||
/**
|
||||
* Get the value of the company in the given quarter.
|
||||
@@ -308,13 +334,13 @@ public:
|
||||
* @pre quarter <= EARLIEST_QUARTER.
|
||||
* @return The value of the company in the given quarter.
|
||||
*/
|
||||
static Money GetQuarterlyCompanyValue(CompanyID company, uint32 quarter);
|
||||
static Money GetQuarterlyCompanyValue(CompanyID company, SQInteger quarter);
|
||||
|
||||
/**
|
||||
* Build your company's HQ on the given tile.
|
||||
* @param tile The tile to build your HQ on, this tile is the most northern tile of your HQ.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
* @exception ScriptError::ERR_FLAT_LAND_REQUIRED
|
||||
* @return True if the HQ could be build.
|
||||
@@ -335,8 +361,8 @@ public:
|
||||
/**
|
||||
* Set whether autorenew is enabled for your company.
|
||||
* @param autorenew The new autorenew status.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True if autorenew status has been modified.
|
||||
* @api -game
|
||||
*/
|
||||
static bool SetAutoRenewStatus(bool autorenew);
|
||||
|
||||
@@ -351,10 +377,11 @@ public:
|
||||
/**
|
||||
* Set the number of months before/after max age to autorenew an engine for your company.
|
||||
* @param months The new months between autorenew.
|
||||
* The value will be clamped to MIN(int16_t) .. MAX(int16_t).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True if autorenew months has been modified.
|
||||
* @api -game
|
||||
*/
|
||||
static bool SetAutoRenewMonths(int16 months);
|
||||
static bool SetAutoRenewMonths(SQInteger months);
|
||||
|
||||
/**
|
||||
* Return the number of months before/after max age to autorenew an engine for a company.
|
||||
@@ -362,15 +389,15 @@ public:
|
||||
* @pre ResolveCompanyID(company) != COMPANY_INVALID.
|
||||
* @return The months before/after max age of engine.
|
||||
*/
|
||||
static int16 GetAutoRenewMonths(CompanyID company);
|
||||
static SQInteger GetAutoRenewMonths(CompanyID company);
|
||||
|
||||
/**
|
||||
* Set the minimum money needed to autorenew an engine for your company.
|
||||
* @param money The new minimum required money for autorenew to work.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True if autorenew money has been modified.
|
||||
* @pre money >= 0
|
||||
* @pre money < 2**32
|
||||
* @api -game
|
||||
*/
|
||||
static bool SetAutoRenewMoney(Money money);
|
||||
|
||||
@@ -386,6 +413,7 @@ public:
|
||||
* Set primary colour for your company.
|
||||
* @param scheme Livery scheme to set.
|
||||
* @param colour Colour to set.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return False if unable to set primary colour of the livery scheme (e.g. colour in use).
|
||||
*/
|
||||
static bool SetPrimaryLiveryColour(LiveryScheme scheme, Colours colour);
|
||||
@@ -394,6 +422,7 @@ public:
|
||||
* Set secondary colour for your company.
|
||||
* @param scheme Livery scheme to set.
|
||||
* @param colour Colour to set.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return False if unable to set secondary colour of the livery scheme.
|
||||
*/
|
||||
static bool SetSecondaryLiveryColour(LiveryScheme scheme, Colours colour);
|
||||
|
||||
@@ -13,16 +13,26 @@
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
ScriptCompanyMode::ScriptCompanyMode(int company)
|
||||
ScriptCompanyMode::ScriptCompanyMode(SQInteger company)
|
||||
{
|
||||
if (company < OWNER_BEGIN || company >= MAX_COMPANIES) company = INVALID_COMPANY;
|
||||
if (!::Company::IsValidID(company)) company = INVALID_COMPANY;
|
||||
|
||||
this->last_company = ScriptObject::GetCompany();
|
||||
ScriptObject::SetCompany((CompanyID)company);
|
||||
ScriptObject::SetCompany((::CompanyID)company);
|
||||
}
|
||||
|
||||
ScriptCompanyMode::~ScriptCompanyMode()
|
||||
{
|
||||
ScriptObject::SetCompany(this->last_company);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptCompanyMode::IsValid()
|
||||
{
|
||||
return ::Company::IsValidID(ScriptObject::GetCompany());
|
||||
}
|
||||
|
||||
/* static */ bool ScriptCompanyMode::IsDeity()
|
||||
{
|
||||
return ScriptObject::GetCompany() == OWNER_DEITY;
|
||||
}
|
||||
|
||||
@@ -40,13 +40,29 @@ public:
|
||||
* @note When the instance is destroyed, it restores the company that was
|
||||
* current when the instance was created!
|
||||
*/
|
||||
ScriptCompanyMode(int company);
|
||||
ScriptCompanyMode(SQInteger company);
|
||||
|
||||
/**
|
||||
* Destroying this instance reset the company to that what it was
|
||||
* in when the instance was created.
|
||||
*/
|
||||
~ScriptCompanyMode();
|
||||
|
||||
/**
|
||||
* Check whether a company mode is valid. In other words, are commands
|
||||
* being executed under some company and does the company still exist?
|
||||
* @return true When a company mode is valid.
|
||||
* @post !ScriptCompanyMode::IsDeity().
|
||||
*/
|
||||
static bool IsValid();
|
||||
|
||||
/**
|
||||
* Check whether the company mode is not active, i.e. whether we are a deity.
|
||||
* In other words, are commands are not being executed under some company.
|
||||
* @return true When we are a deity, i.e. company mode is not active.
|
||||
* @post !ScriptCompanyMode::IsValid().
|
||||
*/
|
||||
static bool IsDeity();
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_COMPANYMODE_HPP */
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "../script_info.hpp"
|
||||
#include "../script_instance.hpp"
|
||||
#include "script_log.hpp"
|
||||
#include "../../ai/ai_gui.hpp"
|
||||
#include "../script_gui.h"
|
||||
#include "../../settings_type.h"
|
||||
#include "../../network/network.h"
|
||||
#include "../../misc_cmd.h"
|
||||
@@ -45,28 +45,26 @@
|
||||
throw Script_Suspend(ticks, nullptr);
|
||||
}
|
||||
|
||||
/* static */ void ScriptController::Break(const char* message)
|
||||
/* static */ void ScriptController::Break(const std::string &message)
|
||||
{
|
||||
if (_network_dedicated || !_settings_client.gui.ai_developer_tools) return;
|
||||
|
||||
ScriptObject::GetActiveInstance()->Pause();
|
||||
|
||||
char log_message[1024];
|
||||
seprintf(log_message, lastof(log_message), "Break: %s", message);
|
||||
ScriptLog::Log(ScriptLog::LOG_SQ_ERROR, log_message);
|
||||
ScriptLog::Log(ScriptLogTypes::LOG_SQ_ERROR, fmt::format("Break: {}", message));
|
||||
|
||||
/* Inform script developer that their script has been paused and
|
||||
* needs manual action to continue. */
|
||||
ShowAIDebugWindow(ScriptObject::GetRootCompany());
|
||||
ShowScriptDebugWindow(ScriptObject::GetRootCompany());
|
||||
|
||||
if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) {
|
||||
ScriptObject::Command<CMD_PAUSE>::Do(PM_PAUSED_NORMAL, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void ScriptController::Print(bool error_msg, const char *message)
|
||||
/* static */ void ScriptController::Print(bool error_msg, const std::string &message)
|
||||
{
|
||||
ScriptLog::Log(error_msg ? ScriptLog::LOG_SQ_ERROR : ScriptLog::LOG_SQ_INFO, message);
|
||||
ScriptLog::Log(error_msg ? ScriptLogTypes::LOG_SQ_ERROR : ScriptLogTypes::LOG_SQ_INFO, message);
|
||||
}
|
||||
|
||||
ScriptController::ScriptController(CompanyID company) :
|
||||
@@ -76,16 +74,6 @@ ScriptController::ScriptController(CompanyID company) :
|
||||
ScriptObject::SetCompany(company);
|
||||
}
|
||||
|
||||
ScriptController::~ScriptController()
|
||||
{
|
||||
for (const auto &item : this->loaded_library) {
|
||||
free(item.second);
|
||||
free(item.first);
|
||||
}
|
||||
|
||||
this->loaded_library.clear();
|
||||
}
|
||||
|
||||
/* static */ uint ScriptController::GetTick()
|
||||
{
|
||||
return ScriptObject::GetActiveInstance()->GetController()->ticks;
|
||||
@@ -96,7 +84,7 @@ ScriptController::~ScriptController()
|
||||
return ScriptObject::GetActiveInstance()->GetOpsTillSuspend();
|
||||
}
|
||||
|
||||
/* static */ int ScriptController::GetSetting(const char *name)
|
||||
/* static */ int ScriptController::GetSetting(const std::string &name)
|
||||
{
|
||||
return ScriptObject::GetActiveInstance()->GetSetting(name);
|
||||
}
|
||||
@@ -106,7 +94,7 @@ ScriptController::~ScriptController()
|
||||
return _openttd_newgrf_version;
|
||||
}
|
||||
|
||||
/* static */ HSQOBJECT ScriptController::Import(const char *library, const char *class_name, int version)
|
||||
/* static */ HSQOBJECT ScriptController::Import(const std::string &library, const std::string &class_name, int version)
|
||||
{
|
||||
ScriptController *controller = ScriptObject::GetActiveInstance()->GetController();
|
||||
Squirrel *engine = ScriptObject::GetActiveInstance()->engine;
|
||||
@@ -114,30 +102,26 @@ ScriptController::~ScriptController()
|
||||
|
||||
ScriptInfo *lib = ScriptObject::GetActiveInstance()->FindLibrary(library, version);
|
||||
if (lib == nullptr) {
|
||||
char error[1024];
|
||||
seprintf(error, lastof(error), "couldn't find library '%s' with version %d", library, version);
|
||||
throw sq_throwerror(vm, error);
|
||||
throw sq_throwerror(vm, fmt::format("couldn't find library '{}' with version {}", library, 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);
|
||||
std::string library_name = fmt::format("{}.{}", library, version);
|
||||
|
||||
/* Get the current table/class we belong to */
|
||||
HSQOBJECT parent;
|
||||
sq_getstackobj(vm, 1, &parent);
|
||||
|
||||
char fake_class[1024];
|
||||
std::string fake_class;
|
||||
|
||||
LoadedLibraryList::iterator it = controller->loaded_library.find(library_name);
|
||||
if (it != controller->loaded_library.end()) {
|
||||
strecpy(fake_class, (*it).second, lastof(fake_class));
|
||||
fake_class = (*it).second;
|
||||
} else {
|
||||
int next_number = ++controller->loaded_library_count;
|
||||
|
||||
/* Create a new fake internal name */
|
||||
seprintf(fake_class, lastof(fake_class), "_internalNA%d", next_number);
|
||||
fake_class = fmt::format("_internalNA{}", next_number);
|
||||
|
||||
/* Load the library in a 'fake' namespace, so we can link it to the name the user requested */
|
||||
sq_pushroottable(vm);
|
||||
@@ -145,15 +129,13 @@ ScriptController::~ScriptController()
|
||||
sq_newclass(vm, SQFalse);
|
||||
/* Load the library */
|
||||
if (!engine->LoadScript(vm, lib->GetMainScript(), false)) {
|
||||
char error[1024];
|
||||
seprintf(error, lastof(error), "there was a compile error when importing '%s' version %d", library, version);
|
||||
throw sq_throwerror(vm, error);
|
||||
throw sq_throwerror(vm, fmt::format("there was a compile error when importing '{}' version {}", library, version));
|
||||
}
|
||||
/* Create the fake class */
|
||||
sq_newslot(vm, -3, SQFalse);
|
||||
sq_pop(vm, 1);
|
||||
|
||||
controller->loaded_library[stredup(library_name)] = stredup(fake_class);
|
||||
controller->loaded_library[library_name] = fake_class;
|
||||
}
|
||||
|
||||
/* Find the real class inside the fake class (like 'sets.Vector') */
|
||||
@@ -164,15 +146,13 @@ ScriptController::~ScriptController()
|
||||
}
|
||||
sq_pushstring(vm, lib->GetInstanceName(), -1);
|
||||
if (SQ_FAILED(sq_get(vm, -2))) {
|
||||
char error[1024];
|
||||
seprintf(error, lastof(error), "unable to find class '%s' in the library '%s' version %d", lib->GetInstanceName(), library, version);
|
||||
throw sq_throwerror(vm, error);
|
||||
throw sq_throwerror(vm, fmt::format("unable to find class '{}' in the library '{}' version {}", lib->GetInstanceName(), library, version));
|
||||
}
|
||||
HSQOBJECT obj;
|
||||
sq_getstackobj(vm, -1, &obj);
|
||||
sq_pop(vm, 3);
|
||||
|
||||
if (StrEmpty(class_name)) return obj;
|
||||
if (class_name.empty()) return obj;
|
||||
|
||||
/* Now link the name the user wanted to our 'fake' class */
|
||||
sq_pushobject(vm, parent);
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
#define SCRIPT_CONTROLLER_HPP
|
||||
|
||||
#include "script_types.hpp"
|
||||
#include "../../core/string_compare_type.hpp"
|
||||
#include <map>
|
||||
|
||||
/**
|
||||
* The Controller, the class each Script should extend. It creates the Script,
|
||||
@@ -48,17 +46,14 @@ class ScriptController {
|
||||
friend class ScriptInstance;
|
||||
|
||||
public:
|
||||
#ifndef DOXYGEN_API
|
||||
/**
|
||||
* Initializer of the ScriptController.
|
||||
* @param company The company this Script is normally serving.
|
||||
*/
|
||||
ScriptController(CompanyID company);
|
||||
|
||||
/**
|
||||
* Destructor of the ScriptController.
|
||||
*/
|
||||
~ScriptController();
|
||||
|
||||
#else
|
||||
/**
|
||||
* This function is called to start your script. Your script starts here. If you
|
||||
* return from this function, your script dies, so make sure that doesn't
|
||||
@@ -67,7 +62,6 @@ public:
|
||||
*/
|
||||
void Start();
|
||||
|
||||
#ifdef DOXYGEN_API
|
||||
/**
|
||||
* Save the state of the script.
|
||||
*
|
||||
@@ -130,7 +124,7 @@ public:
|
||||
* @param name The name of the setting.
|
||||
* @return the value for the setting, or -1 if the setting is not known.
|
||||
*/
|
||||
static int GetSetting(const char *name);
|
||||
static int GetSetting(const std::string &name);
|
||||
|
||||
/**
|
||||
* Get the OpenTTD version of this executable. The version is formatted
|
||||
@@ -186,7 +180,7 @@ public:
|
||||
* @note gui.ai_developer_tools setting must be enabled or the break is
|
||||
* ignored.
|
||||
*/
|
||||
static void Break(const char* message);
|
||||
static void Break(const std::string &message);
|
||||
|
||||
/**
|
||||
* When Squirrel triggers a print, this function is called.
|
||||
@@ -195,7 +189,7 @@ public:
|
||||
* @param message The message Squirrel logged.
|
||||
* @note Use ScriptLog.Info/Warning/Error instead of 'print'.
|
||||
*/
|
||||
static void Print(bool error_msg, const char *message);
|
||||
static void Print(bool error_msg, const std::string &message);
|
||||
|
||||
/**
|
||||
* Import a library.
|
||||
@@ -206,10 +200,10 @@ public:
|
||||
* @return The loaded library object. If class_name is set, it is also available (under the scope of the import) under that name.
|
||||
* @note This command can be called from the global space, and does not need an instance.
|
||||
*/
|
||||
static HSQOBJECT Import(const char *library, const char *class_name, int version);
|
||||
static HSQOBJECT Import(const std::string &library, const std::string &class_name, int version);
|
||||
|
||||
private:
|
||||
typedef std::map<const char *, const char *, StringCompare> LoadedLibraryList; ///< The type for loaded libraries.
|
||||
typedef std::map<std::string, std::string, CaseInsensitiveComparator> LoadedLibraryList; ///< The type for loaded libraries.
|
||||
|
||||
uint ticks; ///< The amount of ticks we're sleeping.
|
||||
LoadedLibraryList loaded_library; ///< The libraries we loaded.
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
|
||||
#include "../../stdafx.h"
|
||||
#include "script_date.hpp"
|
||||
#include "../../date_func.h"
|
||||
#include "script_timemode.hpp"
|
||||
#include "../../timer/timer_game_calendar.h"
|
||||
#include "../../timer/timer_game_economy.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
@@ -22,46 +24,62 @@
|
||||
|
||||
/* static */ ScriptDate::Date ScriptDate::GetCurrentDate()
|
||||
{
|
||||
return (ScriptDate::Date)_date;
|
||||
if (ScriptTimeMode::IsCalendarMode()) return (ScriptDate::Date)TimerGameCalendar::date.base();
|
||||
|
||||
return (ScriptDate::Date)TimerGameEconomy::date.base();
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptDate::GetYear(ScriptDate::Date date)
|
||||
/* static */ SQInteger ScriptDate::GetYear(ScriptDate::Date date)
|
||||
{
|
||||
if (date < 0) return DATE_INVALID;
|
||||
|
||||
::YearMonthDay ymd;
|
||||
::ConvertDateToYMD(date, &ymd);
|
||||
return ymd.year;
|
||||
if (ScriptTimeMode::IsCalendarMode()) {
|
||||
::TimerGameCalendar::YearMonthDay ymd = ::TimerGameCalendar::ConvertDateToYMD(date);
|
||||
return ymd.year.base();
|
||||
}
|
||||
|
||||
::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(date);
|
||||
return ymd.year.base();
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptDate::GetMonth(ScriptDate::Date date)
|
||||
/* static */ SQInteger ScriptDate::GetMonth(ScriptDate::Date date)
|
||||
{
|
||||
if (date < 0) return DATE_INVALID;
|
||||
|
||||
::YearMonthDay ymd;
|
||||
::ConvertDateToYMD(date, &ymd);
|
||||
if (ScriptTimeMode::IsCalendarMode()) {
|
||||
::TimerGameCalendar::YearMonthDay ymd = ::TimerGameCalendar::ConvertDateToYMD(date);
|
||||
return ymd.month + 1;
|
||||
}
|
||||
|
||||
::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(date);
|
||||
return ymd.month + 1;
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptDate::GetDayOfMonth(ScriptDate::Date date)
|
||||
/* static */ SQInteger ScriptDate::GetDayOfMonth(ScriptDate::Date date)
|
||||
{
|
||||
if (date < 0) return DATE_INVALID;
|
||||
|
||||
::YearMonthDay ymd;
|
||||
::ConvertDateToYMD(date, &ymd);
|
||||
if (ScriptTimeMode::IsCalendarMode()) {
|
||||
::TimerGameCalendar::YearMonthDay ymd = ::TimerGameCalendar::ConvertDateToYMD(date);
|
||||
return ymd.day;
|
||||
}
|
||||
|
||||
::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(date);
|
||||
return ymd.day;
|
||||
}
|
||||
|
||||
/* static */ ScriptDate::Date ScriptDate::GetDate(int32 year, int32 month, int32 day_of_month)
|
||||
/* static */ ScriptDate::Date ScriptDate::GetDate(SQInteger year, SQInteger month, SQInteger day_of_month)
|
||||
{
|
||||
if (month < 1 || month > 12) return DATE_INVALID;
|
||||
if (day_of_month < 1 || day_of_month > 31) return DATE_INVALID;
|
||||
if (year < 0 || year > MAX_YEAR) return DATE_INVALID;
|
||||
if (year < 0 || year > CalendarTime::MAX_YEAR) return DATE_INVALID;
|
||||
|
||||
return (ScriptDate::Date)::ConvertYMDToDate(year, month - 1, day_of_month);
|
||||
if (ScriptTimeMode::IsCalendarMode()) return (ScriptDate::Date)::TimerGameCalendar::ConvertYMDToDate(year, month - 1, day_of_month).base();
|
||||
|
||||
return (ScriptDate::Date)::TimerGameEconomy::ConvertYMDToDate(year, month - 1, day_of_month).base();
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptDate::GetSystemTime()
|
||||
/* static */ SQInteger ScriptDate::GetSystemTime()
|
||||
{
|
||||
time_t t;
|
||||
time(&t);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#define SCRIPT_DATE_HPP
|
||||
|
||||
#include "script_object.hpp"
|
||||
#include "../../date_type.h"
|
||||
#include "../../timer/timer_game_calendar.h"
|
||||
|
||||
/**
|
||||
* Class that handles all date related (calculation) functions.
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
* compose valid date values for a known year, month and day.
|
||||
*/
|
||||
enum Date {
|
||||
DATE_INVALID = ::INVALID_DATE, ///< A value representing an invalid date.
|
||||
DATE_INVALID = ::CalendarTime::INVALID_DATE.base(), ///< A value representing an invalid date.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -55,21 +55,21 @@ public:
|
||||
* @param date The date to get the year of.
|
||||
* @return The year.
|
||||
*/
|
||||
static int32 GetYear(Date date);
|
||||
static SQInteger GetYear(Date date);
|
||||
|
||||
/**
|
||||
* Get the month of the given date.
|
||||
* @param date The date to get the month of.
|
||||
* @return The month.
|
||||
*/
|
||||
static int32 GetMonth(Date date);
|
||||
static SQInteger GetMonth(Date date);
|
||||
|
||||
/**
|
||||
* Get the day (of the month) of the given date.
|
||||
* @param date The date to get the day of.
|
||||
* @return The day.
|
||||
*/
|
||||
static int32 GetDayOfMonth(Date date);
|
||||
static SQInteger GetDayOfMonth(Date date);
|
||||
|
||||
/**
|
||||
* Get the date given a year, month and day of month.
|
||||
@@ -78,7 +78,7 @@ public:
|
||||
* @param day_of_month The day of month of the to-be determined date.
|
||||
* @return The date.
|
||||
*/
|
||||
static Date GetDate(int32 year, int32 month, int32 day_of_month);
|
||||
static Date GetDate(SQInteger year, SQInteger month, SQInteger day_of_month);
|
||||
|
||||
/**
|
||||
* Get the time of the host system.
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
* @api -ai
|
||||
* @note This uses the clock of the host system, which can skew or be set back. Use with caution.
|
||||
*/
|
||||
static int32 GetSystemTime();
|
||||
static SQInteger GetSystemTime();
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_DATE_HPP */
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
ScriptDepotList::ScriptDepotList(ScriptTile::TransportType transport_type)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid_Void();
|
||||
::TileType tile_type;
|
||||
switch (transport_type) {
|
||||
default: return;
|
||||
@@ -26,10 +27,12 @@ ScriptDepotList::ScriptDepotList(ScriptTile::TransportType transport_type)
|
||||
|
||||
case ScriptTile::TRANSPORT_AIR: {
|
||||
/* Hangars are not seen as real depots by the depot code. */
|
||||
bool is_deity = ScriptCompanyMode::IsDeity();
|
||||
CompanyID owner = ScriptObject::GetCompany();
|
||||
for (const Station *st : Station::Iterate()) {
|
||||
if (st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) {
|
||||
if (is_deity || st->owner == owner) {
|
||||
for (uint i = 0; i < st->airport.GetNumHangars(); i++) {
|
||||
this->AddItem(st->airport.GetHangarTile(i));
|
||||
this->AddItem(st->airport.GetHangarTile(i).base());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,7 +41,9 @@ ScriptDepotList::ScriptDepotList(ScriptTile::TransportType transport_type)
|
||||
}
|
||||
|
||||
/* Handle 'standard' depots. */
|
||||
bool is_deity = ScriptCompanyMode::IsDeity();
|
||||
CompanyID owner = ScriptObject::GetCompany();
|
||||
for (const Depot *depot : Depot::Iterate()) {
|
||||
if ((::GetTileOwner(depot->xy) == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && ::IsTileType(depot->xy, tile_type)) this->AddItem(depot->xy);
|
||||
if ((is_deity || ::GetTileOwner(depot->xy) == owner) && ::IsTileType(depot->xy, tile_type)) this->AddItem(depot->xy.base());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,30 +18,33 @@
|
||||
#include "../../engine_func.h"
|
||||
#include "../../articulated_vehicles.h"
|
||||
#include "../../engine_cmd.h"
|
||||
#include "../../timer/timer_game_calendar.h"
|
||||
#include "table/strings.h"
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
/* static */ bool ScriptEngine::IsValidEngine(EngineID engine_id)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
const Engine *e = ::Engine::GetIfValid(engine_id);
|
||||
if (e == nullptr || !e->IsEnabled()) return false;
|
||||
|
||||
/* AIs have only access to engines they can purchase or still have in use.
|
||||
* Deity has access to all engined that will be or were available ever. */
|
||||
CompanyID company = ScriptObject::GetCompany();
|
||||
return company == OWNER_DEITY || ::IsEngineBuildable(engine_id, e->type, company) || ::Company::Get(company)->group_all[e->type].num_engines[engine_id] > 0;
|
||||
return ScriptCompanyMode::IsDeity() || ::IsEngineBuildable(engine_id, e->type, company) || ::Company::Get(company)->group_all[e->type].GetNumEngines(engine_id) > 0;
|
||||
}
|
||||
|
||||
/* static */ bool ScriptEngine::IsBuildable(EngineID engine_id)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
const Engine *e = ::Engine::GetIfValid(engine_id);
|
||||
return e != nullptr && ::IsEngineBuildable(engine_id, e->type, ScriptObject::GetCompany());
|
||||
}
|
||||
|
||||
/* static */ char *ScriptEngine::GetName(EngineID engine_id)
|
||||
/* static */ std::optional<std::string> ScriptEngine::GetName(EngineID engine_id)
|
||||
{
|
||||
if (!IsValidEngine(engine_id)) return nullptr;
|
||||
if (!IsValidEngine(engine_id)) return std::nullopt;
|
||||
|
||||
::SetDParam(0, engine_id);
|
||||
return GetString(STR_ENGINE_NAME);
|
||||
@@ -49,20 +52,14 @@
|
||||
|
||||
/* static */ CargoID ScriptEngine::GetCargoType(EngineID engine_id)
|
||||
{
|
||||
if (!IsValidEngine(engine_id)) return CT_INVALID;
|
||||
if (!IsValidEngine(engine_id)) return INVALID_CARGO;
|
||||
|
||||
CargoArray cap = ::GetCapacityOfArticulatedParts(engine_id);
|
||||
|
||||
CargoID most_cargo = CT_INVALID;
|
||||
uint amount = 0;
|
||||
for (CargoID cid = 0; cid < NUM_CARGO; cid++) {
|
||||
if (cap[cid] > amount) {
|
||||
amount = cap[cid];
|
||||
most_cargo = cid;
|
||||
}
|
||||
}
|
||||
auto it = std::max_element(std::cbegin(cap), std::cend(cap));
|
||||
if (*it == 0) return INVALID_CARGO;
|
||||
|
||||
return most_cargo;
|
||||
return CargoID(std::distance(std::cbegin(cap), it));
|
||||
}
|
||||
|
||||
/* static */ bool ScriptEngine::CanRefitCargo(EngineID engine_id, CargoID cargo_id)
|
||||
@@ -83,7 +80,7 @@
|
||||
}
|
||||
|
||||
|
||||
/* static */ int32 ScriptEngine::GetCapacity(EngineID engine_id)
|
||||
/* static */ SQInteger ScriptEngine::GetCapacity(EngineID engine_id)
|
||||
{
|
||||
if (!IsValidEngine(engine_id)) return -1;
|
||||
|
||||
@@ -92,9 +89,8 @@
|
||||
case VEH_ROAD:
|
||||
case VEH_TRAIN: {
|
||||
CargoArray capacities = GetCapacityOfArticulatedParts(engine_id);
|
||||
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
||||
if (capacities[c] == 0) continue;
|
||||
return capacities[c];
|
||||
for (uint &cap : capacities) {
|
||||
if (cap != 0) return cap;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -107,7 +103,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptEngine::GetReliability(EngineID engine_id)
|
||||
/* static */ SQInteger ScriptEngine::GetReliability(EngineID engine_id)
|
||||
{
|
||||
if (!IsValidEngine(engine_id)) return -1;
|
||||
if (GetVehicleType(engine_id) == ScriptVehicle::VT_RAIL && IsWagon(engine_id)) return -1;
|
||||
@@ -115,12 +111,12 @@
|
||||
return ::ToPercent16(::Engine::Get(engine_id)->reliability);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptEngine::GetMaxSpeed(EngineID engine_id)
|
||||
/* static */ SQInteger ScriptEngine::GetMaxSpeed(EngineID engine_id)
|
||||
{
|
||||
if (!IsValidEngine(engine_id)) return -1;
|
||||
|
||||
const Engine *e = ::Engine::Get(engine_id);
|
||||
int32 max_speed = e->GetDisplayMaxSpeed(); // km-ish/h
|
||||
uint max_speed = e->GetDisplayMaxSpeed(); // km-ish/h
|
||||
if (e->type == VEH_AIRCRAFT) max_speed /= _settings_game.vehicle.plane_speed;
|
||||
return max_speed;
|
||||
}
|
||||
@@ -132,12 +128,12 @@
|
||||
return ::Engine::Get(engine_id)->GetCost();
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptEngine::GetMaxAge(EngineID engine_id)
|
||||
/* static */ SQInteger ScriptEngine::GetMaxAge(EngineID engine_id)
|
||||
{
|
||||
if (!IsValidEngine(engine_id)) return -1;
|
||||
if (GetVehicleType(engine_id) == ScriptVehicle::VT_RAIL && IsWagon(engine_id)) return -1;
|
||||
|
||||
return ::Engine::Get(engine_id)->GetLifeLengthInDays();
|
||||
return ::Engine::Get(engine_id)->GetLifeLengthInDays().base();
|
||||
}
|
||||
|
||||
/* static */ Money ScriptEngine::GetRunningCost(EngineID engine_id)
|
||||
@@ -147,7 +143,7 @@
|
||||
return ::Engine::Get(engine_id)->GetRunningCost();
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptEngine::GetPower(EngineID engine_id)
|
||||
/* static */ SQInteger ScriptEngine::GetPower(EngineID engine_id)
|
||||
{
|
||||
if (!IsValidEngine(engine_id)) return -1;
|
||||
if (GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL && GetVehicleType(engine_id) != ScriptVehicle::VT_ROAD) return -1;
|
||||
@@ -156,7 +152,7 @@
|
||||
return ::Engine::Get(engine_id)->GetPower();
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptEngine::GetWeight(EngineID engine_id)
|
||||
/* static */ SQInteger ScriptEngine::GetWeight(EngineID engine_id)
|
||||
{
|
||||
if (!IsValidEngine(engine_id)) return -1;
|
||||
if (GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL && GetVehicleType(engine_id) != ScriptVehicle::VT_ROAD) return -1;
|
||||
@@ -164,20 +160,20 @@
|
||||
return ::Engine::Get(engine_id)->GetDisplayWeight();
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptEngine::GetMaxTractiveEffort(EngineID engine_id)
|
||||
/* static */ SQInteger ScriptEngine::GetMaxTractiveEffort(EngineID engine_id)
|
||||
{
|
||||
if (!IsValidEngine(engine_id)) return -1;
|
||||
if (GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL && GetVehicleType(engine_id) != ScriptVehicle::VT_ROAD) return -1;
|
||||
if (IsWagon(engine_id)) return -1;
|
||||
|
||||
return ::Engine::Get(engine_id)->GetDisplayMaxTractiveEffort();
|
||||
return ::Engine::Get(engine_id)->GetDisplayMaxTractiveEffort() / 1000;
|
||||
}
|
||||
|
||||
/* static */ ScriptDate::Date ScriptEngine::GetDesignDate(EngineID engine_id)
|
||||
{
|
||||
if (!IsValidEngine(engine_id)) return ScriptDate::DATE_INVALID;
|
||||
|
||||
return (ScriptDate::Date)::Engine::Get(engine_id)->intro_date;
|
||||
return (ScriptDate::Date)::Engine::Get(engine_id)->intro_date.base();
|
||||
}
|
||||
|
||||
/* static */ ScriptVehicle::VehicleType ScriptEngine::GetVehicleType(EngineID engine_id)
|
||||
@@ -265,24 +261,19 @@
|
||||
return (ScriptAirport::PlaneType)::AircraftVehInfo(engine_id)->subtype;
|
||||
}
|
||||
|
||||
/* static */ uint ScriptEngine::GetMaximumOrderDistance(EngineID engine_id)
|
||||
/* static */ SQInteger ScriptEngine::GetMaximumOrderDistance(EngineID engine_id)
|
||||
{
|
||||
if (!IsValidEngine(engine_id)) return 0;
|
||||
if (GetVehicleType(engine_id) != ScriptVehicle::VT_AIR) return 0;
|
||||
|
||||
switch (GetVehicleType(engine_id)) {
|
||||
case ScriptVehicle::VT_AIR:
|
||||
return ::Engine::Get(engine_id)->GetRange() * ::Engine::Get(engine_id)->GetRange();
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return (SQInteger)::Engine::Get(engine_id)->GetRange() * ::Engine::Get(engine_id)->GetRange();
|
||||
}
|
||||
|
||||
/* static */ bool ScriptEngine::EnableForCompany(EngineID engine_id, ScriptCompany::CompanyID company)
|
||||
{
|
||||
company = ScriptCompany::ResolveCompanyID(company);
|
||||
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, IsValidEngine(engine_id));
|
||||
EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID);
|
||||
|
||||
@@ -293,7 +284,7 @@
|
||||
{
|
||||
company = ScriptCompany::ResolveCompanyID(company);
|
||||
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, IsValidEngine(engine_id));
|
||||
EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
/**
|
||||
* Checks whether the given engine type is valid.
|
||||
* An engine is valid for a company if it has at least one vehicle of this engine or it's currently buildable.
|
||||
* @game Outside ScriptCompanyMode scope the function reports all engines valid, which were or will be available at some point.
|
||||
* @game Outside ScriptCompanyMode scope (ScriptCompanyMode::IsDeity) the function reports all engines valid, which were or will be available at some point.
|
||||
* @param engine_id The engine to check.
|
||||
* @return True if and only if the engine type is valid.
|
||||
*/
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
|
||||
/**
|
||||
* Checks whether the given engine type is buildable for a company.
|
||||
* @game Outside ScriptCompanyMode scope the function checks whether the engine is currently buildable by all companies (no exclusive preview).
|
||||
* @game Outside ScriptCompanyMode scope (ScriptCompanyMode::IsDeity) the function checks whether the engine is currently buildable by all companies (no exclusive preview).
|
||||
* @param engine_id The engine to check.
|
||||
* @return True if and only if the engine type is buildable.
|
||||
*/
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
* @pre IsValidEngine(engine_id).
|
||||
* @return The name the engine has.
|
||||
*/
|
||||
static char *GetName(EngineID engine_id);
|
||||
static std::optional<std::string> GetName(EngineID engine_id);
|
||||
|
||||
/**
|
||||
* Get the cargo-type of an engine. In case it can transport multiple cargoes, it
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
* @pre IsValidEngine(engine_id).
|
||||
* @return The capacity of the engine.
|
||||
*/
|
||||
static int32 GetCapacity(EngineID engine_id);
|
||||
static SQInteger GetCapacity(EngineID engine_id);
|
||||
|
||||
/**
|
||||
* Get the reliability of an engine. The value is between 0 and 100, where
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
* @pre GetVehicleType(engine_id) != ScriptVehicle::VT_TRAIN || !IsWagon(engine_id).
|
||||
* @return The reliability the engine has.
|
||||
*/
|
||||
static int32 GetReliability(EngineID engine_id);
|
||||
static SQInteger GetReliability(EngineID engine_id);
|
||||
|
||||
/**
|
||||
* Get the maximum speed of an engine.
|
||||
@@ -111,7 +111,7 @@ public:
|
||||
* This is mph / 1.6, which is roughly km/h.
|
||||
* To get km/h multiply this number by 1.00584.
|
||||
*/
|
||||
static int32 GetMaxSpeed(EngineID engine_id);
|
||||
static SQInteger GetMaxSpeed(EngineID engine_id);
|
||||
|
||||
/**
|
||||
* Get the new cost of an engine.
|
||||
@@ -128,7 +128,7 @@ public:
|
||||
* @returns The maximum age of a new engine in days.
|
||||
* @note Age is in days; divide by 366 to get per year.
|
||||
*/
|
||||
static int32 GetMaxAge(EngineID engine_id);
|
||||
static SQInteger GetMaxAge(EngineID engine_id);
|
||||
|
||||
/**
|
||||
* Get the running cost of an engine.
|
||||
@@ -146,7 +146,7 @@ public:
|
||||
* @pre (GetVehicleType(engine_id) == ScriptVehicle::VT_RAIL || GetVehicleType(engine_id) == ScriptVehicle::VT_ROAD) && !IsWagon(engine_id).
|
||||
* @return The power of the engine in hp.
|
||||
*/
|
||||
static int32 GetPower(EngineID engine_id);
|
||||
static SQInteger GetPower(EngineID engine_id);
|
||||
|
||||
/**
|
||||
* Get the weight of an engine.
|
||||
@@ -155,7 +155,7 @@ public:
|
||||
* @pre (GetVehicleType(engine_id) == ScriptVehicle::VT_RAIL || GetVehicleType(engine_id) == ScriptVehicle::VT_ROAD).
|
||||
* @return The weight of the engine in metric tons.
|
||||
*/
|
||||
static int32 GetWeight(EngineID engine_id);
|
||||
static SQInteger GetWeight(EngineID engine_id);
|
||||
|
||||
/**
|
||||
* Get the maximum tractive effort of an engine.
|
||||
@@ -164,7 +164,7 @@ public:
|
||||
* @pre (GetVehicleType(engine_id) == ScriptVehicle::VT_RAIL || GetVehicleType(engine_id) == ScriptVehicle::VT_ROAD) && !IsWagon(engine_id).
|
||||
* @return The maximum tractive effort of the engine in kN.
|
||||
*/
|
||||
static int32 GetMaxTractiveEffort(EngineID engine_id);
|
||||
static SQInteger GetMaxTractiveEffort(EngineID engine_id);
|
||||
|
||||
/**
|
||||
* Get the date this engine was designed.
|
||||
@@ -286,7 +286,7 @@ public:
|
||||
* not be compared with map distances
|
||||
* @see ScriptOrder::GetOrderDistance
|
||||
*/
|
||||
static uint GetMaximumOrderDistance(EngineID engine_id);
|
||||
static SQInteger GetMaximumOrderDistance(EngineID engine_id);
|
||||
|
||||
/**
|
||||
* Allows a company to use an engine before its intro date or after retirement.
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
|
||||
ScriptEngineList::ScriptEngineList(ScriptVehicle::VehicleType vehicle_type)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid_Void();
|
||||
bool is_deity = ScriptCompanyMode::IsDeity();
|
||||
CompanyID owner = ScriptObject::GetCompany();
|
||||
for (const Engine *e : Engine::IterateType((::VehicleType)vehicle_type)) {
|
||||
if (ScriptObject::GetCompany() == OWNER_DEITY || HasBit(e->company_avail, ScriptObject::GetCompany())) this->AddItem(e->index);
|
||||
if (is_deity || HasBit(e->company_avail, owner)) this->AddItem(e->index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@ ScriptError::ScriptErrorMapString ScriptError::error_map_string = ScriptError::S
|
||||
return ScriptObject::GetLastError();
|
||||
}
|
||||
|
||||
/* static */ char *ScriptError::GetLastErrorString()
|
||||
/* static */ std::optional<std::string> ScriptError::GetLastErrorString()
|
||||
{
|
||||
return stredup((*error_map_string.find(ScriptError::GetLastError())).second);
|
||||
return (*error_map_string.find(ScriptError::GetLastError())).second;
|
||||
}
|
||||
|
||||
/* static */ ScriptErrorType ScriptError::StringToError(StringID internal_string_id)
|
||||
@@ -38,7 +38,7 @@ ScriptError::ScriptErrorMapString ScriptError::error_map_string = ScriptError::S
|
||||
|
||||
case TEXT_TAB_SPECIAL:
|
||||
if (index < 0xE4) break; // Player name
|
||||
FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
|
||||
case TEXT_TAB_TOWN:
|
||||
if (index < 0xC0) break; // Town name
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#define SCRIPT_ERROR_HPP
|
||||
|
||||
#include "script_object.hpp"
|
||||
#include <map>
|
||||
#include "script_companymode.hpp"
|
||||
|
||||
/**
|
||||
* Helper to write precondition enforcers for the script API in an abbreviated manner.
|
||||
@@ -42,15 +42,51 @@
|
||||
* @param string The string that is checked.
|
||||
*/
|
||||
#define EnforcePreconditionEncodedText(returnval, string) \
|
||||
if ((string) == nullptr) { \
|
||||
ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_TOO_MANY_PARAMETERS); \
|
||||
return returnval; \
|
||||
} \
|
||||
if (StrEmpty(string)) { \
|
||||
if (string.empty()) { \
|
||||
ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_FAILED); \
|
||||
return returnval; \
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to enforce the precondition that the company mode is valid.
|
||||
* @param returnval The value to return on failure.
|
||||
*/
|
||||
#define EnforceCompanyModeValid(returnval) \
|
||||
EnforcePreconditionCustomError(returnval, ScriptCompanyMode::IsValid(), ScriptError::ERR_PRECONDITION_INVALID_COMPANY)
|
||||
|
||||
/**
|
||||
* Helper to enforce the precondition that the company mode is valid.
|
||||
*/
|
||||
#define EnforceCompanyModeValid_Void() \
|
||||
if (!ScriptCompanyMode::IsValid()) { \
|
||||
ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY); \
|
||||
return; \
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to enforce the precondition that we are in a deity mode.
|
||||
* @param returnval The value to return on failure.
|
||||
*/
|
||||
#define EnforceDeityMode(returnval) \
|
||||
EnforcePreconditionCustomError(returnval, ScriptCompanyMode::IsDeity(), ScriptError::ERR_PRECONDITION_INVALID_COMPANY)
|
||||
|
||||
/**
|
||||
* Helper to enforce the precondition that the company mode is valid or that we are a deity.
|
||||
* @param returnval The value to return on failure.
|
||||
*/
|
||||
#define EnforceDeityOrCompanyModeValid(returnval) \
|
||||
EnforcePreconditionCustomError(returnval, ScriptCompanyMode::IsDeity() || ScriptCompanyMode::IsValid(), ScriptError::ERR_PRECONDITION_INVALID_COMPANY)
|
||||
|
||||
/**
|
||||
* Helper to enforce the precondition that the company mode is valid or that we are a deity.
|
||||
*/
|
||||
#define EnforceDeityOrCompanyModeValid_Void() \
|
||||
if (!(ScriptCompanyMode::IsDeity() || ScriptCompanyMode::IsValid())) { \
|
||||
ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY); \
|
||||
return; \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class that handles all error related functions.
|
||||
* @api ai game
|
||||
@@ -94,8 +130,6 @@ public:
|
||||
ERR_PRECONDITION_FAILED, // []
|
||||
/** A string supplied was too long */
|
||||
ERR_PRECONDITION_STRING_TOO_LONG, // []
|
||||
/** A string had too many parameters */
|
||||
ERR_PRECONDITION_TOO_MANY_PARAMETERS, // []
|
||||
/** The company you use is invalid */
|
||||
ERR_PRECONDITION_INVALID_COMPANY, // []
|
||||
/** An error returned by a NewGRF. No possibility to get the exact error in an script readable format */
|
||||
@@ -158,7 +192,7 @@ public:
|
||||
* Get the last error in string format (for human readability).
|
||||
* @return An ErrorMessage enum item, as string.
|
||||
*/
|
||||
static char *GetLastErrorString();
|
||||
static std::optional<std::string> GetLastErrorString();
|
||||
|
||||
/**
|
||||
* Get the error based on the OpenTTD StringID.
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "../../string_func.h"
|
||||
#include "../../economy_cmd.h"
|
||||
#include "../../engine_cmd.h"
|
||||
#include "../../3rdparty/nlohmann/json.hpp"
|
||||
#include "table/strings.h"
|
||||
|
||||
#include "../../safeguards.h"
|
||||
@@ -28,9 +29,9 @@ bool ScriptEventEnginePreview::IsEngineValid() const
|
||||
return e != nullptr && e->IsEnabled();
|
||||
}
|
||||
|
||||
char *ScriptEventEnginePreview::GetName()
|
||||
std::optional<std::string> ScriptEventEnginePreview::GetName()
|
||||
{
|
||||
if (!this->IsEngineValid()) return nullptr;
|
||||
if (!this->IsEngineValid()) return std::nullopt;
|
||||
|
||||
::SetDParam(0, this->engine);
|
||||
return GetString(STR_ENGINE_NAME);
|
||||
@@ -38,22 +39,16 @@ char *ScriptEventEnginePreview::GetName()
|
||||
|
||||
CargoID ScriptEventEnginePreview::GetCargoType()
|
||||
{
|
||||
if (!this->IsEngineValid()) return CT_INVALID;
|
||||
if (!this->IsEngineValid()) return INVALID_CARGO;
|
||||
CargoArray cap = ::GetCapacityOfArticulatedParts(this->engine);
|
||||
|
||||
CargoID most_cargo = CT_INVALID;
|
||||
uint amount = 0;
|
||||
for (CargoID cid = 0; cid < NUM_CARGO; cid++) {
|
||||
if (cap[cid] > amount) {
|
||||
amount = cap[cid];
|
||||
most_cargo = cid;
|
||||
}
|
||||
}
|
||||
auto it = std::max_element(std::cbegin(cap), std::cend(cap));
|
||||
if (*it == 0) return INVALID_CARGO;
|
||||
|
||||
return most_cargo;
|
||||
return CargoID(std::distance(std::cbegin(cap), it));
|
||||
}
|
||||
|
||||
int32 ScriptEventEnginePreview::GetCapacity()
|
||||
int32_t ScriptEventEnginePreview::GetCapacity()
|
||||
{
|
||||
if (!this->IsEngineValid()) return -1;
|
||||
const Engine *e = ::Engine::Get(this->engine);
|
||||
@@ -61,9 +56,8 @@ int32 ScriptEventEnginePreview::GetCapacity()
|
||||
case VEH_ROAD:
|
||||
case VEH_TRAIN: {
|
||||
CargoArray capacities = GetCapacityOfArticulatedParts(this->engine);
|
||||
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
||||
if (capacities[c] == 0) continue;
|
||||
return capacities[c];
|
||||
for (uint &cap : capacities) {
|
||||
if (cap != 0) return cap;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -76,11 +70,11 @@ int32 ScriptEventEnginePreview::GetCapacity()
|
||||
}
|
||||
}
|
||||
|
||||
int32 ScriptEventEnginePreview::GetMaxSpeed()
|
||||
int32_t ScriptEventEnginePreview::GetMaxSpeed()
|
||||
{
|
||||
if (!this->IsEngineValid()) return -1;
|
||||
const Engine *e = ::Engine::Get(this->engine);
|
||||
int32 max_speed = e->GetDisplayMaxSpeed(); // km-ish/h
|
||||
int32_t max_speed = e->GetDisplayMaxSpeed(); // km-ish/h
|
||||
if (e->type == VEH_AIRCRAFT) max_speed /= _settings_game.vehicle.plane_speed;
|
||||
return max_speed;
|
||||
}
|
||||
@@ -97,7 +91,7 @@ Money ScriptEventEnginePreview::GetRunningCost()
|
||||
return ::Engine::Get(this->engine)->GetRunningCost();
|
||||
}
|
||||
|
||||
int32 ScriptEventEnginePreview::GetVehicleType()
|
||||
int32_t ScriptEventEnginePreview::GetVehicleType()
|
||||
{
|
||||
if (!this->IsEngineValid()) return ScriptVehicle::VT_INVALID;
|
||||
switch (::Engine::Get(this->engine)->type) {
|
||||
@@ -111,13 +105,15 @@ int32 ScriptEventEnginePreview::GetVehicleType()
|
||||
|
||||
bool ScriptEventEnginePreview::AcceptPreview()
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
if (!this->IsEngineValid()) return false;
|
||||
return ScriptObject::Command<CMD_WANT_ENGINE_PREVIEW>::Do(this->engine);
|
||||
}
|
||||
|
||||
bool ScriptEventCompanyAskMerger::AcceptMerger()
|
||||
{
|
||||
return ScriptObject::Command<CMD_BUY_COMPANY>::Do((::CompanyID)this->owner);
|
||||
EnforceCompanyModeValid(false);
|
||||
return ScriptObject::Command<CMD_BUY_COMPANY>::Do((::CompanyID)this->owner, false);
|
||||
}
|
||||
|
||||
ScriptEventAdminPort::ScriptEventAdminPort(const std::string &json) :
|
||||
@@ -125,193 +121,89 @@ ScriptEventAdminPort::ScriptEventAdminPort(const std::string &json) :
|
||||
json(json)
|
||||
{
|
||||
}
|
||||
/**
|
||||
* Convert a JSON part fo Squirrel.
|
||||
* @param vm The VM used.
|
||||
* @param json The JSON part to convert to Squirrel.
|
||||
*/
|
||||
static bool ScriptEventAdminPortReadValue(HSQUIRRELVM vm, nlohmann::json &json)
|
||||
{
|
||||
switch (json.type()) {
|
||||
case nlohmann::json::value_t::null:
|
||||
sq_pushnull(vm);
|
||||
break;
|
||||
|
||||
#define SKIP_EMPTY(p) while (*(p) == ' ' || *(p) == '\n' || *(p) == '\r') (p)++;
|
||||
#define RETURN_ERROR(stack) { ScriptLog::Error("Received invalid JSON data from AdminPort."); if (stack != 0) sq_pop(vm, stack); return nullptr; }
|
||||
case nlohmann::json::value_t::boolean:
|
||||
sq_pushbool(vm, json.get<bool>() ? 1 : 0);
|
||||
break;
|
||||
|
||||
case nlohmann::json::value_t::string: {
|
||||
auto value = json.get<std::string>();
|
||||
sq_pushstring(vm, value.data(), value.size());
|
||||
break;
|
||||
}
|
||||
|
||||
case nlohmann::json::value_t::number_integer:
|
||||
case nlohmann::json::value_t::number_unsigned:
|
||||
sq_pushinteger(vm, json.get<int64_t>());
|
||||
break;
|
||||
|
||||
case nlohmann::json::value_t::object:
|
||||
sq_newtable(vm);
|
||||
|
||||
for (auto &[key, value] : json.items()) {
|
||||
sq_pushstring(vm, key.data(), key.size());
|
||||
|
||||
if (!ScriptEventAdminPortReadValue(vm, value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sq_rawset(vm, -3);
|
||||
}
|
||||
break;
|
||||
|
||||
case nlohmann::json::value_t::array:
|
||||
sq_newarray(vm, 0);
|
||||
|
||||
for (auto &value : json) {
|
||||
if (!ScriptEventAdminPortReadValue(vm, value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sq_arrayappend(vm, -2);
|
||||
}
|
||||
break;
|
||||
|
||||
/* These types are not supported by Squirrel. */
|
||||
case nlohmann::json::value_t::number_float:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm)
|
||||
{
|
||||
const char *p = this->json.c_str();
|
||||
auto json = nlohmann::json::parse(this->json, nullptr, false);
|
||||
|
||||
if (!json.is_object()) {
|
||||
ScriptLog::Error("The root element in the JSON data from AdminPort has to be an object.");
|
||||
|
||||
sq_pushnull(vm);
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto top = sq_gettop(vm);
|
||||
if (!ScriptEventAdminPortReadValue(vm, json)) {
|
||||
/* Rewind the stack, removing anything that might be left on top. */
|
||||
sq_settop(vm, top);
|
||||
|
||||
ScriptLog::Error("Received invalid JSON data from AdminPort.");
|
||||
|
||||
if (this->ReadTable(vm, p) == nullptr) {
|
||||
sq_pushnull(vm);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *ScriptEventAdminPort::ReadString(HSQUIRRELVM vm, const char *p)
|
||||
{
|
||||
const char *value = p;
|
||||
|
||||
bool escape = false;
|
||||
for (;;) {
|
||||
if (*p == '\\') {
|
||||
escape = true;
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
if (*p == '"' && escape) {
|
||||
escape = false;
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
escape = false;
|
||||
|
||||
if (*p == '"') break;
|
||||
if (*p == '\0') RETURN_ERROR(0);
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
size_t len = p - value;
|
||||
sq_pushstring(vm, value, len);
|
||||
p++; // Step past the end-of-string marker (")
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
const char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, const char *p)
|
||||
{
|
||||
sq_newtable(vm);
|
||||
|
||||
SKIP_EMPTY(p);
|
||||
if (*p++ != '{') RETURN_ERROR(1);
|
||||
|
||||
for (;;) {
|
||||
SKIP_EMPTY(p);
|
||||
if (*p++ != '"') RETURN_ERROR(1);
|
||||
|
||||
p = ReadString(vm, p);
|
||||
if (p == nullptr) {
|
||||
sq_pop(vm, 1);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SKIP_EMPTY(p);
|
||||
if (*p++ != ':') RETURN_ERROR(2);
|
||||
|
||||
p = this->ReadValue(vm, p);
|
||||
if (p == nullptr) {
|
||||
sq_pop(vm, 2);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sq_rawset(vm, -3);
|
||||
/* The key (-2) and value (-1) are popped from the stack by squirrel. */
|
||||
|
||||
SKIP_EMPTY(p);
|
||||
if (*p == ',') {
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
SKIP_EMPTY(p);
|
||||
if (*p++ != '}') RETURN_ERROR(1);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
const char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, const char *p)
|
||||
{
|
||||
SKIP_EMPTY(p);
|
||||
|
||||
if (strncmp(p, "false", 5) == 0) {
|
||||
sq_pushinteger(vm, 0);
|
||||
return p + 5;
|
||||
}
|
||||
if (strncmp(p, "true", 4) == 0) {
|
||||
sq_pushinteger(vm, 1);
|
||||
return p + 4;
|
||||
}
|
||||
if (strncmp(p, "null", 4) == 0) {
|
||||
sq_pushnull(vm);
|
||||
return p + 4;
|
||||
}
|
||||
|
||||
switch (*p) {
|
||||
case '"': {
|
||||
/* String */
|
||||
p = ReadString(vm, ++p);
|
||||
if (p == nullptr) return nullptr;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case '{': {
|
||||
/* Table */
|
||||
p = this->ReadTable(vm, p);
|
||||
if (p == nullptr) return nullptr;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case '[': {
|
||||
/* Array */
|
||||
sq_newarray(vm, 0);
|
||||
|
||||
/* Empty array? */
|
||||
const char *p2 = p + 1;
|
||||
SKIP_EMPTY(p2);
|
||||
if (*p2 == ']') {
|
||||
p = p2 + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
while (*p++ != ']') {
|
||||
p = this->ReadValue(vm, p);
|
||||
if (p == nullptr) {
|
||||
sq_pop(vm, 1);
|
||||
return nullptr;
|
||||
}
|
||||
sq_arrayappend(vm, -2);
|
||||
|
||||
SKIP_EMPTY(p);
|
||||
if (*p == ',') continue;
|
||||
if (*p == ']') break;
|
||||
RETURN_ERROR(1);
|
||||
}
|
||||
|
||||
p++;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9': case '0':
|
||||
case '-': {
|
||||
/* Integer */
|
||||
|
||||
const char *value = p++;
|
||||
for (;;) {
|
||||
switch (*p++) {
|
||||
case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9': case '0':
|
||||
continue;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
p--;
|
||||
break;
|
||||
}
|
||||
|
||||
int res = atoi(value);
|
||||
sq_pushinteger(vm, (SQInteger)res);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
RETURN_ERROR(0);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
#undef SKIP_EMPTY
|
||||
#undef RETURN_ERROR
|
||||
|
||||
@@ -239,7 +239,7 @@ public:
|
||||
* Get the name of the offered engine.
|
||||
* @return The name the engine has.
|
||||
*/
|
||||
char *GetName();
|
||||
std::optional<std::string> GetName();
|
||||
|
||||
/**
|
||||
* Get the cargo-type of the offered engine. In case it can transport multiple cargoes, it
|
||||
@@ -253,7 +253,7 @@ public:
|
||||
* returns the first/main.
|
||||
* @return The capacity of the engine.
|
||||
*/
|
||||
int32 GetCapacity();
|
||||
int32_t GetCapacity();
|
||||
|
||||
/**
|
||||
* Get the maximum speed of the offered engine.
|
||||
@@ -262,7 +262,7 @@ public:
|
||||
* This is mph / 1.6, which is roughly km/h.
|
||||
* To get km/h multiply this number by 1.00584.
|
||||
*/
|
||||
int32 GetMaxSpeed();
|
||||
int32_t GetMaxSpeed();
|
||||
|
||||
/**
|
||||
* Get the new cost of the offered engine.
|
||||
@@ -284,11 +284,12 @@ public:
|
||||
#ifdef DOXYGEN_API
|
||||
ScriptVehicle::VehicleType GetVehicleType();
|
||||
#else
|
||||
int32 GetVehicleType();
|
||||
int32_t GetVehicleType();
|
||||
#endif /* DOXYGEN_API */
|
||||
|
||||
/**
|
||||
* Accept the engine preview.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True when the accepting succeeded.
|
||||
*/
|
||||
bool AcceptPreview();
|
||||
@@ -381,7 +382,7 @@ public:
|
||||
* @param owner The company that can be bought.
|
||||
* @param value The value/costs of buying the company.
|
||||
*/
|
||||
ScriptEventCompanyAskMerger(Owner owner, int32 value) :
|
||||
ScriptEventCompanyAskMerger(Owner owner, Money value) :
|
||||
ScriptEvent(ET_COMPANY_ASK_MERGER),
|
||||
owner((ScriptCompany::CompanyID)owner),
|
||||
value(value)
|
||||
@@ -406,17 +407,18 @@ public:
|
||||
* Get the value of the new company.
|
||||
* @return The value of the new company.
|
||||
*/
|
||||
int32 GetValue() { return this->value; }
|
||||
Money GetValue() { return this->value; }
|
||||
|
||||
/**
|
||||
* Take over the company for this merger.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return true if the merger was a success.
|
||||
*/
|
||||
bool AcceptMerger();
|
||||
|
||||
private:
|
||||
ScriptCompany::CompanyID owner; ///< The company that is in trouble.
|
||||
int32 value; ///< The value of the company, i.e. the amount you would pay.
|
||||
Money value; ///< The value of the company, i.e. the amount you would pay.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -908,27 +910,6 @@ public:
|
||||
|
||||
private:
|
||||
std::string json; ///< The JSON string.
|
||||
|
||||
/**
|
||||
* Read a table from a JSON string.
|
||||
* @param vm The VM used.
|
||||
* @param p The (part of the) JSON string reading.
|
||||
*/
|
||||
const char *ReadTable(HSQUIRRELVM vm, const char *p);
|
||||
|
||||
/**
|
||||
* Read a value from a JSON string.
|
||||
* @param vm The VM used.
|
||||
* @param p The (part of the) JSON string reading.
|
||||
*/
|
||||
const char *ReadValue(HSQUIRRELVM vm, const char *p);
|
||||
|
||||
/**
|
||||
* Read a string from a JSON string.
|
||||
* @param vm The VM used.
|
||||
* @param p The (part of the) JSON string reading.
|
||||
*/
|
||||
const char *ReadString(HSQUIRRELVM vm, const char *p);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -943,7 +924,7 @@ public:
|
||||
* @param number The windownumber that was clicked.
|
||||
* @param widget The widget in the window that was clicked.
|
||||
*/
|
||||
ScriptEventWindowWidgetClick(ScriptWindow::WindowClass window, uint32 number, uint8 widget) :
|
||||
ScriptEventWindowWidgetClick(ScriptWindow::WindowClass window, uint32_t number, WidgetID widget) :
|
||||
ScriptEvent(ET_WINDOW_WIDGET_CLICK),
|
||||
window(window),
|
||||
number(number),
|
||||
@@ -968,18 +949,18 @@ public:
|
||||
* Get the number of the window that was clicked.
|
||||
* @return The clicked identifying number of the widget within the class.
|
||||
*/
|
||||
uint32 GetWindowNumber() { return this->number; }
|
||||
uint32_t GetWindowNumber() { return this->number; }
|
||||
|
||||
/**
|
||||
* Get the number of the widget that was clicked.
|
||||
* @return The number of the clicked widget.
|
||||
*/
|
||||
uint8 GetWidgetNumber() { return this->widget; }
|
||||
int GetWidgetNumber() { return this->widget; }
|
||||
|
||||
private:
|
||||
ScriptWindow::WindowClass window; ///< Window of the click.
|
||||
uint32 number; ///< Number of the click.
|
||||
uint8 widget; ///< Widget of the click.
|
||||
uint32_t number; ///< Number of the click.
|
||||
WidgetID widget; ///< Widget of the click.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -996,7 +977,7 @@ public:
|
||||
* @param company The company that is replying.
|
||||
* @param button The button the company pressed.
|
||||
*/
|
||||
ScriptEventGoalQuestionAnswer(uint16 uniqueid, ScriptCompany::CompanyID company, ScriptGoal::QuestionButton button) :
|
||||
ScriptEventGoalQuestionAnswer(uint16_t uniqueid, ScriptCompany::CompanyID company, ScriptGoal::QuestionButton button) :
|
||||
ScriptEvent(ET_GOAL_QUESTION_ANSWER),
|
||||
uniqueid(uniqueid),
|
||||
company(company),
|
||||
@@ -1015,7 +996,7 @@ public:
|
||||
* Get the unique id of the question.
|
||||
* @return The unique id.
|
||||
*/
|
||||
uint16 GetUniqueID() { return this->uniqueid; }
|
||||
uint16_t GetUniqueID() { return this->uniqueid; }
|
||||
|
||||
/**
|
||||
* Get the company that pressed a button.
|
||||
@@ -1030,7 +1011,7 @@ public:
|
||||
ScriptGoal::QuestionButton GetButton() { return this->button; }
|
||||
|
||||
private:
|
||||
uint16 uniqueid; ///< The uniqueid of the question.
|
||||
uint16_t uniqueid; ///< The uniqueid of the question.
|
||||
ScriptCompany::CompanyID company; ///< The company given the answer.
|
||||
ScriptGoal::QuestionButton button; ///< The button that was pressed.
|
||||
};
|
||||
|
||||
@@ -31,8 +31,8 @@ ScriptExecMode::ScriptExecMode()
|
||||
void ScriptExecMode::FinalRelease()
|
||||
{
|
||||
if (this->GetDoCommandModeInstance() != this) {
|
||||
/* Ignore this error if the script already died. */
|
||||
if (!ScriptObject::GetActiveInstance()->IsDead()) {
|
||||
/* Ignore this error if the script is not alive. */
|
||||
if (ScriptObject::GetActiveInstance()->IsAlive()) {
|
||||
throw Script_FatalError("ScriptExecMode object was removed while it was not the latest *Mode object created.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
/**
|
||||
* @api -all
|
||||
*/
|
||||
virtual void FinalRelease();
|
||||
void FinalRelease() override;
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_EXECMODE_HPP */
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "../../stdafx.h"
|
||||
#include "script_game.hpp"
|
||||
#include "script_error.hpp"
|
||||
#include "../../command_type.h"
|
||||
#include "../../settings_type.h"
|
||||
#include "../../network/network.h"
|
||||
|
||||
@@ -16,28 +16,33 @@
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
/* static */ bool ScriptGameSettings::IsValid(const char *setting)
|
||||
/* static */ bool ScriptGameSettings::IsValid(const std::string &setting)
|
||||
{
|
||||
const SettingDesc *sd = GetSettingFromName(setting);
|
||||
return sd != nullptr && sd->IsIntSetting();
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptGameSettings::GetValue(const char *setting)
|
||||
/* static */ SQInteger ScriptGameSettings::GetValue(const std::string &setting)
|
||||
{
|
||||
if (!IsValid(setting)) return -1;
|
||||
|
||||
const SettingDesc *sd = GetSettingFromName(setting);
|
||||
assert(sd != nullptr);
|
||||
return sd->AsIntSetting()->Read(&_settings_game);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGameSettings::SetValue(const char *setting, int value)
|
||||
/* static */ bool ScriptGameSettings::SetValue(const std::string &setting, SQInteger value)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
if (!IsValid(setting)) return false;
|
||||
|
||||
const SettingDesc *sd = GetSettingFromName(setting);
|
||||
assert(sd != nullptr);
|
||||
|
||||
if ((sd->flags & SF_NO_NETWORK_SYNC) != 0) return false;
|
||||
|
||||
value = Clamp<SQInteger>(value, INT32_MIN, INT32_MAX);
|
||||
|
||||
return ScriptObject::Command<CMD_CHANGE_SETTING>::Do(sd->GetName(), value);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
* @note Results achieved in the past offer no guarantee for the future.
|
||||
* @return True if and only if the setting is valid.
|
||||
*/
|
||||
static bool IsValid(const char *setting);
|
||||
static bool IsValid(const std::string &setting);
|
||||
|
||||
/**
|
||||
* Gets the value of the game setting.
|
||||
@@ -57,24 +57,24 @@ public:
|
||||
* @note Results achieved in the past offer no guarantee for the future.
|
||||
* @return The value for the setting.
|
||||
*/
|
||||
static int32 GetValue(const char *setting);
|
||||
static SQInteger GetValue(const std::string &setting);
|
||||
|
||||
/**
|
||||
* Sets the value of the game setting.
|
||||
* @param setting The setting to set the value of.
|
||||
* @param value The value to set the setting to.
|
||||
* The value will be clamped to MIN(int32_t) .. MAX(int32_t).
|
||||
* @pre IsValid(setting).
|
||||
* @return True if the action succeeded.
|
||||
* @note Results achieved in the past offer no guarantee for the future.
|
||||
* @api -ai
|
||||
*/
|
||||
static bool SetValue(const char *setting, int value);
|
||||
static bool SetValue(const std::string &setting, SQInteger value);
|
||||
|
||||
/**
|
||||
* Checks whether the given vehicle-type is disabled for companies.
|
||||
* @param vehicle_type The vehicle-type to check.
|
||||
* @return True if the vehicle-type is disabled.
|
||||
* @api -game
|
||||
*/
|
||||
static bool IsDisabledVehicleType(ScriptVehicle::VehicleType vehicle_type);
|
||||
};
|
||||
|
||||
@@ -28,29 +28,32 @@
|
||||
return ::Goal::IsValidID(goal_id);
|
||||
}
|
||||
|
||||
/* static */ ScriptGoal::GoalID ScriptGoal::New(ScriptCompany::CompanyID company, Text *goal, GoalType type, uint32 destination)
|
||||
/* static */ bool ScriptGoal::IsValidGoalDestination(ScriptCompany::CompanyID company, GoalType type, SQInteger destination)
|
||||
{
|
||||
CCountedPtr<Text> counter(goal);
|
||||
|
||||
EnforcePrecondition(GOAL_INVALID, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforcePrecondition(GOAL_INVALID, goal != nullptr);
|
||||
const char *text = goal->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(GOAL_INVALID, text);
|
||||
EnforcePrecondition(GOAL_INVALID, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID);
|
||||
|
||||
CompanyID c = (::CompanyID)company;
|
||||
if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY;
|
||||
StoryPage *story_page = nullptr;
|
||||
if (type == GT_STORY_PAGE && ScriptStoryPage::IsValidStoryPage((ScriptStoryPage::StoryPageID)destination)) story_page = ::StoryPage::Get((ScriptStoryPage::StoryPageID)destination);
|
||||
|
||||
EnforcePrecondition(GOAL_INVALID, (type == GT_NONE && destination == 0) ||
|
||||
return (type == GT_NONE && destination == 0) ||
|
||||
(type == GT_TILE && ScriptMap::IsValidTile(destination)) ||
|
||||
(type == GT_INDUSTRY && ScriptIndustry::IsValidIndustry(destination)) ||
|
||||
(type == GT_TOWN && ScriptTown::IsValidTown(destination)) ||
|
||||
(type == GT_COMPANY && ScriptCompany::ResolveCompanyID((ScriptCompany::CompanyID)destination) != ScriptCompany::COMPANY_INVALID) ||
|
||||
(type == GT_STORY_PAGE && story_page != nullptr && (c == INVALID_COMPANY ? story_page->company == INVALID_COMPANY : story_page->company == INVALID_COMPANY || story_page->company == c)));
|
||||
(type == GT_STORY_PAGE && story_page != nullptr && (c == INVALID_COMPANY ? story_page->company == INVALID_COMPANY : story_page->company == INVALID_COMPANY || story_page->company == c));
|
||||
}
|
||||
|
||||
if (!ScriptObject::Command<CMD_CREATE_GOAL>::Do(&ScriptInstance::DoCommandReturnGoalID, c, (::GoalType)type, destination, text)) return GOAL_INVALID;
|
||||
/* static */ ScriptGoal::GoalID ScriptGoal::New(ScriptCompany::CompanyID company, Text *goal, GoalType type, SQInteger destination)
|
||||
{
|
||||
CCountedPtr<Text> counter(goal);
|
||||
|
||||
EnforceDeityMode(GOAL_INVALID);
|
||||
EnforcePrecondition(GOAL_INVALID, goal != nullptr);
|
||||
std::string text = goal->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(GOAL_INVALID, text);
|
||||
EnforcePrecondition(GOAL_INVALID, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID);
|
||||
EnforcePrecondition(GOAL_INVALID, IsValidGoalDestination(company, type, destination));
|
||||
|
||||
if (!ScriptObject::Command<CMD_CREATE_GOAL>::Do(&ScriptInstance::DoCommandReturnGoalID, (::CompanyID)company, (::GoalType)type, destination, text)) return GOAL_INVALID;
|
||||
|
||||
/* In case of test-mode, we return GoalID 0 */
|
||||
return (ScriptGoal::GoalID)0;
|
||||
@@ -58,22 +61,33 @@
|
||||
|
||||
/* static */ bool ScriptGoal::Remove(GoalID goal_id)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, IsValidGoal(goal_id));
|
||||
|
||||
return ScriptObject::Command<CMD_REMOVE_GOAL>::Do(goal_id);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGoal::SetDestination(GoalID goal_id, GoalType type, SQInteger destination)
|
||||
{
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, IsValidGoal(goal_id));
|
||||
Goal *g = Goal::Get(goal_id);
|
||||
EnforcePrecondition(false, IsValidGoalDestination((ScriptCompany::CompanyID)g->company, type, destination));
|
||||
|
||||
return ScriptObject::Command<CMD_SET_GOAL_DESTINATION>::Do(goal_id, (::GoalType)type, destination);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGoal::SetText(GoalID goal_id, Text *goal)
|
||||
{
|
||||
CCountedPtr<Text> counter(goal);
|
||||
|
||||
EnforcePrecondition(false, IsValidGoal(goal_id));
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, goal != nullptr);
|
||||
EnforcePrecondition(false, !StrEmpty(goal->GetEncodedText()));
|
||||
std::string text = goal->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(false, text);
|
||||
|
||||
return ScriptObject::Command<CMD_SET_GOAL_TEXT>::Do(goal_id, goal->GetEncodedText());
|
||||
return ScriptObject::Command<CMD_SET_GOAL_TEXT>::Do(goal_id, text);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGoal::SetProgress(GoalID goal_id, Text *progress)
|
||||
@@ -81,20 +95,15 @@
|
||||
CCountedPtr<Text> counter(progress);
|
||||
|
||||
EnforcePrecondition(false, IsValidGoal(goal_id));
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforceDeityMode(false);
|
||||
|
||||
/* Ensure null as used for empty string. */
|
||||
if (progress != nullptr && StrEmpty(progress->GetEncodedText())) {
|
||||
progress = nullptr;
|
||||
}
|
||||
|
||||
return ScriptObject::Command<CMD_SET_GOAL_PROGRESS>::Do(goal_id, progress != nullptr ? std::string{ progress->GetEncodedText() } : std::string{});
|
||||
return ScriptObject::Command<CMD_SET_GOAL_PROGRESS>::Do(goal_id, progress != nullptr ? progress->GetEncodedText() : std::string{});
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGoal::SetCompleted(GoalID goal_id, bool completed)
|
||||
{
|
||||
EnforcePrecondition(false, IsValidGoal(goal_id));
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforceDeityMode(false);
|
||||
|
||||
return ScriptObject::Command<CMD_SET_GOAL_COMPLETED>::Do(goal_id, completed);
|
||||
}
|
||||
@@ -102,49 +111,49 @@
|
||||
/* static */ bool ScriptGoal::IsCompleted(GoalID goal_id)
|
||||
{
|
||||
EnforcePrecondition(false, IsValidGoal(goal_id));
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforceDeityMode(false);
|
||||
|
||||
Goal *g = Goal::Get(goal_id);
|
||||
return g != nullptr && g->completed;
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGoal::DoQuestion(uint16 uniqueid, uint32 target, bool is_client, Text *question, QuestionType type, uint32 buttons)
|
||||
/* static */ bool ScriptGoal::DoQuestion(SQInteger uniqueid, uint32_t target, bool is_client, Text *question, QuestionType type, SQInteger buttons)
|
||||
{
|
||||
CCountedPtr<Text> counter(question);
|
||||
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, question != nullptr);
|
||||
const char *text = question->GetEncodedText();
|
||||
std::string text = question->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(false, text);
|
||||
uint min_buttons = (type == QT_QUESTION ? 1 : 0);
|
||||
EnforcePrecondition(false, CountBits(buttons) >= min_buttons && CountBits(buttons) <= 3);
|
||||
EnforcePrecondition(false, buttons < (1 << ::GOAL_QUESTION_BUTTON_COUNT));
|
||||
EnforcePrecondition(false, CountBits<uint64_t>(buttons) >= min_buttons && CountBits<uint64_t>(buttons) <= 3);
|
||||
EnforcePrecondition(false, buttons >= 0 && buttons < (1 << ::GOAL_QUESTION_BUTTON_COUNT));
|
||||
EnforcePrecondition(false, (int)type < ::GQT_END);
|
||||
EnforcePrecondition(false, uniqueid >= 0 && uniqueid <= UINT16_MAX);
|
||||
|
||||
return ScriptObject::Command<CMD_GOAL_QUESTION>::Do(uniqueid, target, is_client, buttons, (::GoalQuestionType)type, text);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGoal::Question(uint16 uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, int buttons)
|
||||
/* static */ bool ScriptGoal::Question(SQInteger uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, SQInteger buttons)
|
||||
{
|
||||
EnforcePrecondition(false, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID);
|
||||
uint8 c = company;
|
||||
uint8_t c = company;
|
||||
if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY;
|
||||
|
||||
return DoQuestion(uniqueid, c, false, question, type, buttons);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGoal::QuestionClient(uint16 uniqueid, ScriptClient::ClientID client, Text *question, QuestionType type, int buttons)
|
||||
/* static */ bool ScriptGoal::QuestionClient(SQInteger uniqueid, ScriptClient::ClientID client, Text *question, QuestionType type, SQInteger buttons)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptGame::IsMultiplayer());
|
||||
EnforcePrecondition(false, ScriptClient::ResolveClientID(client) != ScriptClient::CLIENT_INVALID);
|
||||
/* Can only send 16 bits of client_id before proper fix is implemented */
|
||||
EnforcePrecondition(false, client < (1 << 16));
|
||||
return DoQuestion(uniqueid, client, true, question, type, buttons);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGoal::CloseQuestion(uint16 uniqueid)
|
||||
/* static */ bool ScriptGoal::CloseQuestion(SQInteger uniqueid)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, uniqueid >= 0 && uniqueid <= UINT16_MAX);
|
||||
|
||||
return ScriptObject::Command<CMD_GOAL_QUESTION_ANSWER>::Do(uniqueid, 0);
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ public:
|
||||
/**
|
||||
* The goal IDs.
|
||||
*/
|
||||
enum GoalID {
|
||||
enum GoalID : uint16_t {
|
||||
/* Note: these values represent part of the in-game GoalID enum */
|
||||
GOAL_INVALID = ::INVALID_GOALTYPE, ///< An invalid goal id.
|
||||
GOAL_INVALID = ::INVALID_GOAL, ///< An invalid goal id.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -89,6 +89,15 @@ public:
|
||||
*/
|
||||
static bool IsValidGoal(GoalID goal_id);
|
||||
|
||||
/**
|
||||
* Check whether this is a valid goal destination.
|
||||
* @param company The relevant company if a story page is the destination.
|
||||
* @param type The type of the goal.
|
||||
* @param destination The destination of the \a type type.
|
||||
* @return True if and only if this goal destination is valid.
|
||||
*/
|
||||
static bool IsValidGoalDestination(ScriptCompany::CompanyID company, GoalType type, SQInteger destination);
|
||||
|
||||
/**
|
||||
* Create a new goal.
|
||||
* @param company The company to create the goal for, or ScriptCompany::COMPANY_INVALID for all.
|
||||
@@ -96,30 +105,42 @@ public:
|
||||
* @param type The type of the goal.
|
||||
* @param destination The destination of the \a type type.
|
||||
* @return The new GoalID, or GOAL_INVALID if it failed.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @pre goal != null && len(goal) != 0.
|
||||
* @pre company == COMPANY_INVALID || ResolveCompanyID(company) != COMPANY_INVALID.
|
||||
* @pre if type is GT_STORY_PAGE, the company of the goal and the company of the story page need to match:
|
||||
* \li Global goals can only reference global story pages.
|
||||
* \li Company specific goals can reference global story pages and story pages of the same company.
|
||||
*/
|
||||
static GoalID New(ScriptCompany::CompanyID company, Text *goal, GoalType type, uint32 destination);
|
||||
static GoalID New(ScriptCompany::CompanyID company, Text *goal, GoalType type, SQInteger destination);
|
||||
|
||||
/**
|
||||
* Remove a goal from the list.
|
||||
* @param goal_id The goal to remove.
|
||||
* @return True if the action succeeded.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @pre IsValidGoal(goal_id).
|
||||
*/
|
||||
static bool Remove(GoalID goal_id);
|
||||
|
||||
/**
|
||||
* Update goal destination of a goal.
|
||||
* @param goal_id The goal to update.
|
||||
* @param type The type of the goal.
|
||||
* @param destination The destination of the \a type type.
|
||||
* @return True if the action succeeded.
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @pre IsValidGoal(goal_id).
|
||||
* @pre IsValidGoalDestination(g->company, type, destination).
|
||||
*/
|
||||
static bool SetDestination(GoalID goal_id, GoalType type, SQInteger destination);
|
||||
|
||||
/**
|
||||
* Update goal text of a goal.
|
||||
* @param goal_id The goal to update.
|
||||
* @param goal The new goal text (can be either a raw string, or a ScriptText object).
|
||||
* @return True if the action succeeded.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @pre goal != null && len(goal) != 0.
|
||||
* @pre IsValidGoal(goal_id).
|
||||
*/
|
||||
@@ -134,7 +155,7 @@ public:
|
||||
* or a ScriptText object). To clear the progress string you can pass null or an
|
||||
* empty string.
|
||||
* @return True if the action succeeded.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @pre IsValidGoal(goal_id).
|
||||
*/
|
||||
static bool SetProgress(GoalID goal_id, Text *progress);
|
||||
@@ -144,7 +165,7 @@ public:
|
||||
* @param goal_id The goal to update.
|
||||
* @param complete The new goal completed status.
|
||||
* @return True if the action succeeded.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @pre IsValidGoal(goal_id).
|
||||
*/
|
||||
static bool SetCompleted(GoalID goal_id, bool complete);
|
||||
@@ -153,7 +174,7 @@ public:
|
||||
* Checks if a given goal have been marked as completed.
|
||||
* @param goal_id The goal to check complete status.
|
||||
* @return True if the goal is completed, otherwise false.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @pre IsValidGoal(goal_id).
|
||||
*/
|
||||
static bool IsCompleted(GoalID goal_id);
|
||||
@@ -166,14 +187,15 @@ public:
|
||||
* @param type The type of question that is being asked.
|
||||
* @param buttons Any combinations (at least 1, up to 3) of buttons defined in QuestionButton. Like BUTTON_YES + BUTTON_NO.
|
||||
* @return True if the action succeeded.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @pre question != null && len(question) != 0.
|
||||
* @pre company == COMPANY_INVALID || ResolveCompanyID(company) != COMPANY_INVALID.
|
||||
* @pre CountBits(buttons) >= 1 && CountBits(buttons) <= 3.
|
||||
* @note Replies to the question are given by you via the event ScriptEvent_GoalQuestionAnswer.
|
||||
* @pre uniqueid >= 0 && uniqueid <= MAX(uint16_t)
|
||||
* @note Replies to the question are given by you via the event ScriptEventGoalQuestionAnswer.
|
||||
* @note There is no guarantee you ever get a reply on your question.
|
||||
*/
|
||||
static bool Question(uint16 uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, int buttons);
|
||||
static bool Question(SQInteger uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, SQInteger buttons);
|
||||
|
||||
/**
|
||||
* Ask client a question.
|
||||
@@ -183,33 +205,35 @@ public:
|
||||
* @param type The type of question that is being asked.
|
||||
* @param buttons Any combinations (at least 1, up to 3) of buttons defined in QuestionButton. Like BUTTON_YES + BUTTON_NO.
|
||||
* @return True if the action succeeded.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @pre ScriptGame::IsMultiplayer()
|
||||
* @pre question != null && len(question) != 0.
|
||||
* @pre ResolveClientID(client) != CLIENT_INVALID.
|
||||
* @pre CountBits(buttons) >= 1 && CountBits(buttons) <= 3.
|
||||
* @note Replies to the question are given by you via the event ScriptEvent_GoalQuestionAnswer.
|
||||
* @pre uniqueid >= 0 && uniqueid <= MAX(uint16_t)
|
||||
* @note Replies to the question are given by you via the event ScriptEventGoalQuestionAnswer.
|
||||
* @note There is no guarantee you ever get a reply on your question.
|
||||
*/
|
||||
static bool QuestionClient(uint16 uniqueid, ScriptClient::ClientID client, Text *question, QuestionType type, int buttons);
|
||||
static bool QuestionClient(SQInteger uniqueid, ScriptClient::ClientID client, Text *question, QuestionType type, SQInteger buttons);
|
||||
|
||||
/**
|
||||
* Close the question on all clients.
|
||||
* @param uniqueid The uniqueid of the question you want to close.
|
||||
* @return True if the action succeeded.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @pre uniqueid >= 0 && uniqueid <= MAX(uint16_t)
|
||||
* @note If you send a question to a single company, and get a reply for them,
|
||||
* the question is already closed on all clients. Only use this function if
|
||||
* you want to timeout a question, or if you send the question to all
|
||||
* companies, but you are only interested in the reply of the first.
|
||||
*/
|
||||
static bool CloseQuestion(uint16 uniqueid);
|
||||
static bool CloseQuestion(SQInteger uniqueid);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Does common checks and asks the question.
|
||||
*/
|
||||
static bool DoQuestion(uint16 uniqueid, uint32 target, bool is_client, Text *question, QuestionType type, uint32 buttons);
|
||||
static bool DoQuestion(SQInteger uniqueid, uint32_t target, bool is_client, Text *question, QuestionType type, SQInteger buttons);
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_GOAL_HPP */
|
||||
|
||||
@@ -25,12 +25,14 @@
|
||||
|
||||
/* static */ bool ScriptGroup::IsValidGroup(GroupID group_id)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
const Group *g = ::Group::GetIfValid(group_id);
|
||||
return g != nullptr && g->owner == ScriptObject::GetCompany();
|
||||
}
|
||||
|
||||
/* static */ ScriptGroup::GroupID ScriptGroup::CreateGroup(ScriptVehicle::VehicleType vehicle_type, GroupID parent_group_id)
|
||||
{
|
||||
EnforceCompanyModeValid(GROUP_INVALID);
|
||||
if (!ScriptObject::Command<CMD_CREATE_GROUP>::Do(&ScriptInstance::DoCommandReturnGroupID, (::VehicleType)vehicle_type, parent_group_id)) return GROUP_INVALID;
|
||||
|
||||
/* In case of test-mode, we return GroupID 0 */
|
||||
@@ -39,6 +41,7 @@
|
||||
|
||||
/* static */ bool ScriptGroup::DeleteGroup(GroupID group_id)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidGroup(group_id));
|
||||
|
||||
return ScriptObject::Command<CMD_DELETE_GROUP>::Do(group_id);
|
||||
@@ -55,18 +58,19 @@
|
||||
{
|
||||
CCountedPtr<Text> counter(name);
|
||||
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidGroup(group_id));
|
||||
EnforcePrecondition(false, name != nullptr);
|
||||
const char *text = name->GetDecodedText();
|
||||
const std::string &text = name->GetDecodedText();
|
||||
EnforcePreconditionEncodedText(false, text);
|
||||
EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_GROUP_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG);
|
||||
|
||||
return ScriptObject::Command<CMD_ALTER_GROUP>::Do(AlterGroupMode::Rename, group_id, 0, text);
|
||||
}
|
||||
|
||||
/* static */ char *ScriptGroup::GetName(GroupID group_id)
|
||||
/* static */ std::optional<std::string> ScriptGroup::GetName(GroupID group_id)
|
||||
{
|
||||
if (!IsValidGroup(group_id)) return nullptr;
|
||||
if (!IsValidGroup(group_id)) return std::nullopt;
|
||||
|
||||
::SetDParam(0, group_id);
|
||||
return GetString(STR_GROUP_NAME);
|
||||
@@ -74,6 +78,7 @@
|
||||
|
||||
/* static */ bool ScriptGroup::SetParent(GroupID group_id, GroupID parent_group_id)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidGroup(group_id));
|
||||
EnforcePrecondition(false, IsValidGroup(parent_group_id));
|
||||
|
||||
@@ -90,6 +95,7 @@
|
||||
|
||||
/* static */ bool ScriptGroup::EnableAutoReplaceProtection(GroupID group_id, bool enable)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidGroup(group_id));
|
||||
|
||||
return ScriptObject::Command<CMD_SET_GROUP_FLAG>::Do(group_id, GroupFlags::GF_REPLACE_PROTECTION, enable, false);
|
||||
@@ -102,15 +108,17 @@
|
||||
return HasBit(::Group::Get(group_id)->flags, GroupFlags::GF_REPLACE_PROTECTION);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptGroup::GetNumEngines(GroupID group_id, EngineID engine_id)
|
||||
/* static */ SQInteger ScriptGroup::GetNumEngines(GroupID group_id, EngineID engine_id)
|
||||
{
|
||||
EnforceCompanyModeValid(-1);
|
||||
if (!IsValidGroup(group_id) && group_id != GROUP_DEFAULT && group_id != GROUP_ALL) return -1;
|
||||
|
||||
return GetGroupNumEngines(ScriptObject::GetCompany(), group_id, engine_id);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptGroup::GetNumVehicles(GroupID group_id, ScriptVehicle::VehicleType vehicle_type)
|
||||
/* static */ SQInteger ScriptGroup::GetNumVehicles(GroupID group_id, ScriptVehicle::VehicleType vehicle_type)
|
||||
{
|
||||
EnforceCompanyModeValid(-1);
|
||||
bool valid_group = IsValidGroup(group_id);
|
||||
if (!valid_group && group_id != GROUP_DEFAULT && group_id != GROUP_ALL) return -1;
|
||||
if (!valid_group && (vehicle_type < ScriptVehicle::VT_RAIL || vehicle_type > ScriptVehicle::VT_AIR)) return -1;
|
||||
@@ -120,14 +128,16 @@
|
||||
|
||||
/* static */ bool ScriptGroup::MoveVehicle(GroupID group_id, VehicleID vehicle_id)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT);
|
||||
EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id));
|
||||
EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id));
|
||||
|
||||
return ScriptObject::Command<CMD_ADD_VEHICLE_GROUP>::Do(group_id, vehicle_id, false);
|
||||
return ScriptObject::Command<CMD_ADD_VEHICLE_GROUP>::Do(group_id, vehicle_id, false, VehicleListIdentifier{});
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGroup::EnableWagonRemoval(bool enable_removal)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
if (HasWagonRemoval() == enable_removal) return true;
|
||||
|
||||
return ScriptObject::Command<CMD_CHANGE_COMPANY_SETTING>::Do("company.renew_keep_length", enable_removal ? 1 : 0);
|
||||
@@ -135,11 +145,13 @@
|
||||
|
||||
/* static */ bool ScriptGroup::HasWagonRemoval()
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
return ::Company::Get(ScriptObject::GetCompany())->settings.renew_keep_length;
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGroup::SetAutoReplace(GroupID group_id, EngineID engine_id_old, EngineID engine_id_new)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL);
|
||||
EnforcePrecondition(false, ScriptEngine::IsBuildable(engine_id_new));
|
||||
|
||||
@@ -148,6 +160,7 @@
|
||||
|
||||
/* static */ EngineID ScriptGroup::GetEngineReplacement(GroupID group_id, EngineID engine_id)
|
||||
{
|
||||
EnforceCompanyModeValid(::INVALID_ENGINE);
|
||||
if (!IsValidGroup(group_id) && group_id != GROUP_DEFAULT && group_id != GROUP_ALL) return ::INVALID_ENGINE;
|
||||
|
||||
return ::EngineReplacementForCompany(Company::Get(ScriptObject::GetCompany()), engine_id, group_id);
|
||||
@@ -155,6 +168,7 @@
|
||||
|
||||
/* static */ bool ScriptGroup::StopAutoReplace(GroupID group_id, EngineID engine_id)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL);
|
||||
|
||||
return ScriptObject::Command<CMD_SET_AUTOREPLACE>::Do(group_id, engine_id, ::INVALID_ENGINE, false);
|
||||
@@ -183,12 +197,12 @@
|
||||
return ::Group::Get(group_id)->statistics.profit_last_year;
|
||||
}
|
||||
|
||||
/* static */ uint32 ScriptGroup::GetCurrentUsage(GroupID group_id)
|
||||
/* static */ SQInteger ScriptGroup::GetCurrentUsage(GroupID group_id)
|
||||
{
|
||||
if (!IsValidGroup(group_id)) return -1;
|
||||
|
||||
uint32 occupancy = 0;
|
||||
uint32 vehicle_count = 0;
|
||||
uint32_t occupancy = 0;
|
||||
uint32_t vehicle_count = 0;
|
||||
|
||||
for (const Vehicle *v : Vehicle::Iterate()) {
|
||||
if (v->group_id != group_id) continue;
|
||||
@@ -205,6 +219,7 @@
|
||||
|
||||
/* static */ bool ScriptGroup::SetPrimaryColour(GroupID group_id, ScriptCompany::Colours colour)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidGroup(group_id));
|
||||
|
||||
return ScriptObject::Command<CMD_SET_GROUP_LIVERY>::Do(group_id, true, (::Colours)colour);
|
||||
@@ -212,6 +227,7 @@
|
||||
|
||||
/* static */ bool ScriptGroup::SetSecondaryColour(GroupID group_id, ScriptCompany::Colours colour)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidGroup(group_id));
|
||||
|
||||
return ScriptObject::Command<CMD_SET_GROUP_LIVERY>::Do(group_id, false, (::Colours)colour);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
/**
|
||||
* Class that handles all group related functions.
|
||||
* @api ai
|
||||
* @api ai game
|
||||
*/
|
||||
class ScriptGroup : public ScriptObject {
|
||||
public:
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
* Create a new group.
|
||||
* @param vehicle_type The type of vehicle to create a group for.
|
||||
* @param parent_group_id The parent group id to create this group under, INVALID_GROUP for top-level.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return The GroupID of the new group, or an invalid GroupID when
|
||||
* it failed. Check the return value using IsValidGroup(). In test-mode
|
||||
* 0 is returned if it was successful; any other value indicates failure.
|
||||
@@ -52,6 +53,7 @@ public:
|
||||
* given group will move to the GROUP_DEFAULT.
|
||||
* @param group_id The group to delete.
|
||||
* @pre IsValidGroup(group_id).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True if and only if the group was successfully deleted.
|
||||
*/
|
||||
static bool DeleteGroup(GroupID group_id);
|
||||
@@ -70,6 +72,7 @@ public:
|
||||
* @param name The name for the group (can be either a raw string, or a ScriptText object).
|
||||
* @pre IsValidGroup(group_id).
|
||||
* @pre name != null && len(name) != 0
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE
|
||||
* @return True if and only if the name was changed.
|
||||
*/
|
||||
@@ -81,7 +84,7 @@ public:
|
||||
* @pre IsValidGroup(group_id).
|
||||
* @return The name the group has.
|
||||
*/
|
||||
static char *GetName(GroupID group_id);
|
||||
static std::optional<std::string> GetName(GroupID group_id);
|
||||
|
||||
/**
|
||||
* Set parent group of a group.
|
||||
@@ -89,6 +92,7 @@ public:
|
||||
* @param parent_group_id The parent group to set.
|
||||
* @pre IsValidGroup(group_id).
|
||||
* @pre IsValidGroup(parent_group_id).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True if and only if the parent group was changed.
|
||||
*/
|
||||
static bool SetParent(GroupID group_id, GroupID parent_group_id);
|
||||
@@ -107,6 +111,7 @@ public:
|
||||
* @param group_id The group to change the protection for.
|
||||
* @param enable True if protection should be enabled.
|
||||
* @pre IsValidGroup(group_id).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True if and only if the protection was successfully changed.
|
||||
*/
|
||||
static bool EnableAutoReplaceProtection(GroupID group_id, bool enable);
|
||||
@@ -124,9 +129,10 @@ public:
|
||||
* @param group_id The group to get the number of engines in.
|
||||
* @param engine_id The engine id to count.
|
||||
* @pre IsValidGroup(group_id) || group_id == GROUP_ALL || group_id == GROUP_DEFAULT.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return The number of engines with id engine_id in the group with id group_id.
|
||||
*/
|
||||
static int32 GetNumEngines(GroupID group_id, EngineID engine_id);
|
||||
static SQInteger GetNumEngines(GroupID group_id, EngineID engine_id);
|
||||
|
||||
/**
|
||||
* Get the total number of vehicles in a given group and its sub-groups.
|
||||
@@ -135,19 +141,21 @@ public:
|
||||
* @pre IsValidGroup(group_id) || group_id == GROUP_ALL || group_id == GROUP_DEFAULT.
|
||||
* @pre IsValidGroup(group_id) || vehicle_type == ScriptVehicle::VT_ROAD || vehicle_type == ScriptVehicle::VT_RAIL ||
|
||||
* vehicle_type == ScriptVehicle::VT_WATER || vehicle_type == ScriptVehicle::VT_AIR
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return The total number of vehicles in the group with id group_id and it's sub-groups.
|
||||
* @note If the group is valid (neither GROUP_ALL nor GROUP_DEFAULT), the value of
|
||||
* vehicle_type is retrieved from the group itself and not from the input value.
|
||||
* But if the group is GROUP_ALL or GROUP_DEFAULT, then vehicle_type must be valid.
|
||||
*/
|
||||
static int32 GetNumVehicles(GroupID group_id, ScriptVehicle::VehicleType vehicle_type);
|
||||
static SQInteger GetNumVehicles(GroupID group_id, ScriptVehicle::VehicleType vehicle_type);
|
||||
|
||||
/**
|
||||
* Move a vehicle to a group.
|
||||
* @param group_id The group to move the vehicle to.
|
||||
* @param vehicle_id The vehicle to move to the group.
|
||||
* @pre IsValidGroup(group_id) || group_id == GROUP_DEFAULT.
|
||||
* @pre ScriptVehicle::IsValidVehicle(vehicle_id).
|
||||
* @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True if and only if the vehicle was successfully moved to the group.
|
||||
* @note A vehicle can be in only one group at the same time. To remove it from
|
||||
* a group, move it to another or to GROUP_DEFAULT. Moving the vehicle to the
|
||||
@@ -161,12 +169,14 @@ public:
|
||||
* If enabled, wagons are removed from the end of the vehicle until it
|
||||
* fits in the same number of tiles as it did before.
|
||||
* @param keep_length If true, wagons will be removed if the new engine is longer.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True if and only if the value was successfully changed.
|
||||
*/
|
||||
static bool EnableWagonRemoval(bool keep_length);
|
||||
|
||||
/**
|
||||
* Get the current status of wagon removal.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return Whether or not wagon removal is enabled.
|
||||
*/
|
||||
static bool HasWagonRemoval();
|
||||
@@ -179,6 +189,7 @@ public:
|
||||
* @param engine_id_new The engine id to replace with.
|
||||
* @pre IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL.
|
||||
* @pre ScriptEngine.IsBuildable(engine_id_new).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True if and if the replacing was successfully started.
|
||||
* @note To stop autoreplacing engine_id_old, call StopAutoReplace(group_id, engine_id_old).
|
||||
*/
|
||||
@@ -189,6 +200,7 @@ public:
|
||||
* @param group_id The group to get the replacement from.
|
||||
* @param engine_id The engine that is being replaced.
|
||||
* @pre IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return The EngineID that is replacing engine_id or an invalid EngineID
|
||||
* in case engine_id is not begin replaced.
|
||||
*/
|
||||
@@ -199,6 +211,7 @@ public:
|
||||
* @param group_id The group to stop replacing the engine in.
|
||||
* @param engine_id The engine id to stop replacing with another engine.
|
||||
* @pre IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True if and if the replacing was successfully stopped.
|
||||
*/
|
||||
static bool StopAutoReplace(GroupID group_id, EngineID engine_id);
|
||||
@@ -225,13 +238,14 @@ public:
|
||||
* @pre IsValidGroup(group_id).
|
||||
* @return The current usage of the group.
|
||||
*/
|
||||
static uint32 GetCurrentUsage(GroupID group_id);
|
||||
static SQInteger GetCurrentUsage(GroupID group_id);
|
||||
|
||||
/**
|
||||
* Set primary colour for a group.
|
||||
* @param group_id The group id to set the colour of.
|
||||
* @param colour Colour to set.
|
||||
* @pre IsValidGroup(group_id).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True iff the colour was set successfully.
|
||||
*/
|
||||
static bool SetPrimaryColour(GroupID group_id, ScriptCompany::Colours colour);
|
||||
@@ -241,6 +255,7 @@ public:
|
||||
* @param group_id The group id to set the colour of.
|
||||
* @param colour Colour to set.
|
||||
* @pre IsValidGroup(group_id).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True iff the colour was set successfully.
|
||||
*/
|
||||
static bool SetSecondaryColour(GroupID group_id, ScriptCompany::Colours colour);
|
||||
|
||||
@@ -9,13 +9,16 @@
|
||||
|
||||
#include "../../stdafx.h"
|
||||
#include "script_grouplist.hpp"
|
||||
#include "script_error.hpp"
|
||||
#include "../../group.h"
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
ScriptGroupList::ScriptGroupList()
|
||||
ScriptGroupList::ScriptGroupList(HSQUIRRELVM vm)
|
||||
{
|
||||
for (const Group *g : Group::Iterate()) {
|
||||
if (g->owner == ScriptObject::GetCompany()) this->AddItem(g->index);
|
||||
}
|
||||
EnforceCompanyModeValid_Void();
|
||||
CompanyID owner = ScriptObject::GetCompany();
|
||||
ScriptList::FillList<Group>(vm, this,
|
||||
[owner](const Group *g) { return g->owner == owner; }
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,12 +15,40 @@
|
||||
/**
|
||||
* Creates a list of groups of which you are the owner.
|
||||
* @note Neither ScriptGroup::GROUP_ALL nor ScriptGroup::GROUP_DEFAULT is in this list.
|
||||
* @api ai
|
||||
* @api ai game
|
||||
* @ingroup ScriptList
|
||||
*/
|
||||
class ScriptGroupList : public ScriptList {
|
||||
public:
|
||||
#ifdef DOXYGEN_API
|
||||
/**
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
*/
|
||||
ScriptGroupList();
|
||||
|
||||
/**
|
||||
* Apply a filter when building the list.
|
||||
* @param filter_function The function which will be doing the filtering.
|
||||
* @param params The params to give to the filters (minus the first param,
|
||||
* which is always the index-value).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @note You can write your own filters and use them. Just remember that
|
||||
* the first parameter should be the index-value, and it should return
|
||||
* a bool.
|
||||
* @note Example:
|
||||
* function IsType(group_id, type)
|
||||
* {
|
||||
* return ScriptGroup.GetVehicleType(group_id) == type;
|
||||
* }
|
||||
* ScriptGroupList(IsType, ScriptVehicle.VT_ROAD);
|
||||
*/
|
||||
ScriptGroupList(void *filter_function, int params, ...);
|
||||
#else
|
||||
/**
|
||||
* The constructor wrapper from Squirrel.
|
||||
*/
|
||||
ScriptGroupList(HSQUIRRELVM vm);
|
||||
#endif /* DOXYGEN_API */
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_GROUPLIST_HPP */
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
#include "../../station_base.h"
|
||||
#include "../../newgrf_industries.h"
|
||||
#include "../../industry_cmd.h"
|
||||
#include "../../timer/timer_game_calendar.h"
|
||||
#include "table/strings.h"
|
||||
#include <numeric>
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
/* static */ int32 ScriptIndustry::GetIndustryCount()
|
||||
/* static */ SQInteger ScriptIndustry::GetIndustryCount()
|
||||
{
|
||||
return (int32)::Industry::GetNumItems();
|
||||
return ::Industry::GetNumItems();
|
||||
}
|
||||
|
||||
/* static */ bool ScriptIndustry::IsValidIndustry(IndustryID industry_id)
|
||||
@@ -41,26 +41,29 @@
|
||||
return ::GetIndustryIndex(tile);
|
||||
}
|
||||
|
||||
/* static */ char *ScriptIndustry::GetName(IndustryID industry_id)
|
||||
/* static */ std::optional<std::string> ScriptIndustry::GetName(IndustryID industry_id)
|
||||
{
|
||||
if (!IsValidIndustry(industry_id)) return nullptr;
|
||||
if (!IsValidIndustry(industry_id)) return std::nullopt;
|
||||
|
||||
::SetDParam(0, industry_id);
|
||||
return GetString(STR_INDUSTRY_NAME);
|
||||
}
|
||||
|
||||
/* static */ ScriptDate::Date ScriptIndustry::GetConstructionDate(IndustryID industry_id)
|
||||
{
|
||||
Industry *i = Industry::GetIfValid(industry_id);
|
||||
if (i == nullptr) return ScriptDate::DATE_INVALID;
|
||||
return (ScriptDate::Date)i->construction_date.base();
|
||||
}
|
||||
|
||||
/* static */ bool ScriptIndustry::SetText(IndustryID industry_id, Text *text)
|
||||
{
|
||||
CCountedPtr<Text> counter(text);
|
||||
|
||||
const char *encoded_text = nullptr;
|
||||
if (text != nullptr) {
|
||||
encoded_text = text->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(false, encoded_text);
|
||||
}
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, IsValidIndustry(industry_id));
|
||||
|
||||
return ScriptObject::Command<CMD_INDUSTRY_CTRL>::Do(industry_id, IndustryAction::SetText, INDCTL_NONE, INVALID_OWNER, std::string{ encoded_text ? encoded_text : "" });
|
||||
return ScriptObject::Command<CMD_INDUSTRY_SET_TEXT>::Do(industry_id, text != nullptr ? text->GetEncodedText() : std::string{});
|
||||
}
|
||||
|
||||
/* static */ ScriptIndustry::CargoAcceptState ScriptIndustry::IsCargoAccepted(IndustryID industry_id, CargoID cargo_id)
|
||||
@@ -70,72 +73,62 @@
|
||||
|
||||
Industry *i = ::Industry::Get(industry_id);
|
||||
|
||||
for (byte j = 0; j < lengthof(i->accepts_cargo); j++) {
|
||||
if (i->accepts_cargo[j] == cargo_id) {
|
||||
if (IndustryTemporarilyRefusesCargo(i, cargo_id)) return CAS_TEMP_REFUSED;
|
||||
return CAS_ACCEPTED;
|
||||
}
|
||||
}
|
||||
if (!i->IsCargoAccepted(cargo_id)) return CAS_NOT_ACCEPTED;
|
||||
if (IndustryTemporarilyRefusesCargo(i, cargo_id)) return CAS_TEMP_REFUSED;
|
||||
|
||||
return CAS_NOT_ACCEPTED;
|
||||
return CAS_ACCEPTED;
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptIndustry::GetStockpiledCargo(IndustryID industry_id, CargoID cargo_id)
|
||||
/* static */ SQInteger ScriptIndustry::GetStockpiledCargo(IndustryID industry_id, CargoID cargo_id)
|
||||
{
|
||||
if (!IsValidIndustry(industry_id)) return -1;
|
||||
if (!ScriptCargo::IsValidCargo(cargo_id)) return -1;
|
||||
|
||||
Industry *ind = ::Industry::Get(industry_id);
|
||||
for (uint i = 0; i < lengthof(ind->accepts_cargo); i++) {
|
||||
CargoID cid = ind->accepts_cargo[i];
|
||||
if (cid == cargo_id) {
|
||||
return ind->incoming_cargo_waiting[i];
|
||||
}
|
||||
}
|
||||
Industry *i = ::Industry::Get(industry_id);
|
||||
|
||||
return -1;
|
||||
auto it = i->GetCargoAccepted(cargo_id);
|
||||
if (it == std::end(i->accepted)) return -1;
|
||||
|
||||
return it->waiting;
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptIndustry::GetLastMonthProduction(IndustryID industry_id, CargoID cargo_id)
|
||||
/* static */ SQInteger ScriptIndustry::GetLastMonthProduction(IndustryID industry_id, CargoID cargo_id)
|
||||
{
|
||||
if (!IsValidIndustry(industry_id)) return -1;
|
||||
if (!ScriptCargo::IsValidCargo(cargo_id)) return -1;
|
||||
|
||||
const Industry *i = ::Industry::Get(industry_id);
|
||||
Industry *i = ::Industry::Get(industry_id);
|
||||
|
||||
for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
|
||||
if (i->produced_cargo[j] == cargo_id) return i->last_month_production[j];
|
||||
}
|
||||
auto it = i->GetCargoProduced(cargo_id);
|
||||
if (it == std::end(i->produced)) return -1;
|
||||
|
||||
return -1;
|
||||
return it->history[LAST_MONTH].production;
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptIndustry::GetLastMonthTransported(IndustryID industry_id, CargoID cargo_id)
|
||||
/* static */ SQInteger ScriptIndustry::GetLastMonthTransported(IndustryID industry_id, CargoID cargo_id)
|
||||
{
|
||||
if (!IsValidIndustry(industry_id)) return -1;
|
||||
if (!ScriptCargo::IsValidCargo(cargo_id)) return -1;
|
||||
|
||||
const Industry *i = ::Industry::Get(industry_id);
|
||||
Industry *i = ::Industry::Get(industry_id);
|
||||
|
||||
for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
|
||||
if (i->produced_cargo[j] == cargo_id) return i->last_month_transported[j];
|
||||
}
|
||||
auto it = i->GetCargoProduced(cargo_id);
|
||||
if (it == std::end(i->produced)) return -1;
|
||||
|
||||
return -1;
|
||||
return it->history[LAST_MONTH].transported;
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptIndustry::GetLastMonthTransportedPercentage(IndustryID industry_id, CargoID cargo_id)
|
||||
/* static */ SQInteger ScriptIndustry::GetLastMonthTransportedPercentage(IndustryID industry_id, CargoID cargo_id)
|
||||
{
|
||||
if (!IsValidIndustry(industry_id)) return -1;
|
||||
if (!ScriptCargo::IsValidCargo(cargo_id)) return -1;
|
||||
|
||||
const Industry *i = ::Industry::Get(industry_id);
|
||||
Industry *i = ::Industry::Get(industry_id);
|
||||
|
||||
for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
|
||||
if (i->produced_cargo[j] == cargo_id) return ::ToPercent8(i->last_month_pct_transported[j]);
|
||||
}
|
||||
auto it = i->GetCargoProduced(cargo_id);
|
||||
if (it == std::end(i->produced)) return -1;
|
||||
|
||||
return -1;
|
||||
return ::ToPercent8(it->history[LAST_MONTH].PctTransported());
|
||||
}
|
||||
|
||||
/* static */ TileIndex ScriptIndustry::GetLocation(IndustryID industry_id)
|
||||
@@ -145,22 +138,22 @@
|
||||
return ::Industry::Get(industry_id)->location.tile;
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptIndustry::GetAmountOfStationsAround(IndustryID industry_id)
|
||||
/* static */ SQInteger ScriptIndustry::GetAmountOfStationsAround(IndustryID industry_id)
|
||||
{
|
||||
if (!IsValidIndustry(industry_id)) return -1;
|
||||
|
||||
Industry *ind = ::Industry::Get(industry_id);
|
||||
return (int32)ind->stations_near.size();
|
||||
return ind->stations_near.size();
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptIndustry::GetDistanceManhattanToTile(IndustryID industry_id, TileIndex tile)
|
||||
/* static */ SQInteger ScriptIndustry::GetDistanceManhattanToTile(IndustryID industry_id, TileIndex tile)
|
||||
{
|
||||
if (!IsValidIndustry(industry_id)) return -1;
|
||||
|
||||
return ScriptMap::DistanceManhattan(tile, GetLocation(industry_id));
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptIndustry::GetDistanceSquareToTile(IndustryID industry_id, TileIndex tile)
|
||||
/* static */ SQInteger ScriptIndustry::GetDistanceSquareToTile(IndustryID industry_id, TileIndex tile)
|
||||
{
|
||||
if (!IsValidIndustry(industry_id)) return -1;
|
||||
|
||||
@@ -225,40 +218,41 @@
|
||||
return ::Industry::Get(industry_id)->type;
|
||||
}
|
||||
|
||||
int32 ScriptIndustry::GetLastProductionYear(IndustryID industry_id)
|
||||
/* static */ SQInteger ScriptIndustry::GetLastProductionYear(IndustryID industry_id)
|
||||
{
|
||||
Industry *i = Industry::GetIfValid(industry_id);
|
||||
if (i == nullptr) return 0;
|
||||
return i->last_prod_year;
|
||||
return i->last_prod_year.base();
|
||||
}
|
||||
|
||||
ScriptDate::Date ScriptIndustry::GetCargoLastAcceptedDate(IndustryID industry_id, CargoID cargo_type)
|
||||
/* static */ ScriptDate::Date ScriptIndustry::GetCargoLastAcceptedDate(IndustryID industry_id, CargoID cargo_type)
|
||||
{
|
||||
Industry *i = Industry::GetIfValid(industry_id);
|
||||
if (i == nullptr) return ScriptDate::DATE_INVALID;
|
||||
|
||||
if (cargo_type == CT_INVALID) {
|
||||
return (ScriptDate::Date)std::accumulate(std::begin(i->last_cargo_accepted_at), std::end(i->last_cargo_accepted_at), 0, [](Date a, Date b) { return std::max(a, b); });
|
||||
if (!::IsValidCargoID(cargo_type)) {
|
||||
auto it = std::max_element(std::begin(i->accepted), std::end(i->accepted), [](const auto &a, const auto &b) { return a.last_accepted < b.last_accepted; });
|
||||
return (ScriptDate::Date)it->last_accepted.base();
|
||||
} else {
|
||||
int index = i->GetCargoAcceptedIndex(cargo_type);
|
||||
if (index < 0) return ScriptDate::DATE_INVALID;
|
||||
return (ScriptDate::Date)i->last_cargo_accepted_at[index];
|
||||
auto it = i->GetCargoAccepted(cargo_type);
|
||||
if (it == std::end(i->accepted)) return ScriptDate::DATE_INVALID;
|
||||
return (ScriptDate::Date)it->last_accepted.base();
|
||||
}
|
||||
}
|
||||
|
||||
uint32 ScriptIndustry::GetControlFlags(IndustryID industry_id)
|
||||
/* static */ SQInteger ScriptIndustry::GetControlFlags(IndustryID industry_id)
|
||||
{
|
||||
Industry *i = Industry::GetIfValid(industry_id);
|
||||
if (i == nullptr) return 0;
|
||||
return i->ctlflags;
|
||||
}
|
||||
|
||||
bool ScriptIndustry::SetControlFlags(IndustryID industry_id, uint32 control_flags)
|
||||
/* static */ bool ScriptIndustry::SetControlFlags(IndustryID industry_id, SQInteger control_flags)
|
||||
{
|
||||
if (ScriptObject::GetCompany() != OWNER_DEITY) return false;
|
||||
EnforceDeityMode(false);
|
||||
if (!IsValidIndustry(industry_id)) return false;
|
||||
|
||||
return ScriptObject::Command<CMD_INDUSTRY_CTRL>::Do(industry_id, IndustryAction::SetControlFlags, (::IndustryControlFlags)control_flags & ::INDCTL_MASK, INVALID_OWNER, {});
|
||||
return ScriptObject::Command<CMD_INDUSTRY_SET_FLAGS>::Do(industry_id, (::IndustryControlFlags)control_flags & ::INDCTL_MASK);
|
||||
}
|
||||
|
||||
/* static */ ScriptCompany::CompanyID ScriptIndustry::GetExclusiveSupplier(IndustryID industry_id)
|
||||
@@ -273,11 +267,12 @@ bool ScriptIndustry::SetControlFlags(IndustryID industry_id, uint32 control_flag
|
||||
|
||||
/* static */ bool ScriptIndustry::SetExclusiveSupplier(IndustryID industry_id, ScriptCompany::CompanyID company_id)
|
||||
{
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, IsValidIndustry(industry_id));
|
||||
|
||||
auto company = ScriptCompany::ResolveCompanyID(company_id);
|
||||
::Owner owner = (company == ScriptCompany::COMPANY_INVALID ? ::INVALID_OWNER : (::Owner)company);
|
||||
return ScriptObject::Command<CMD_INDUSTRY_CTRL>::Do(industry_id, IndustryAction::SetExclusiveSupplier, INDCTL_NONE, owner, {});
|
||||
return ScriptObject::Command<CMD_INDUSTRY_SET_EXCLUSIVITY>::Do(industry_id, owner, false);
|
||||
}
|
||||
|
||||
/* static */ ScriptCompany::CompanyID ScriptIndustry::GetExclusiveConsumer(IndustryID industry_id)
|
||||
@@ -292,9 +287,28 @@ bool ScriptIndustry::SetControlFlags(IndustryID industry_id, uint32 control_flag
|
||||
|
||||
/* static */ bool ScriptIndustry::SetExclusiveConsumer(IndustryID industry_id, ScriptCompany::CompanyID company_id)
|
||||
{
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, IsValidIndustry(industry_id));
|
||||
|
||||
auto company = ScriptCompany::ResolveCompanyID(company_id);
|
||||
::Owner owner = (company == ScriptCompany::COMPANY_INVALID ? ::INVALID_OWNER : (::Owner)company);
|
||||
return ScriptObject::Command<CMD_INDUSTRY_CTRL>::Do(industry_id, IndustryAction::SetExclusiveConsumer, INDCTL_NONE, owner, {});
|
||||
return ScriptObject::Command<CMD_INDUSTRY_SET_EXCLUSIVITY>::Do(industry_id, owner, true);
|
||||
}
|
||||
|
||||
/* static */ SQInteger ScriptIndustry::GetProductionLevel(IndustryID industry_id)
|
||||
{
|
||||
Industry *i = Industry::GetIfValid(industry_id);
|
||||
if (i == nullptr) return 0;
|
||||
return i->prod_level;
|
||||
}
|
||||
|
||||
/* static */ bool ScriptIndustry::SetProductionLevel(IndustryID industry_id, SQInteger prod_level, bool show_news, Text *custom_news)
|
||||
{
|
||||
CCountedPtr<Text> counter(custom_news);
|
||||
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, IsValidIndustry(industry_id));
|
||||
EnforcePrecondition(false, prod_level >= PRODLEVEL_MINIMUM && prod_level <= PRODLEVEL_MAXIMUM);
|
||||
|
||||
return ScriptObject::Command<CMD_INDUSTRY_SET_PRODUCTION>::Do(industry_id, prod_level, show_news, custom_news != nullptr ? custom_news->GetEncodedText() : std::string{});
|
||||
}
|
||||
|
||||
@@ -47,6 +47,10 @@ public:
|
||||
* This does not prevent a closure already announced.
|
||||
*/
|
||||
INDCTL_NO_CLOSURE = ::INDCTL_NO_CLOSURE,
|
||||
/**
|
||||
* Indicates that the production level of the industry is controlled by a game script.
|
||||
*/
|
||||
INDCTL_EXTERNAL_PROD_LEVEL = ::INDCTL_EXTERNAL_PROD_LEVEL,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -54,7 +58,7 @@ public:
|
||||
* @return The number of industries.
|
||||
* @note The maximum valid IndustryID can be higher than the value returned.
|
||||
*/
|
||||
static int32 GetIndustryCount();
|
||||
static SQInteger GetIndustryCount();
|
||||
|
||||
/**
|
||||
* Checks whether the given industry index is valid.
|
||||
@@ -79,12 +83,22 @@ public:
|
||||
* @pre IsValidIndustry(industry_id).
|
||||
* @return The name of the industry.
|
||||
*/
|
||||
static char *GetName(IndustryID industry_id);
|
||||
static std::optional<std::string> GetName(IndustryID industry_id);
|
||||
|
||||
/**
|
||||
* Get the construction date of an industry.
|
||||
* @param industry_id The index of the industry.
|
||||
* @pre IsValidIndustry(industry_id).
|
||||
* @return Date the industry was constructed.
|
||||
* @api -ai
|
||||
*/
|
||||
static ScriptDate::Date GetConstructionDate(IndustryID industry_id);
|
||||
|
||||
/**
|
||||
* Set the custom text of an industry, shown in the GUI.
|
||||
* @param industry_id The industry to set the custom text of.
|
||||
* @param text The text to set it to (can be either a raw string, or a ScriptText object). If null is passed, the text will be removed.
|
||||
* @param text The text to set it to (can be either a raw string, or a ScriptText object). If null, or an empty string, is passed, the text will be removed.
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @pre IsValidIndustry(industry_id).
|
||||
* @return True if the action succeeded.
|
||||
* @api -ai
|
||||
@@ -109,7 +123,7 @@ public:
|
||||
* @pre ScriptCargo::IsValidCargo(cargo_id).
|
||||
* @return The amount of cargo that is waiting for processing.
|
||||
*/
|
||||
static int32 GetStockpiledCargo(IndustryID industry_id, CargoID cargo_id);
|
||||
static SQInteger GetStockpiledCargo(IndustryID industry_id, CargoID cargo_id);
|
||||
|
||||
/**
|
||||
* Get the total last month's production of the given cargo at an industry.
|
||||
@@ -119,7 +133,7 @@ public:
|
||||
* @pre ScriptCargo::IsValidCargo(cargo_id).
|
||||
* @return The last month's production of the given cargo for this industry.
|
||||
*/
|
||||
static int32 GetLastMonthProduction(IndustryID industry_id, CargoID cargo_id);
|
||||
static SQInteger GetLastMonthProduction(IndustryID industry_id, CargoID cargo_id);
|
||||
|
||||
/**
|
||||
* Get the total amount of cargo transported from an industry last month.
|
||||
@@ -129,7 +143,7 @@ public:
|
||||
* @pre ScriptCargo::IsValidCargo(cargo_id).
|
||||
* @return The amount of given cargo transported from this industry last month.
|
||||
*/
|
||||
static int32 GetLastMonthTransported(IndustryID industry_id, CargoID cargo_id);
|
||||
static SQInteger GetLastMonthTransported(IndustryID industry_id, CargoID cargo_id);
|
||||
|
||||
/**
|
||||
* Get the percentage of cargo transported from an industry last month.
|
||||
@@ -139,7 +153,7 @@ public:
|
||||
* @pre ScriptCargo::IsValidCargo(cargo_id).
|
||||
* @return The percentage of given cargo transported from this industry last month.
|
||||
*/
|
||||
static int32 GetLastMonthTransportedPercentage(IndustryID industry_id, CargoID cargo_id);
|
||||
static SQInteger GetLastMonthTransportedPercentage(IndustryID industry_id, CargoID cargo_id);
|
||||
|
||||
/**
|
||||
* Gets the location of the industry.
|
||||
@@ -157,7 +171,7 @@ public:
|
||||
* @pre IsValidIndustry(industry_id).
|
||||
* @return The number of stations around an industry.
|
||||
*/
|
||||
static int32 GetAmountOfStationsAround(IndustryID industry_id);
|
||||
static SQInteger GetAmountOfStationsAround(IndustryID industry_id);
|
||||
|
||||
/**
|
||||
* Get the manhattan distance from the tile to the ScriptIndustry::GetLocation()
|
||||
@@ -168,7 +182,7 @@ public:
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @return The distance between industry and tile.
|
||||
*/
|
||||
static int32 GetDistanceManhattanToTile(IndustryID industry_id, TileIndex tile);
|
||||
static SQInteger GetDistanceManhattanToTile(IndustryID industry_id, TileIndex tile);
|
||||
|
||||
/**
|
||||
* Get the square distance from the tile to the ScriptIndustry::GetLocation()
|
||||
@@ -179,7 +193,7 @@ public:
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @return The distance between industry and tile.
|
||||
*/
|
||||
static int32 GetDistanceSquareToTile(IndustryID industry_id, TileIndex tile);
|
||||
static SQInteger GetDistanceSquareToTile(IndustryID industry_id, TileIndex tile);
|
||||
|
||||
/**
|
||||
* Is this industry built on water.
|
||||
@@ -238,14 +252,14 @@ public:
|
||||
* @return Year the industry last had production, 0 if error.
|
||||
* @api -ai
|
||||
*/
|
||||
static int32 GetLastProductionYear(IndustryID industry_id);
|
||||
static SQInteger GetLastProductionYear(IndustryID industry_id);
|
||||
|
||||
/**
|
||||
* Get the last date this industry accepted any cargo delivery.
|
||||
* @param industry_id The index of the industry.
|
||||
* @param cargo_type The cargo to query, or CT_INVALID to query latest of all accepted cargoes.
|
||||
* @param cargo_type The cargo to query, or INVALID_CARGO to query latest of all accepted cargoes.
|
||||
* @pre IsValidIndustry(industry_id).
|
||||
* @pre IsValidCargo(cargo_type) || cargo_type == CT_INVALID.
|
||||
* @pre IsValidCargo(cargo_type) || cargo_type == INVALID_CARGO.
|
||||
* @return Date the industry last received cargo from a delivery, or ScriptDate::DATE_INVALID on error.
|
||||
* @api -ai
|
||||
*/
|
||||
@@ -258,18 +272,18 @@ public:
|
||||
* @return Bit flags of the IndustryControlFlags enumeration.
|
||||
* @api -ai
|
||||
*/
|
||||
static uint32 GetControlFlags(IndustryID industry_id);
|
||||
static SQInteger GetControlFlags(IndustryID industry_id);
|
||||
|
||||
/**
|
||||
* Change the control flags for an industry.
|
||||
* @param industry_id The index of the industry.
|
||||
* @param control_flags New flags as a combination of IndustryControlFlags values.
|
||||
* @pre IsValidIndustry(industry_id).
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @return True if the action succeeded.
|
||||
* @api -ai
|
||||
*/
|
||||
static bool SetControlFlags(IndustryID industry_id, uint32 control_flags);
|
||||
static bool SetControlFlags(IndustryID industry_id, SQInteger control_flags);
|
||||
|
||||
/**
|
||||
* Find out which company currently has the exclusive rights to deliver cargo to the industry.
|
||||
@@ -286,6 +300,7 @@ public:
|
||||
* @param industry_id The index of the industry.
|
||||
* @param company_id The company to set (ScriptCompany::COMPANY_INVALID to reset).
|
||||
* @pre IsValidIndustry(industry_id).
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @return True if the action succeeded.
|
||||
* @api -ai
|
||||
*/
|
||||
@@ -306,11 +321,35 @@ public:
|
||||
* @param industry_id The index of the industry.
|
||||
* @param company_id The company to set (ScriptCompany::COMPANY_INVALID to reset).
|
||||
* @pre IsValidIndustry(industry_id).
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @return True if the action succeeded.
|
||||
* @api -ai
|
||||
*/
|
||||
static bool SetExclusiveConsumer(IndustryID industry_id, ScriptCompany::CompanyID company_id);
|
||||
|
||||
/**
|
||||
* Gets the current production level of an industry.
|
||||
* @param industry_id The index of the industry.
|
||||
* @return The current production level of the industry.
|
||||
* @api -ai
|
||||
*/
|
||||
static SQInteger GetProductionLevel(IndustryID industry_id);
|
||||
|
||||
/**
|
||||
* Sets the current production level of an industry.
|
||||
* @note Setting the production level automatically sets the control flag INDCTL_EXTERNAL_PROD_LEVEL if it wasn't already set.
|
||||
* Normal production behaviour can be restored by clearing the control flag.
|
||||
* @param industry_id The index of the industry.
|
||||
* @param prod_level The production level to set.
|
||||
* @param show_news If set to true and the production changed, generate a production change news message. If set to false, no news message is shown.
|
||||
* @param custom_news Custom news message text to override the default news text with. Pass null to use the default text. Only used if \c show_news is set to true.
|
||||
* @pre IsValidIndustry(industry_id).
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @pre prod_level >= 4 && prod_level <= 128.
|
||||
* @return True if the action succeeded.
|
||||
* @api -ai
|
||||
*/
|
||||
static bool SetProductionLevel(IndustryID industry_id, SQInteger prod_level, bool show_news, Text *custom_news);
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_INDUSTRY_HPP */
|
||||
|
||||
@@ -13,27 +13,21 @@
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
ScriptIndustryList::ScriptIndustryList()
|
||||
ScriptIndustryList::ScriptIndustryList(HSQUIRRELVM vm)
|
||||
{
|
||||
for (const Industry *i : Industry::Iterate()) {
|
||||
this->AddItem(i->index);
|
||||
}
|
||||
ScriptList::FillList<Industry>(vm, this);
|
||||
}
|
||||
|
||||
ScriptIndustryList_CargoAccepting::ScriptIndustryList_CargoAccepting(CargoID cargo_id)
|
||||
{
|
||||
for (const Industry *i : Industry::Iterate()) {
|
||||
for (byte j = 0; j < lengthof(i->accepts_cargo); j++) {
|
||||
if (i->accepts_cargo[j] == cargo_id) this->AddItem(i->index);
|
||||
}
|
||||
}
|
||||
ScriptList::FillList<Industry>(this,
|
||||
[cargo_id](const Industry *i) { return i->IsCargoAccepted(cargo_id); }
|
||||
);
|
||||
}
|
||||
|
||||
ScriptIndustryList_CargoProducing::ScriptIndustryList_CargoProducing(CargoID cargo_id)
|
||||
{
|
||||
for (const Industry *i : Industry::Iterate()) {
|
||||
for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
|
||||
if (i->produced_cargo[j] == cargo_id) this->AddItem(i->index);
|
||||
}
|
||||
}
|
||||
ScriptList::FillList<Industry>(this,
|
||||
[cargo_id](const Industry *i) { return i->IsCargoProduced(cargo_id); }
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,32 @@
|
||||
*/
|
||||
class ScriptIndustryList : public ScriptList {
|
||||
public:
|
||||
#ifdef DOXYGEN_API
|
||||
ScriptIndustryList();
|
||||
|
||||
/**
|
||||
* Apply a filter when building the list.
|
||||
* @param filter_function The function which will be doing the filtering.
|
||||
* @param params The params to give to the filters (minus the first param,
|
||||
* which is always the index-value).
|
||||
* @note You can write your own filters and use them. Just remember that
|
||||
* the first parameter should be the index-value, and it should return
|
||||
* a bool.
|
||||
* @note Example:
|
||||
* ScriptIndustryList(ScriptIndustry.HasDock);
|
||||
* function IsType(industry_id, type)
|
||||
* {
|
||||
* return ScriptIndustry.GetIndustryType(industry_id) == type;
|
||||
* }
|
||||
* ScriptIndustryList(IsType, 0);
|
||||
*/
|
||||
ScriptIndustryList(void *filter_function, int params, ...);
|
||||
#else
|
||||
/**
|
||||
* The constructor wrapper from Squirrel.
|
||||
*/
|
||||
ScriptIndustryList(HSQUIRRELVM vm);
|
||||
#endif /* DOXYGEN_API */
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "../../stdafx.h"
|
||||
#include "script_industrytype.hpp"
|
||||
#include "script_base.hpp"
|
||||
#include "script_map.hpp"
|
||||
#include "script_error.hpp"
|
||||
#include "../../strings_func.h"
|
||||
@@ -56,9 +57,9 @@
|
||||
return ::GetIndustrySpec(industry_type)->GetConstructionCost();
|
||||
}
|
||||
|
||||
/* static */ char *ScriptIndustryType::GetName(IndustryType industry_type)
|
||||
/* static */ std::optional<std::string> ScriptIndustryType::GetName(IndustryType industry_type)
|
||||
{
|
||||
if (!IsValidIndustryType(industry_type)) return nullptr;
|
||||
if (!IsValidIndustryType(industry_type)) return std::nullopt;
|
||||
|
||||
return GetString(::GetIndustrySpec(industry_type)->name);
|
||||
}
|
||||
@@ -70,8 +71,8 @@
|
||||
const IndustrySpec *ins = ::GetIndustrySpec(industry_type);
|
||||
|
||||
ScriptList *list = new ScriptList();
|
||||
for (size_t i = 0; i < lengthof(ins->produced_cargo); i++) {
|
||||
if (ins->produced_cargo[i] != CT_INVALID) list->AddItem(ins->produced_cargo[i]);
|
||||
for (const CargoID &c : ins->produced_cargo) {
|
||||
if (::IsValidCargoID(c)) list->AddItem(c);
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -84,8 +85,8 @@
|
||||
const IndustrySpec *ins = ::GetIndustrySpec(industry_type);
|
||||
|
||||
ScriptList *list = new ScriptList();
|
||||
for (size_t i = 0; i < lengthof(ins->accepts_cargo); i++) {
|
||||
if (ins->accepts_cargo[i] != CT_INVALID) list->AddItem(ins->accepts_cargo[i]);
|
||||
for (const CargoID &c : ins->accepts_cargo) {
|
||||
if (::IsValidCargoID(c)) list->AddItem(c);
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -95,7 +96,7 @@
|
||||
{
|
||||
if (!IsValidIndustryType(industry_type)) return false;
|
||||
|
||||
const bool deity = ScriptObject::GetCompany() == OWNER_DEITY;
|
||||
const bool deity = ScriptCompanyMode::IsDeity();
|
||||
if (::GetIndustryProbabilityCallback(industry_type, deity ? IACT_RANDOMCREATION : IACT_USERCREATION, 1) == 0) return false;
|
||||
if (deity) return true;
|
||||
if (!::GetIndustrySpec(industry_type)->IsRawIndustry()) return true;
|
||||
@@ -108,7 +109,7 @@
|
||||
{
|
||||
if (!IsValidIndustryType(industry_type)) return false;
|
||||
|
||||
const bool deity = ScriptObject::GetCompany() == OWNER_DEITY;
|
||||
const bool deity = ScriptCompanyMode::IsDeity();
|
||||
if (!deity && !::GetIndustrySpec(industry_type)->IsRawIndustry()) return false;
|
||||
if (::GetIndustryProbabilityCallback(industry_type, deity ? IACT_RANDOMCREATION : IACT_USERCREATION, 1) == 0) return false;
|
||||
|
||||
@@ -118,19 +119,21 @@
|
||||
|
||||
/* static */ bool ScriptIndustryType::BuildIndustry(IndustryType industry_type, TileIndex tile)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
EnforcePrecondition(false, CanBuildIndustry(industry_type));
|
||||
EnforcePrecondition(false, ScriptMap::IsValidTile(tile));
|
||||
|
||||
uint32 seed = ::InteractiveRandom();
|
||||
uint32 layout_index = ::InteractiveRandomRange((uint32)::GetIndustrySpec(industry_type)->layouts.size());
|
||||
uint32_t seed = ScriptBase::Rand();
|
||||
uint32_t layout_index = ScriptBase::RandRange((uint32_t)::GetIndustrySpec(industry_type)->layouts.size());
|
||||
return ScriptObject::Command<CMD_BUILD_INDUSTRY>::Do(tile, industry_type, layout_index, true, seed);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptIndustryType::ProspectIndustry(IndustryType industry_type)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
EnforcePrecondition(false, CanProspectIndustry(industry_type));
|
||||
|
||||
uint32 seed = ::InteractiveRandom();
|
||||
uint32_t seed = ScriptBase::Rand();
|
||||
return ScriptObject::Command<CMD_BUILD_INDUSTRY>::Do(0, industry_type, 0, false, seed);
|
||||
}
|
||||
|
||||
@@ -155,10 +158,10 @@
|
||||
return (::GetIndustrySpec(industry_type)->behaviour & INDUSTRYBEH_AI_AIRSHIP_ROUTES) != 0;
|
||||
}
|
||||
|
||||
/* static */ IndustryType ScriptIndustryType::ResolveNewGRFID(uint32 grfid, uint16 grf_local_id)
|
||||
/* static */ IndustryType ScriptIndustryType::ResolveNewGRFID(SQInteger grfid, SQInteger grf_local_id)
|
||||
{
|
||||
EnforcePrecondition(INVALID_INDUSTRYTYPE, IsInsideBS(grf_local_id, 0x00, NUM_INDUSTRYTYPES_PER_GRF));
|
||||
|
||||
grfid = BSWAP32(grfid); // Match people's expectations.
|
||||
grfid = BSWAP32(GB(grfid, 0, 32)); // Match people's expectations.
|
||||
return _industry_mngr.GetID(grf_local_id, grfid);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
* @pre IsValidIndustryType(industry_type).
|
||||
* @return The name of an industry.
|
||||
*/
|
||||
static char *GetName(IndustryType industry_type);
|
||||
static std::optional<std::string> GetName(IndustryType industry_type);
|
||||
|
||||
/**
|
||||
* Get a list of CargoID possible produced by this industry-type.
|
||||
@@ -111,9 +111,9 @@ public:
|
||||
* @pre IsValidIndustryType(industry_type).
|
||||
* @return True if you can build this type of industry at locations of your choice.
|
||||
* @ai @note Returns false if you can only prospect this type of industry, or not build it at all.
|
||||
* @game @note If no valid ScriptCompanyMode active in scope, this method returns false if you can
|
||||
* @game @note When ScriptCompanyMode::IsDeity, this method returns false if you can
|
||||
* @game only prospect this type of industry, or not build it at all.
|
||||
* @game @note If no valid ScriptCompanyMode active in scope, the script can
|
||||
* @game @note When ScriptCompanyMode::IsDeity, the script can
|
||||
* @game build as long as the industry type can be built. (a NewGRF can for example
|
||||
* @game reject construction based on current year)
|
||||
*/
|
||||
@@ -126,10 +126,10 @@ public:
|
||||
* @return True if you can prospect this type of industry.
|
||||
* @ai @note If the setting "Manual primary industry construction method" is set
|
||||
* @ai to either "None" or "as other industries" this function always returns false.
|
||||
* @game @note If no valid ScriptCompanyMode is active in scope, and if the setting
|
||||
* @game @note When ScriptCompanyMode::IsDeity, and if the setting
|
||||
* @game "Manual primary industry construction method" is set to either "None" or
|
||||
* @game "as other industries" this function always returns false.
|
||||
* @game @note If no valid ScriptCompanyMode active in scope, the script can
|
||||
* @game @note When ScriptCompanyMode::IsDeity, the script can
|
||||
* @game prospect as long as the industry type can be built. (a NewGRF can for
|
||||
* @game example reject construction based on current year)
|
||||
*/
|
||||
@@ -152,7 +152,7 @@ public:
|
||||
* @return True if no error occurred while trying to prospect.
|
||||
* @note Even if true is returned there is no guarantee a new industry is build.
|
||||
* @note If true is returned the money is paid, whether a new industry was build or not.
|
||||
* @game @note if no valid ScriptCompanyMode exist in scope, prospection will not fail
|
||||
* @game @note When ScriptCompanyMode::IsDeity, prospection will not fail
|
||||
* @game due to the general chance that prospection may fail. However prospection can still
|
||||
* @game fail if OpenTTD is unable to find a suitable location to place the industry.
|
||||
*/
|
||||
@@ -189,7 +189,7 @@ public:
|
||||
* @pre 0x00 <= grf_local_id < NUM_INDUSTRYTYPES_PER_GRF.
|
||||
* @return the industry-type ID, local to the current game (this diverges from the grf_local_id).
|
||||
*/
|
||||
static IndustryType ResolveNewGRFID(uint32 grfid, uint16 grf_local_id);
|
||||
static IndustryType ResolveNewGRFID(SQInteger grfid, SQInteger grf_local_id);
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_INDUSTRYTYPE_HPP */
|
||||
|
||||
@@ -203,7 +203,6 @@ public:
|
||||
/** Miscellaneous flags for Script settings. */
|
||||
enum ScriptConfigFlags {
|
||||
CONFIG_NONE, ///< Normal setting.
|
||||
CONFIG_RANDOM, ///< When randomizing the Script, pick any value between min_value and max_value (inclusive).
|
||||
CONFIG_BOOLEAN, ///< This value is a boolean (either 0 (false) or 1 (true) ).
|
||||
CONFIG_INGAME, ///< This setting can be changed while the Script is running.
|
||||
CONFIG_DEVELOPER, ///< This setting will only be visible when the Script development tools are active.
|
||||
@@ -219,27 +218,18 @@ public:
|
||||
* - description A single line describing the setting. Required.
|
||||
* - min_value The minimum value of this setting. Required for integer
|
||||
* settings and not allowed for boolean settings. The value will be
|
||||
* clamped in the range [MIN(int32), MAX(int32)] (inclusive).
|
||||
* clamped in the range [MIN(int32_t), MAX(int32_t)] (inclusive).
|
||||
* - max_value The maximum value of this setting. Required for integer
|
||||
* settings and not allowed for boolean settings. The value will be
|
||||
* clamped in the range [MIN(int32), MAX(int32)] (inclusive).
|
||||
* - easy_value The default value if the easy difficulty level
|
||||
* is selected. Required. The value will be clamped in the range
|
||||
* [MIN(int32), MAX(int32)] (inclusive).
|
||||
* - medium_value The default value if the medium difficulty level
|
||||
* is selected. Required. The value will be clamped in the range
|
||||
* [MIN(int32), MAX(int32)] (inclusive).
|
||||
* - hard_value The default value if the hard difficulty level
|
||||
* is selected. Required. The value will be clamped in the range
|
||||
* [MIN(int32), MAX(int32)] (inclusive).
|
||||
* - custom_value The default value if the custom difficulty level
|
||||
* is selected. Required. The value will be clamped in the range
|
||||
* [MIN(int32), MAX(int32)] (inclusive).
|
||||
* clamped in the range [MIN(int32_t), MAX(int32_t)] (inclusive).
|
||||
* - default_value The default value. Required. The value will be
|
||||
* clamped in the range [MIN(int32_t), MAX(int32_t)] (inclusive).
|
||||
* - random_deviation If this property has a nonzero value, then the
|
||||
* actual value of the setting in game will be randomized in the range
|
||||
* actual value of the setting in game will be randomised in the range
|
||||
* [user_configured_value - random_deviation, user_configured_value + random_deviation] (inclusive).
|
||||
* random_deviation sign is ignored and the value is clamped in the range [0, MAX(int32)] (inclusive).
|
||||
* Not allowed if the CONFIG_RANDOM flag is set, otherwise optional.
|
||||
* random_deviation sign is ignored and the value is clamped in the range [0, MAX(int32_t)] (inclusive).
|
||||
* The randomisation will happen just before the Script start.
|
||||
* Not allowed if the CONFIG_BOOLEAN flag is set, otherwise optional.
|
||||
* - step_size The increase/decrease of the value every time the user
|
||||
* clicks one of the up/down arrow buttons. Optional, default is 1.
|
||||
* - flags Bitmask of some flags, see ScriptConfigFlags. Required.
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "../../safeguards.h"
|
||||
|
||||
|
||||
/* static */ uint32 ScriptInfrastructure::GetRailPieceCount(ScriptCompany::CompanyID company, ScriptRail::RailType railtype)
|
||||
/* static */ SQInteger ScriptInfrastructure::GetRailPieceCount(ScriptCompany::CompanyID company, ScriptRail::RailType railtype)
|
||||
{
|
||||
company = ScriptCompany::ResolveCompanyID(company);
|
||||
if (company == ScriptCompany::COMPANY_INVALID || (::RailType)railtype >= RAILTYPE_END) return 0;
|
||||
@@ -26,7 +26,7 @@
|
||||
return ::Company::Get((::CompanyID)company)->infrastructure.rail[railtype];
|
||||
}
|
||||
|
||||
/* static */ uint32 ScriptInfrastructure::GetRoadPieceCount(ScriptCompany::CompanyID company, ScriptRoad::RoadType roadtype)
|
||||
/* static */ SQInteger ScriptInfrastructure::GetRoadPieceCount(ScriptCompany::CompanyID company, ScriptRoad::RoadType roadtype)
|
||||
{
|
||||
company = ScriptCompany::ResolveCompanyID(company);
|
||||
if (company == ScriptCompany::COMPANY_INVALID || (::RoadType)roadtype >= ROADTYPE_END) return 0;
|
||||
@@ -34,31 +34,21 @@
|
||||
return ::Company::Get((::CompanyID)company)->infrastructure.road[roadtype];
|
||||
}
|
||||
|
||||
/* static */ uint32 ScriptInfrastructure::GetInfrastructurePieceCount(ScriptCompany::CompanyID company, Infrastructure infra_type)
|
||||
/* static */ SQInteger ScriptInfrastructure::GetInfrastructurePieceCount(ScriptCompany::CompanyID company, Infrastructure infra_type)
|
||||
{
|
||||
company = ScriptCompany::ResolveCompanyID(company);
|
||||
if (company == ScriptCompany::COMPANY_INVALID) return 0;
|
||||
|
||||
::Company *c = ::Company::Get((::CompanyID)company);
|
||||
switch (infra_type) {
|
||||
case INFRASTRUCTURE_RAIL: {
|
||||
uint32 count = 0;
|
||||
for (::RailType rt = ::RAILTYPE_BEGIN; rt != ::RAILTYPE_END; rt++) {
|
||||
count += c->infrastructure.rail[rt];
|
||||
}
|
||||
return count;
|
||||
}
|
||||
case INFRASTRUCTURE_RAIL:
|
||||
return c->infrastructure.GetRailTotal();
|
||||
|
||||
case INFRASTRUCTURE_SIGNALS:
|
||||
return c->infrastructure.signal;
|
||||
|
||||
case INFRASTRUCTURE_ROAD: {
|
||||
uint32 count = 0;
|
||||
for (::RoadType rt = ::ROADTYPE_BEGIN; rt != ::ROADTYPE_END; rt++) {
|
||||
count += c->infrastructure.road[rt];
|
||||
}
|
||||
return count;
|
||||
}
|
||||
case INFRASTRUCTURE_ROAD:
|
||||
return c->infrastructure.GetRoadTotal() + c->infrastructure.GetTramTotal();
|
||||
|
||||
case INFRASTRUCTURE_CANAL:
|
||||
return c->infrastructure.water;
|
||||
@@ -101,7 +91,7 @@
|
||||
switch (infra_type) {
|
||||
case INFRASTRUCTURE_RAIL: {
|
||||
Money cost;
|
||||
uint32 rail_total = c->infrastructure.GetRailTotal();
|
||||
uint32_t rail_total = c->infrastructure.GetRailTotal();
|
||||
for (::RailType rt = ::RAILTYPE_BEGIN; rt != ::RAILTYPE_END; rt++) {
|
||||
cost += RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total);
|
||||
}
|
||||
@@ -113,7 +103,7 @@
|
||||
|
||||
case INFRASTRUCTURE_ROAD: {
|
||||
Money cost;
|
||||
uint32 road_total = c->infrastructure.GetRoadTotal();
|
||||
uint32_t road_total = c->infrastructure.GetRoadTotal();
|
||||
for (::RoadType rt = ::ROADTYPE_BEGIN; rt != ::ROADTYPE_END; rt++) {
|
||||
cost += RoadMaintenanceCost(rt, c->infrastructure.road[rt], road_total);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
* @param railtype Rail type to get the count of.
|
||||
* @return Count for the rail type.
|
||||
*/
|
||||
static uint32 GetRailPieceCount(ScriptCompany::CompanyID company, ScriptRail::RailType railtype);
|
||||
static SQInteger GetRailPieceCount(ScriptCompany::CompanyID company, ScriptRail::RailType railtype);
|
||||
|
||||
/**
|
||||
* Return the number of road pieces of a specific road type for a company.
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
* @param roadtype Road type to get the count of.
|
||||
* @return Count for the road type.
|
||||
*/
|
||||
static uint32 GetRoadPieceCount(ScriptCompany::CompanyID company, ScriptRoad::RoadType roadtype);
|
||||
static SQInteger GetRoadPieceCount(ScriptCompany::CompanyID company, ScriptRoad::RoadType roadtype);
|
||||
|
||||
/**
|
||||
* Return the number of pieces of an infrastructure category for a company.
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
* @return Count for the wanted category.
|
||||
* @note #INFRASTRUCTURE_RAIL and #INFRASTRUCTURE_ROAD return the total count for all rail/road types.
|
||||
*/
|
||||
static uint32 GetInfrastructurePieceCount(ScriptCompany::CompanyID company, Infrastructure infra_type);
|
||||
static SQInteger GetInfrastructurePieceCount(ScriptCompany::CompanyID company, Infrastructure infra_type);
|
||||
|
||||
/**
|
||||
* Return the monthly maintenance costs of a specific rail type for a company.
|
||||
|
||||
@@ -30,13 +30,13 @@
|
||||
CCountedPtr<Text> header_counter(header);
|
||||
CCountedPtr<Text> footer_counter(footer);
|
||||
|
||||
EnforcePrecondition(LEAGUE_TABLE_INVALID, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforceDeityMode(LEAGUE_TABLE_INVALID);
|
||||
EnforcePrecondition(LEAGUE_TABLE_INVALID, title != nullptr);
|
||||
const char *encoded_title = title->GetEncodedText();
|
||||
std::string encoded_title = title->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(LEAGUE_TABLE_INVALID, encoded_title);
|
||||
|
||||
auto encoded_header = (header != nullptr ? std::string{ header->GetEncodedText() } : std::string{});
|
||||
auto encoded_footer = (footer != nullptr ? std::string{ footer->GetEncodedText() } : std::string{});
|
||||
std::string encoded_header = (header != nullptr ? header->GetEncodedText() : std::string{});
|
||||
std::string encoded_footer = (footer != nullptr ? footer->GetEncodedText() : std::string{});
|
||||
|
||||
if (!ScriptObject::Command<CMD_CREATE_LEAGUE_TABLE>::Do(&ScriptInstance::DoCommandReturnLeagueTableID, encoded_title, encoded_header, encoded_footer)) return LEAGUE_TABLE_INVALID;
|
||||
|
||||
@@ -49,12 +49,12 @@
|
||||
return ::LeagueTableElement::IsValidID(element_id);
|
||||
}
|
||||
|
||||
/* static */ ScriptLeagueTable::LeagueTableElementID ScriptLeagueTable::NewElement(ScriptLeagueTable::LeagueTableID table, int64 rating, ScriptCompany::CompanyID company, Text *text, Text *score, LinkType link_type, uint32 link_target)
|
||||
/* static */ ScriptLeagueTable::LeagueTableElementID ScriptLeagueTable::NewElement(ScriptLeagueTable::LeagueTableID table, SQInteger rating, ScriptCompany::CompanyID company, Text *text, Text *score, LinkType link_type, LinkTargetID link_target)
|
||||
{
|
||||
CCountedPtr<Text> text_counter(text);
|
||||
CCountedPtr<Text> score_counter(score);
|
||||
|
||||
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforceDeityMode(LEAGUE_TABLE_ELEMENT_INVALID);
|
||||
|
||||
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, IsValidLeagueTable(table));
|
||||
|
||||
@@ -63,12 +63,11 @@
|
||||
if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY;
|
||||
|
||||
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, text != nullptr);
|
||||
const char *encoded_text_ptr = text->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(LEAGUE_TABLE_ELEMENT_INVALID, encoded_text_ptr);
|
||||
std::string encoded_text = encoded_text_ptr; // save into string so GetEncodedText can reuse the internal buffer
|
||||
std::string encoded_text = text->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(LEAGUE_TABLE_ELEMENT_INVALID, encoded_text);
|
||||
|
||||
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, score != nullptr);
|
||||
const char *encoded_score = score->GetEncodedText();
|
||||
std::string encoded_score = score->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(LEAGUE_TABLE_ELEMENT_INVALID, encoded_score);
|
||||
|
||||
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, IsValidLink(Link((::LinkType)link_type, link_target)));
|
||||
@@ -83,7 +82,7 @@
|
||||
{
|
||||
CCountedPtr<Text> text_counter(text);
|
||||
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, IsValidLeagueTableElement(element));
|
||||
|
||||
EnforcePrecondition(false, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID);
|
||||
@@ -91,7 +90,7 @@
|
||||
if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY;
|
||||
|
||||
EnforcePrecondition(false, text != nullptr);
|
||||
const char *encoded_text = text->GetEncodedText();
|
||||
std::string encoded_text = text->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(false, encoded_text);
|
||||
|
||||
EnforcePrecondition(false, IsValidLink(Link((::LinkType)link_type, link_target)));
|
||||
@@ -99,15 +98,15 @@
|
||||
return ScriptObject::Command<CMD_UPDATE_LEAGUE_TABLE_ELEMENT_DATA>::Do(element, c, encoded_text, (::LinkType)link_type, (::LinkTargetID)link_target);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptLeagueTable::UpdateElementScore(LeagueTableElementID element, int64 rating, Text *score)
|
||||
/* static */ bool ScriptLeagueTable::UpdateElementScore(LeagueTableElementID element, SQInteger rating, Text *score)
|
||||
{
|
||||
CCountedPtr<Text> score_counter(score);
|
||||
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, IsValidLeagueTableElement(element));
|
||||
|
||||
EnforcePrecondition(false, score != nullptr);
|
||||
const char *encoded_score = score->GetEncodedText();
|
||||
std::string encoded_score = score->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(false, encoded_score);
|
||||
|
||||
return ScriptObject::Command<CMD_UPDATE_LEAGUE_TABLE_ELEMENT_SCORE>::Do(element, rating, encoded_score);
|
||||
@@ -115,7 +114,7 @@
|
||||
|
||||
/* static */ bool ScriptLeagueTable::RemoveElement(LeagueTableElementID element)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, IsValidLeagueTableElement(element));
|
||||
|
||||
return ScriptObject::Command<CMD_REMOVE_LEAGUE_TABLE_ELEMENT>::Do(element);
|
||||
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
* @param header The optional header text for the table (null is allowed).
|
||||
* @param footer The optional footer text for the table (null is allowed).
|
||||
* @return The new LeagueTableID, or LEAGUE_TABLE_INVALID if it failed.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre ScriptCompanyMode::IsDeity.
|
||||
* @pre title != null && len(title) != 0.
|
||||
*/
|
||||
static LeagueTableID New(Text *title, Text *header, Text *footer);
|
||||
@@ -86,13 +86,13 @@ public:
|
||||
* @param link_type Type of the referenced object.
|
||||
* @param link_target Id of the referenced object.
|
||||
* @return The new LeagueTableElementID, or LEAGUE_TABLE_ELEMENT_INVALID if it failed.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre ScriptCompanyMode::IsDeity.
|
||||
* @pre IsValidLeagueTable(table).
|
||||
* @pre text != null && len(text) != 0.
|
||||
* @pre score != null && len(score) != 0.
|
||||
* @pre IsValidLink(Link(link_type, link_target)).
|
||||
*/
|
||||
static LeagueTableElementID NewElement(LeagueTableID table, int64 rating, ScriptCompany::CompanyID company, Text *text, Text *score, LinkType link_type, LinkTargetID link_target);
|
||||
static LeagueTableElementID NewElement(LeagueTableID table, SQInteger rating, ScriptCompany::CompanyID company, Text *text, Text *score, LinkType link_type, LinkTargetID link_target);
|
||||
|
||||
/**
|
||||
* Update the attributes of a league table element.
|
||||
@@ -102,7 +102,7 @@ public:
|
||||
* @param link_type Type of the referenced object.
|
||||
* @param link_target Id of the referenced object.
|
||||
* @return True if the action succeeded.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre ScriptCompanyMode::IsDeity.
|
||||
* @pre IsValidLeagueTableElement(element).
|
||||
* @pre text != null && len(text) != 0.
|
||||
* @pre IsValidLink(Link(link_type, link_target)).
|
||||
@@ -115,18 +115,18 @@ public:
|
||||
* @param rating Value that elements are ordered by.
|
||||
* @param score String representation of the score associated with the element (can be either a raw string, or ScriptText object).
|
||||
* @return True if the action succeeded.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre ScriptCompanyMode::IsDeity.
|
||||
* @pre IsValidLeagueTableElement(element).
|
||||
* @pre score != null && len(score) != 0.
|
||||
*/
|
||||
static bool UpdateElementScore(LeagueTableElementID element, int64 rating, Text *score);
|
||||
static bool UpdateElementScore(LeagueTableElementID element, SQInteger rating, Text *score);
|
||||
|
||||
|
||||
/**
|
||||
* Remove a league table element.
|
||||
* @param element Id of the element to update
|
||||
* @return True if the action succeeded.
|
||||
* @pre No ScriptCompanyMode may be in scope.
|
||||
* @pre ScriptCompanyMode::IsDeity.
|
||||
* @pre IsValidLeagueTableElement(element).
|
||||
*/
|
||||
static bool RemoveElement(LeagueTableElementID element);
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#include "../../stdafx.h"
|
||||
#include "script_list.hpp"
|
||||
#include "script_controller.hpp"
|
||||
#include "../../debug.h"
|
||||
#include "../../script/squirrel.hpp"
|
||||
|
||||
@@ -22,18 +21,18 @@ class ScriptListSorter {
|
||||
protected:
|
||||
ScriptList *list; ///< The list that's being sorted.
|
||||
bool has_no_more_items; ///< Whether we have more items to iterate over.
|
||||
int64 item_next; ///< The next item we will show.
|
||||
SQInteger item_next; ///< The next item we will show.
|
||||
|
||||
public:
|
||||
/**
|
||||
* Virtual dtor, needed to mute warnings.
|
||||
*/
|
||||
virtual ~ScriptListSorter() { }
|
||||
virtual ~ScriptListSorter() = default;
|
||||
|
||||
/**
|
||||
* Get the first item of the sorter.
|
||||
*/
|
||||
virtual int64 Begin() = 0;
|
||||
virtual SQInteger Begin() = 0;
|
||||
|
||||
/**
|
||||
* Stop iterating a sorter.
|
||||
@@ -43,7 +42,7 @@ public:
|
||||
/**
|
||||
* Get the next item of the sorter.
|
||||
*/
|
||||
virtual int64 Next() = 0;
|
||||
virtual SQInteger Next() = 0;
|
||||
|
||||
/**
|
||||
* See if the sorter has reached the end.
|
||||
@@ -56,7 +55,7 @@ public:
|
||||
/**
|
||||
* Callback from the list if an item gets removed.
|
||||
*/
|
||||
virtual void Remove(int item) = 0;
|
||||
virtual void Remove(SQInteger item) = 0;
|
||||
|
||||
/**
|
||||
* Attach the sorter to a new list. This assumes the content of the old list has been moved to
|
||||
@@ -90,7 +89,7 @@ public:
|
||||
this->End();
|
||||
}
|
||||
|
||||
int64 Begin()
|
||||
SQInteger Begin() override
|
||||
{
|
||||
if (this->list->buckets.empty()) return 0;
|
||||
this->has_no_more_items = false;
|
||||
@@ -100,12 +99,12 @@ public:
|
||||
this->bucket_list_iter = this->bucket_list->begin();
|
||||
this->item_next = *this->bucket_list_iter;
|
||||
|
||||
int64 item_current = this->item_next;
|
||||
SQInteger item_current = this->item_next;
|
||||
FindNext();
|
||||
return item_current;
|
||||
}
|
||||
|
||||
void End()
|
||||
void End() override
|
||||
{
|
||||
this->bucket_list = nullptr;
|
||||
this->has_no_more_items = true;
|
||||
@@ -135,16 +134,16 @@ public:
|
||||
this->item_next = *this->bucket_list_iter;
|
||||
}
|
||||
|
||||
int64 Next()
|
||||
SQInteger Next() override
|
||||
{
|
||||
if (this->IsEnd()) return 0;
|
||||
|
||||
int64 item_current = this->item_next;
|
||||
SQInteger item_current = this->item_next;
|
||||
FindNext();
|
||||
return item_current;
|
||||
}
|
||||
|
||||
void Remove(int item)
|
||||
void Remove(SQInteger item) override
|
||||
{
|
||||
if (this->IsEnd()) return;
|
||||
|
||||
@@ -179,7 +178,7 @@ public:
|
||||
this->End();
|
||||
}
|
||||
|
||||
int64 Begin()
|
||||
SQInteger Begin() override
|
||||
{
|
||||
if (this->list->buckets.empty()) return 0;
|
||||
this->has_no_more_items = false;
|
||||
@@ -194,12 +193,12 @@ public:
|
||||
--this->bucket_list_iter;
|
||||
this->item_next = *this->bucket_list_iter;
|
||||
|
||||
int64 item_current = this->item_next;
|
||||
SQInteger item_current = this->item_next;
|
||||
FindNext();
|
||||
return item_current;
|
||||
}
|
||||
|
||||
void End()
|
||||
void End() override
|
||||
{
|
||||
this->bucket_list = nullptr;
|
||||
this->has_no_more_items = true;
|
||||
@@ -232,16 +231,16 @@ public:
|
||||
this->item_next = *this->bucket_list_iter;
|
||||
}
|
||||
|
||||
int64 Next()
|
||||
SQInteger Next() override
|
||||
{
|
||||
if (this->IsEnd()) return 0;
|
||||
|
||||
int64 item_current = this->item_next;
|
||||
SQInteger item_current = this->item_next;
|
||||
FindNext();
|
||||
return item_current;
|
||||
}
|
||||
|
||||
void Remove(int item)
|
||||
void Remove(SQInteger item) override
|
||||
{
|
||||
if (this->IsEnd()) return;
|
||||
|
||||
@@ -271,7 +270,7 @@ public:
|
||||
this->End();
|
||||
}
|
||||
|
||||
int64 Begin()
|
||||
SQInteger Begin() override
|
||||
{
|
||||
if (this->list->items.empty()) return 0;
|
||||
this->has_no_more_items = false;
|
||||
@@ -279,12 +278,12 @@ public:
|
||||
this->item_iter = this->list->items.begin();
|
||||
this->item_next = (*this->item_iter).first;
|
||||
|
||||
int64 item_current = this->item_next;
|
||||
SQInteger item_current = this->item_next;
|
||||
FindNext();
|
||||
return item_current;
|
||||
}
|
||||
|
||||
void End()
|
||||
void End() override
|
||||
{
|
||||
this->has_no_more_items = true;
|
||||
}
|
||||
@@ -302,16 +301,16 @@ public:
|
||||
if (this->item_iter != this->list->items.end()) item_next = (*this->item_iter).first;
|
||||
}
|
||||
|
||||
int64 Next()
|
||||
SQInteger Next() override
|
||||
{
|
||||
if (this->IsEnd()) return 0;
|
||||
|
||||
int64 item_current = this->item_next;
|
||||
SQInteger item_current = this->item_next;
|
||||
FindNext();
|
||||
return item_current;
|
||||
}
|
||||
|
||||
void Remove(int item)
|
||||
void Remove(SQInteger item) override
|
||||
{
|
||||
if (this->IsEnd()) return;
|
||||
|
||||
@@ -344,7 +343,7 @@ public:
|
||||
this->End();
|
||||
}
|
||||
|
||||
int64 Begin()
|
||||
SQInteger Begin() override
|
||||
{
|
||||
if (this->list->items.empty()) return 0;
|
||||
this->has_no_more_items = false;
|
||||
@@ -353,12 +352,12 @@ public:
|
||||
--this->item_iter;
|
||||
this->item_next = (*this->item_iter).first;
|
||||
|
||||
int64 item_current = this->item_next;
|
||||
SQInteger item_current = this->item_next;
|
||||
FindNext();
|
||||
return item_current;
|
||||
}
|
||||
|
||||
void End()
|
||||
void End() override
|
||||
{
|
||||
this->has_no_more_items = true;
|
||||
}
|
||||
@@ -381,16 +380,16 @@ public:
|
||||
if (this->item_iter != this->list->items.end()) item_next = (*this->item_iter).first;
|
||||
}
|
||||
|
||||
int64 Next()
|
||||
SQInteger Next() override
|
||||
{
|
||||
if (this->IsEnd()) return 0;
|
||||
|
||||
int64 item_current = this->item_next;
|
||||
SQInteger item_current = this->item_next;
|
||||
FindNext();
|
||||
return item_current;
|
||||
}
|
||||
|
||||
void Remove(int item)
|
||||
void Remove(SQInteger item) override
|
||||
{
|
||||
if (this->IsEnd()) return;
|
||||
|
||||
@@ -419,7 +418,7 @@ ScriptList::~ScriptList()
|
||||
delete this->sorter;
|
||||
}
|
||||
|
||||
bool ScriptList::HasItem(int64 item)
|
||||
bool ScriptList::HasItem(SQInteger item)
|
||||
{
|
||||
return this->items.count(item) == 1;
|
||||
}
|
||||
@@ -433,7 +432,7 @@ void ScriptList::Clear()
|
||||
this->sorter->End();
|
||||
}
|
||||
|
||||
void ScriptList::AddItem(int64 item, int64 value)
|
||||
void ScriptList::AddItem(SQInteger item, SQInteger value)
|
||||
{
|
||||
this->modifications++;
|
||||
|
||||
@@ -443,14 +442,14 @@ void ScriptList::AddItem(int64 item, int64 value)
|
||||
this->buckets[value].insert(item);
|
||||
}
|
||||
|
||||
void ScriptList::RemoveItem(int64 item)
|
||||
void ScriptList::RemoveItem(SQInteger item)
|
||||
{
|
||||
this->modifications++;
|
||||
|
||||
ScriptListMap::iterator item_iter = this->items.find(item);
|
||||
if (item_iter == this->items.end()) return;
|
||||
|
||||
int64 value = item_iter->second;
|
||||
SQInteger value = item_iter->second;
|
||||
|
||||
this->sorter->Remove(item);
|
||||
ScriptListBucket::iterator bucket_iter = this->buckets.find(value);
|
||||
@@ -460,13 +459,13 @@ void ScriptList::RemoveItem(int64 item)
|
||||
this->items.erase(item_iter);
|
||||
}
|
||||
|
||||
int64 ScriptList::Begin()
|
||||
SQInteger ScriptList::Begin()
|
||||
{
|
||||
this->initialized = true;
|
||||
return this->sorter->Begin();
|
||||
}
|
||||
|
||||
int64 ScriptList::Next()
|
||||
SQInteger ScriptList::Next()
|
||||
{
|
||||
if (!this->initialized) {
|
||||
Debug(script, 0, "Next() is invalid as Begin() is never called");
|
||||
@@ -489,25 +488,25 @@ bool ScriptList::IsEnd()
|
||||
return this->sorter->IsEnd();
|
||||
}
|
||||
|
||||
int32 ScriptList::Count()
|
||||
SQInteger ScriptList::Count()
|
||||
{
|
||||
return (int32)this->items.size();
|
||||
return this->items.size();
|
||||
}
|
||||
|
||||
int64 ScriptList::GetValue(int64 item)
|
||||
SQInteger ScriptList::GetValue(SQInteger item)
|
||||
{
|
||||
ScriptListMap::const_iterator item_iter = this->items.find(item);
|
||||
return item_iter == this->items.end() ? 0 : item_iter->second;
|
||||
}
|
||||
|
||||
bool ScriptList::SetValue(int64 item, int64 value)
|
||||
bool ScriptList::SetValue(SQInteger item, SQInteger value)
|
||||
{
|
||||
this->modifications++;
|
||||
|
||||
ScriptListMap::iterator item_iter = this->items.find(item);
|
||||
if (item_iter == this->items.end()) return false;
|
||||
|
||||
int64 value_old = item_iter->second;
|
||||
SQInteger value_old = item_iter->second;
|
||||
if (value_old == value) return true;
|
||||
|
||||
this->sorter->Remove(item);
|
||||
@@ -564,9 +563,9 @@ void ScriptList::AddList(ScriptList *list)
|
||||
this->modifications++;
|
||||
} else {
|
||||
ScriptListMap *list_items = &list->items;
|
||||
for (ScriptListMap::iterator iter = list_items->begin(); iter != list_items->end(); iter++) {
|
||||
this->AddItem((*iter).first);
|
||||
this->SetValue((*iter).first, (*iter).second);
|
||||
for (auto &it : *list_items) {
|
||||
this->AddItem(it.first);
|
||||
this->SetValue(it.first, it.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -586,7 +585,7 @@ void ScriptList::SwapList(ScriptList *list)
|
||||
list->sorter->Retarget(list);
|
||||
}
|
||||
|
||||
void ScriptList::RemoveAboveValue(int64 value)
|
||||
void ScriptList::RemoveAboveValue(SQInteger value)
|
||||
{
|
||||
this->modifications++;
|
||||
|
||||
@@ -596,7 +595,7 @@ void ScriptList::RemoveAboveValue(int64 value)
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptList::RemoveBelowValue(int64 value)
|
||||
void ScriptList::RemoveBelowValue(SQInteger value)
|
||||
{
|
||||
this->modifications++;
|
||||
|
||||
@@ -606,7 +605,7 @@ void ScriptList::RemoveBelowValue(int64 value)
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptList::RemoveBetweenValue(int64 start, int64 end)
|
||||
void ScriptList::RemoveBetweenValue(SQInteger start, SQInteger end)
|
||||
{
|
||||
this->modifications++;
|
||||
|
||||
@@ -616,7 +615,7 @@ void ScriptList::RemoveBetweenValue(int64 start, int64 end)
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptList::RemoveValue(int64 value)
|
||||
void ScriptList::RemoveValue(SQInteger value)
|
||||
{
|
||||
this->modifications++;
|
||||
|
||||
@@ -626,7 +625,7 @@ void ScriptList::RemoveValue(int64 value)
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptList::RemoveTop(int32 count)
|
||||
void ScriptList::RemoveTop(SQInteger count)
|
||||
{
|
||||
this->modifications++;
|
||||
|
||||
@@ -663,7 +662,7 @@ void ScriptList::RemoveTop(int32 count)
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptList::RemoveBottom(int32 count)
|
||||
void ScriptList::RemoveBottom(SQInteger count)
|
||||
{
|
||||
this->modifications++;
|
||||
|
||||
@@ -714,7 +713,7 @@ void ScriptList::RemoveList(ScriptList *list)
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptList::KeepAboveValue(int64 value)
|
||||
void ScriptList::KeepAboveValue(SQInteger value)
|
||||
{
|
||||
this->modifications++;
|
||||
|
||||
@@ -724,7 +723,7 @@ void ScriptList::KeepAboveValue(int64 value)
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptList::KeepBelowValue(int64 value)
|
||||
void ScriptList::KeepBelowValue(SQInteger value)
|
||||
{
|
||||
this->modifications++;
|
||||
|
||||
@@ -734,7 +733,7 @@ void ScriptList::KeepBelowValue(int64 value)
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptList::KeepBetweenValue(int64 start, int64 end)
|
||||
void ScriptList::KeepBetweenValue(SQInteger start, SQInteger end)
|
||||
{
|
||||
this->modifications++;
|
||||
|
||||
@@ -744,7 +743,7 @@ void ScriptList::KeepBetweenValue(int64 start, int64 end)
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptList::KeepValue(int64 value)
|
||||
void ScriptList::KeepValue(SQInteger value)
|
||||
{
|
||||
this->modifications++;
|
||||
|
||||
@@ -754,14 +753,14 @@ void ScriptList::KeepValue(int64 value)
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptList::KeepTop(int32 count)
|
||||
void ScriptList::KeepTop(SQInteger count)
|
||||
{
|
||||
this->modifications++;
|
||||
|
||||
this->RemoveBottom(this->Count() - count);
|
||||
}
|
||||
|
||||
void ScriptList::KeepBottom(int32 count)
|
||||
void ScriptList::KeepBottom(SQInteger count)
|
||||
{
|
||||
this->modifications++;
|
||||
|
||||
@@ -866,6 +865,9 @@ SQInteger ScriptList::Valuate(HSQUIRRELVM vm)
|
||||
bool backup_allow = ScriptObject::GetAllowDoCommand();
|
||||
ScriptObject::SetAllowDoCommand(false);
|
||||
|
||||
/* Limit the total number of ops that can be consumed by a valuate operation */
|
||||
SQOpsLimiter limiter(vm, MAX_VALUATE_OPS, "valuator function");
|
||||
|
||||
/* Push the function to call */
|
||||
sq_push(vm, 2);
|
||||
|
||||
@@ -911,16 +913,6 @@ SQInteger ScriptList::Valuate(HSQUIRRELVM vm)
|
||||
}
|
||||
}
|
||||
|
||||
/* Kill the script when the valuator call takes way too long.
|
||||
* Triggered by nesting valuators, which then take billions of iterations. */
|
||||
if (ScriptController::GetOpsTillSuspend() < -1000000) {
|
||||
/* See below for explanation. The extra pop is the return value. */
|
||||
sq_pop(vm, nparam + 4);
|
||||
|
||||
ScriptObject::SetAllowDoCommand(backup_allow);
|
||||
return sq_throwerror(vm, "excessive CPU usage in valuator function");
|
||||
}
|
||||
|
||||
/* Was something changed? */
|
||||
if (previous_modification_count != this->modifications) {
|
||||
/* See below for explanation. The extra pop is the return value. */
|
||||
|
||||
@@ -12,8 +12,9 @@
|
||||
#define SCRIPT_LIST_HPP
|
||||
|
||||
#include "script_object.hpp"
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
/** Maximum number of operations allowed for valuating a list. */
|
||||
static const int MAX_VALUATE_OPS = 1000000;
|
||||
|
||||
class ScriptListSorter;
|
||||
|
||||
@@ -41,10 +42,111 @@ private:
|
||||
bool initialized; ///< Whether an iteration has been started
|
||||
int modifications; ///< Number of modification that has been done. To prevent changing data while valuating.
|
||||
|
||||
protected:
|
||||
template<typename T, class ItemValid, class ItemFilter>
|
||||
static void FillList(ScriptList *list, ItemValid item_valid, ItemFilter item_filter)
|
||||
{
|
||||
for (const T *item : T::Iterate()) {
|
||||
if (!item_valid(item)) continue;
|
||||
if (!item_filter(item)) continue;
|
||||
list->AddItem(item->index);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, class ItemValid>
|
||||
static void FillList(ScriptList *list, ItemValid item_valid)
|
||||
{
|
||||
ScriptList::FillList<T>(list, item_valid, [](const T *) { return true; });
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void FillList(ScriptList *list)
|
||||
{
|
||||
ScriptList::FillList<T>(list, [](const T *) { return true; });
|
||||
}
|
||||
|
||||
template<typename T, class ItemValid>
|
||||
static void FillList(HSQUIRRELVM vm, ScriptList *list, ItemValid item_valid)
|
||||
{
|
||||
int nparam = sq_gettop(vm) - 1;
|
||||
if (nparam >= 1) {
|
||||
/* Make sure the filter function is really a function, and not any
|
||||
* other type. It's parameter 2 for us, but for the user it's the
|
||||
* first parameter they give. */
|
||||
SQObjectType valuator_type = sq_gettype(vm, 2);
|
||||
if (valuator_type != OT_CLOSURE && valuator_type != OT_NATIVECLOSURE) {
|
||||
throw sq_throwerror(vm, "parameter 1 has an invalid type (expected function)");
|
||||
}
|
||||
|
||||
/* Push the function to call */
|
||||
sq_push(vm, 2);
|
||||
}
|
||||
|
||||
/* Don't allow docommand from a Valuator, as we can't resume in
|
||||
* mid C++-code. */
|
||||
bool backup_allow = ScriptObject::GetAllowDoCommand();
|
||||
ScriptObject::SetAllowDoCommand(false);
|
||||
|
||||
|
||||
if (nparam < 1) {
|
||||
ScriptList::FillList<T>(list, item_valid);
|
||||
} else {
|
||||
/* Limit the total number of ops that can be consumed by a filter operation, if a filter function is present */
|
||||
SQOpsLimiter limiter(vm, MAX_VALUATE_OPS, "list filter function");
|
||||
|
||||
ScriptList::FillList<T>(list, item_valid,
|
||||
[vm, nparam, backup_allow](const T *item) {
|
||||
/* Push the root table as instance object, this is what squirrel does for meta-functions. */
|
||||
sq_pushroottable(vm);
|
||||
/* Push all arguments for the valuator function. */
|
||||
sq_pushinteger(vm, item->index);
|
||||
for (int i = 0; i < nparam - 1; i++) {
|
||||
sq_push(vm, i + 3);
|
||||
}
|
||||
|
||||
/* Call the function. Squirrel pops all parameters and pushes the return value. */
|
||||
if (SQ_FAILED(sq_call(vm, nparam + 1, SQTrue, SQTrue))) {
|
||||
ScriptObject::SetAllowDoCommand(backup_allow);
|
||||
throw sq_throwerror(vm, "failed to run filter");
|
||||
}
|
||||
|
||||
SQBool add = SQFalse;
|
||||
|
||||
/* Retrieve the return value */
|
||||
switch (sq_gettype(vm, -1)) {
|
||||
case OT_BOOL:
|
||||
sq_getbool(vm, -1, &add);
|
||||
break;
|
||||
|
||||
default:
|
||||
ScriptObject::SetAllowDoCommand(backup_allow);
|
||||
throw sq_throwerror(vm, "return value of filter is not valid (not bool)");
|
||||
}
|
||||
|
||||
/* Pop the return value. */
|
||||
sq_poptop(vm);
|
||||
|
||||
return add;
|
||||
}
|
||||
);
|
||||
|
||||
/* Pop the filter function */
|
||||
sq_poptop(vm);
|
||||
}
|
||||
|
||||
ScriptObject::SetAllowDoCommand(backup_allow);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void FillList(HSQUIRRELVM vm, ScriptList *list)
|
||||
{
|
||||
ScriptList::FillList<T>(vm, list, [](const T *) { return true; });
|
||||
}
|
||||
|
||||
public:
|
||||
typedef std::set<int64> ScriptItemList; ///< The list of items inside the bucket
|
||||
typedef std::map<int64, ScriptItemList> ScriptListBucket; ///< The bucket list per value
|
||||
typedef std::map<int64, int64> ScriptListMap; ///< List per item
|
||||
typedef std::set<SQInteger> ScriptItemList; ///< The list of items inside the bucket
|
||||
typedef std::map<SQInteger, ScriptItemList> ScriptListBucket; ///< The bucket list per value
|
||||
typedef std::map<SQInteger, SQInteger> ScriptListMap; ///< List per item
|
||||
|
||||
ScriptListMap items; ///< The items in the list
|
||||
ScriptListBucket buckets; ///< The items in the list, sorted by value
|
||||
@@ -58,16 +160,16 @@ public:
|
||||
* @param item the item to add. Should be unique, otherwise it is ignored.
|
||||
* @param value the value to assign.
|
||||
*/
|
||||
void AddItem(int64 item, int64 value);
|
||||
void AddItem(SQInteger item, SQInteger value);
|
||||
#else
|
||||
void AddItem(int64 item, int64 value = 0);
|
||||
void AddItem(SQInteger item, SQInteger value = 0);
|
||||
#endif /* DOXYGEN_API */
|
||||
|
||||
/**
|
||||
* Remove a single item from the list.
|
||||
* @param item the item to remove. If not existing, it is ignored.
|
||||
*/
|
||||
void RemoveItem(int64 item);
|
||||
void RemoveItem(SQInteger item);
|
||||
|
||||
/**
|
||||
* Clear the list, making Count() returning 0 and IsEmpty() returning true.
|
||||
@@ -79,21 +181,21 @@ public:
|
||||
* @param item the item to check for.
|
||||
* @return true if the item is in the list.
|
||||
*/
|
||||
bool HasItem(int64 item);
|
||||
bool HasItem(SQInteger item);
|
||||
|
||||
/**
|
||||
* Go to the beginning of the list and return the item. To get the value use list.GetValue(list.Begin()).
|
||||
* @return the first item.
|
||||
* @note returns 0 if beyond end-of-list. Use IsEnd() to check for end-of-list.
|
||||
*/
|
||||
int64 Begin();
|
||||
SQInteger Begin();
|
||||
|
||||
/**
|
||||
* Go to the next item in the list and return the item. To get the value use list.GetValue(list.Next()).
|
||||
* @return the next item.
|
||||
* @note returns 0 if beyond end-of-list. Use IsEnd() to check for end-of-list.
|
||||
*/
|
||||
int64 Next();
|
||||
SQInteger Next();
|
||||
|
||||
/**
|
||||
* Check if a list is empty.
|
||||
@@ -112,14 +214,14 @@ public:
|
||||
* Returns the amount of items in the list.
|
||||
* @return amount of items in the list.
|
||||
*/
|
||||
int32 Count();
|
||||
SQInteger Count();
|
||||
|
||||
/**
|
||||
* Get the value that belongs to this item.
|
||||
* @param item the item to get the value from
|
||||
* @return the value that belongs to this item.
|
||||
*/
|
||||
int64 GetValue(int64 item);
|
||||
SQInteger GetValue(SQInteger item);
|
||||
|
||||
/**
|
||||
* Set a value of an item directly.
|
||||
@@ -129,7 +231,7 @@ public:
|
||||
* @note Changing values of items while looping through a list might cause
|
||||
* entries to be skipped. Be very careful with such operations.
|
||||
*/
|
||||
bool SetValue(int64 item, int64 value);
|
||||
bool SetValue(SQInteger item, SQInteger value);
|
||||
|
||||
/**
|
||||
* Sort this list by the given sorter and direction.
|
||||
@@ -160,38 +262,38 @@ public:
|
||||
* Removes all items with a higher value than 'value'.
|
||||
* @param value the value above which all items are removed.
|
||||
*/
|
||||
void RemoveAboveValue(int64 value);
|
||||
void RemoveAboveValue(SQInteger value);
|
||||
|
||||
/**
|
||||
* Removes all items with a lower value than 'value'.
|
||||
* @param value the value below which all items are removed.
|
||||
*/
|
||||
void RemoveBelowValue(int64 value);
|
||||
void RemoveBelowValue(SQInteger value);
|
||||
|
||||
/**
|
||||
* Removes all items with a value above start and below end.
|
||||
* @param start the lower bound of the to be removed values (exclusive).
|
||||
* @param end the upper bound of the to be removed values (exclusive).
|
||||
*/
|
||||
void RemoveBetweenValue(int64 start, int64 end);
|
||||
void RemoveBetweenValue(SQInteger start, SQInteger end);
|
||||
|
||||
/**
|
||||
* Remove all items with this value.
|
||||
* @param value the value to remove.
|
||||
*/
|
||||
void RemoveValue(int64 value);
|
||||
void RemoveValue(SQInteger value);
|
||||
|
||||
/**
|
||||
* Remove the first count items.
|
||||
* @param count the amount of items to remove.
|
||||
*/
|
||||
void RemoveTop(int32 count);
|
||||
void RemoveTop(SQInteger count);
|
||||
|
||||
/**
|
||||
* Remove the last count items.
|
||||
* @param count the amount of items to remove.
|
||||
*/
|
||||
void RemoveBottom(int32 count);
|
||||
void RemoveBottom(SQInteger count);
|
||||
|
||||
/**
|
||||
* Remove everything that is in the given list from this list (same item index that is).
|
||||
@@ -204,38 +306,38 @@ public:
|
||||
* Keep all items with a higher value than 'value'.
|
||||
* @param value the value above which all items are kept.
|
||||
*/
|
||||
void KeepAboveValue(int64 value);
|
||||
void KeepAboveValue(SQInteger value);
|
||||
|
||||
/**
|
||||
* Keep all items with a lower value than 'value'.
|
||||
* @param value the value below which all items are kept.
|
||||
*/
|
||||
void KeepBelowValue(int64 value);
|
||||
void KeepBelowValue(SQInteger value);
|
||||
|
||||
/**
|
||||
* Keep all items with a value above start and below end.
|
||||
* @param start the lower bound of the to be kept values (exclusive).
|
||||
* @param end the upper bound of the to be kept values (exclusive).
|
||||
*/
|
||||
void KeepBetweenValue(int64 start, int64 end);
|
||||
void KeepBetweenValue(SQInteger start, SQInteger end);
|
||||
|
||||
/**
|
||||
* Keep all items with this value.
|
||||
* @param value the value to keep.
|
||||
*/
|
||||
void KeepValue(int64 value);
|
||||
void KeepValue(SQInteger value);
|
||||
|
||||
/**
|
||||
* Keep the first count items, i.e. remove everything except the first count items.
|
||||
* @param count the amount of items to keep.
|
||||
*/
|
||||
void KeepTop(int32 count);
|
||||
void KeepTop(SQInteger count);
|
||||
|
||||
/**
|
||||
* Keep the last count items, i.e. remove everything except the last count items.
|
||||
* @param count the amount of items to keep.
|
||||
*/
|
||||
void KeepBottom(int32 count);
|
||||
void KeepBottom(SQInteger count);
|
||||
|
||||
/**
|
||||
* Keeps everything that is in the given list from this list (same item index that is).
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
/** @file script_log.cpp Implementation of ScriptLog. */
|
||||
|
||||
#include "../../stdafx.h"
|
||||
#include "script_log_types.hpp"
|
||||
#include "script_log.hpp"
|
||||
#include "../../core/alloc_func.hpp"
|
||||
#include "../../debug.h"
|
||||
@@ -16,77 +17,46 @@
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
/* static */ void ScriptLog::Info(const char *message)
|
||||
/* static */ void ScriptLog::Info(const std::string &message)
|
||||
{
|
||||
ScriptLog::Log(LOG_INFO, message);
|
||||
ScriptLog::Log(ScriptLogTypes::LOG_INFO, message);
|
||||
}
|
||||
|
||||
/* static */ void ScriptLog::Warning(const char *message)
|
||||
/* static */ void ScriptLog::Warning(const std::string &message)
|
||||
{
|
||||
ScriptLog::Log(LOG_WARNING, message);
|
||||
ScriptLog::Log(ScriptLogTypes::LOG_WARNING, message);
|
||||
}
|
||||
|
||||
/* static */ void ScriptLog::Error(const char *message)
|
||||
/* static */ void ScriptLog::Error(const std::string &message)
|
||||
{
|
||||
ScriptLog::Log(LOG_ERROR, message);
|
||||
ScriptLog::Log(ScriptLogTypes::LOG_ERROR, message);
|
||||
}
|
||||
|
||||
/* static */ void ScriptLog::Log(ScriptLog::ScriptLogType level, const char *message)
|
||||
/* static */ void ScriptLog::Log(ScriptLogTypes::ScriptLogType level, const std::string &message)
|
||||
{
|
||||
if (ScriptObject::GetLogPointer() == nullptr) {
|
||||
ScriptObject::GetLogPointer() = new LogData();
|
||||
LogData *log = (LogData *)ScriptObject::GetLogPointer();
|
||||
ScriptLogTypes::LogData &logdata = ScriptObject::GetLogData();
|
||||
|
||||
log->lines = CallocT<char *>(400);
|
||||
log->type = CallocT<ScriptLog::ScriptLogType>(400);
|
||||
log->count = 400;
|
||||
log->pos = log->count - 1;
|
||||
log->used = 0;
|
||||
}
|
||||
LogData *log = (LogData *)ScriptObject::GetLogPointer();
|
||||
/* Limit the log to 400 lines. */
|
||||
if (logdata.size() >= 400U) logdata.pop_front();
|
||||
|
||||
/* Go to the next log-line */
|
||||
log->pos = (log->pos + 1) % log->count;
|
||||
|
||||
if (log->used != log->count) log->used++;
|
||||
|
||||
/* Free last message, and write new message */
|
||||
free(log->lines[log->pos]);
|
||||
log->lines[log->pos] = stredup(message);
|
||||
log->type[log->pos] = level;
|
||||
auto &line = logdata.emplace_back();
|
||||
line.type = level;
|
||||
|
||||
/* Cut string after first \n */
|
||||
char *p;
|
||||
while ((p = strchr(log->lines[log->pos], '\n')) != nullptr) {
|
||||
*p = '\0';
|
||||
break;
|
||||
}
|
||||
line.text = message.substr(0, message.find_first_of('\n'));
|
||||
|
||||
char logc;
|
||||
|
||||
switch (level) {
|
||||
case LOG_SQ_ERROR: logc = 'S'; break;
|
||||
case LOG_ERROR: logc = 'E'; break;
|
||||
case LOG_SQ_INFO: logc = 'P'; break;
|
||||
case LOG_WARNING: logc = 'W'; break;
|
||||
case LOG_INFO: logc = 'I'; break;
|
||||
default: logc = '?'; break;
|
||||
case ScriptLogTypes::LOG_SQ_ERROR: logc = 'S'; break;
|
||||
case ScriptLogTypes::LOG_ERROR: logc = 'E'; break;
|
||||
case ScriptLogTypes::LOG_SQ_INFO: logc = 'P'; break;
|
||||
case ScriptLogTypes::LOG_WARNING: logc = 'W'; break;
|
||||
case ScriptLogTypes::LOG_INFO: logc = 'I'; break;
|
||||
default: logc = '?'; break;
|
||||
}
|
||||
|
||||
/* Also still print to debug window */
|
||||
Debug(script, level, "[{}] [{}] {}", (uint)ScriptObject::GetRootCompany(), logc, log->lines[log->pos]);
|
||||
InvalidateWindowData(WC_AI_DEBUG, 0, ScriptObject::GetRootCompany());
|
||||
}
|
||||
|
||||
/* static */ void ScriptLog::FreeLogPointer()
|
||||
{
|
||||
LogData *log = (LogData *)ScriptObject::GetLogPointer();
|
||||
|
||||
for (int i = 0; i < log->count; i++) {
|
||||
free(log->lines[i]);
|
||||
}
|
||||
|
||||
free(log->lines);
|
||||
free(log->type);
|
||||
delete log;
|
||||
Debug(script, level, "[{}] [{}] {}", (uint)ScriptObject::GetRootCompany(), logc, line.text);
|
||||
InvalidateWindowClassesData(WC_SCRIPT_DEBUG, ScriptObject::GetRootCompany());
|
||||
}
|
||||
|
||||
@@ -22,64 +22,32 @@ class ScriptLog : public ScriptObject {
|
||||
friend class ScriptController;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Log levels; The value is also feed to Debug() lvl.
|
||||
* This has no use for you, as script writer.
|
||||
* @api -all
|
||||
*/
|
||||
enum ScriptLogType {
|
||||
LOG_SQ_ERROR = 0, ///< Squirrel printed an error.
|
||||
LOG_ERROR = 1, ///< User printed an error.
|
||||
LOG_SQ_INFO = 2, ///< Squirrel printed some info.
|
||||
LOG_WARNING = 3, ///< User printed some warning.
|
||||
LOG_INFO = 4, ///< User printed some info.
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal representation of the log-data inside the script.
|
||||
* This has no use for you, as script writer.
|
||||
* @api -all
|
||||
*/
|
||||
struct LogData {
|
||||
char **lines; ///< The log-lines.
|
||||
ScriptLog::ScriptLogType *type; ///< Per line, which type of log it was.
|
||||
int count; ///< Total amount of log-lines possible.
|
||||
int pos; ///< Current position in lines.
|
||||
int used; ///< Total amount of used log-lines.
|
||||
};
|
||||
|
||||
/**
|
||||
* Print an Info message to the logs.
|
||||
* @param message The message to log.
|
||||
* @note Special characters such as U+0000-U+0019 and U+E000-U+E1FF are not supported and removed or replaced by a question mark. This includes newlines and tabs.
|
||||
*/
|
||||
static void Info(const char *message);
|
||||
static void Info(const std::string &message);
|
||||
|
||||
/**
|
||||
* Print a Warning message to the logs.
|
||||
* @param message The message to log.
|
||||
* @note Special characters such as U+0000-U+0019 and U+E000-U+E1FF are not supported and removed or replaced by a question mark. This includes newlines and tabs.
|
||||
*/
|
||||
static void Warning(const char *message);
|
||||
static void Warning(const std::string &message);
|
||||
|
||||
/**
|
||||
* Print an Error message to the logs.
|
||||
* @param message The message to log.
|
||||
* @note Special characters such as U+0000-U+0019 and U+E000-U+E1FF are not supported and removed or replaced by a question mark. This includes newlines and tabs.
|
||||
*/
|
||||
static void Error(const char *message);
|
||||
|
||||
/**
|
||||
* Free the log pointer.
|
||||
* @api -all
|
||||
*/
|
||||
static void FreeLogPointer();
|
||||
static void Error(const std::string &message);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Internal command to log the message in a common way.
|
||||
*/
|
||||
static void Log(ScriptLog::ScriptLogType level, const char *message);
|
||||
static void Log(ScriptLogTypes::ScriptLogType level, const std::string &message);
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_LOG_HPP */
|
||||
|
||||
46
src/script/api/script_log_types.hpp
Normal file
46
src/script/api/script_log_types.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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 script_log_types.hpp Data types for script log messages. */
|
||||
|
||||
#ifndef SCRIPT_LOG_TYPES_HPP
|
||||
#define SCRIPT_LOG_TYPES_HPP
|
||||
|
||||
namespace ScriptLogTypes {
|
||||
/**
|
||||
* Log levels; The value is also feed to Debug() lvl.
|
||||
* This has no use for you, as script writer.
|
||||
* @api -all
|
||||
*/
|
||||
enum ScriptLogType {
|
||||
LOG_SQ_ERROR = 0, ///< Squirrel printed an error.
|
||||
LOG_ERROR = 1, ///< User printed an error.
|
||||
LOG_SQ_INFO = 2, ///< Squirrel printed some info.
|
||||
LOG_WARNING = 3, ///< User printed some warning.
|
||||
LOG_INFO = 4, ///< User printed some info.
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal representation of the log-data inside the script.
|
||||
* This has no use for you, as script writer.
|
||||
* @api -all
|
||||
*/
|
||||
struct LogLine {
|
||||
std::string text; ///< The text
|
||||
ScriptLogType type; ///< Text type
|
||||
uint width; ///< The text width
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal representation of the log-data inside the script.
|
||||
* This has no use for you, as script writer.
|
||||
* @api -all
|
||||
*/
|
||||
using LogData = std::deque<LogLine>; ///< The log type
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_LOG_TYPES_HPP */
|
||||
@@ -18,57 +18,57 @@
|
||||
return ::IsValidTile(t);
|
||||
}
|
||||
|
||||
/* static */ TileIndex ScriptMap::GetMapSize()
|
||||
/* static */ SQInteger ScriptMap::GetMapSize()
|
||||
{
|
||||
return ::MapSize();
|
||||
return ::Map::Size();
|
||||
}
|
||||
|
||||
/* static */ uint32 ScriptMap::GetMapSizeX()
|
||||
/* static */ SQInteger ScriptMap::GetMapSizeX()
|
||||
{
|
||||
return ::MapSizeX();
|
||||
return ::Map::SizeX();
|
||||
}
|
||||
|
||||
/* static */ uint32 ScriptMap::GetMapSizeY()
|
||||
/* static */ SQInteger ScriptMap::GetMapSizeY()
|
||||
{
|
||||
return ::MapSizeY();
|
||||
return ::Map::SizeY();
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptMap::GetTileX(TileIndex t)
|
||||
/* static */ SQInteger ScriptMap::GetTileX(TileIndex t)
|
||||
{
|
||||
if (!::IsValidTile(t)) return -1;
|
||||
return ::TileX(t);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptMap::GetTileY(TileIndex t)
|
||||
/* static */ SQInteger ScriptMap::GetTileY(TileIndex t)
|
||||
{
|
||||
if (!::IsValidTile(t)) return -1;
|
||||
return ::TileY(t);
|
||||
}
|
||||
|
||||
/* static */ TileIndex ScriptMap::GetTileIndex(uint32 x, uint32 y)
|
||||
/* static */ TileIndex ScriptMap::GetTileIndex(SQInteger x, SQInteger y)
|
||||
{
|
||||
return ::TileXY(x, y);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptMap::DistanceManhattan(TileIndex t1, TileIndex t2)
|
||||
/* static */ SQInteger ScriptMap::DistanceManhattan(TileIndex t1, TileIndex t2)
|
||||
{
|
||||
if (!::IsValidTile(t1) || !::IsValidTile(t2)) return -1;
|
||||
return ::DistanceManhattan(t1, t2);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptMap::DistanceMax(TileIndex t1, TileIndex t2)
|
||||
/* static */ SQInteger ScriptMap::DistanceMax(TileIndex t1, TileIndex t2)
|
||||
{
|
||||
if (!::IsValidTile(t1) || !::IsValidTile(t2)) return -1;
|
||||
return ::DistanceMax(t1, t2);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptMap::DistanceSquare(TileIndex t1, TileIndex t2)
|
||||
/* static */ SQInteger ScriptMap::DistanceSquare(TileIndex t1, TileIndex t2)
|
||||
{
|
||||
if (!::IsValidTile(t1) || !::IsValidTile(t2)) return -1;
|
||||
return ::DistanceSquare(t1, t2);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptMap::DistanceFromEdge(TileIndex t)
|
||||
/* static */ SQInteger ScriptMap::DistanceFromEdge(TileIndex t)
|
||||
{
|
||||
if (!::IsValidTile(t)) return -1;
|
||||
return ::DistanceFromEdge(t);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
class ScriptMap : public ScriptObject {
|
||||
public:
|
||||
static const int TILE_INVALID = (int)INVALID_TILE; ///< Invalid TileIndex.
|
||||
static const int TILE_INVALID = INVALID_TILE.base(); ///< Invalid TileIndex.
|
||||
|
||||
/**
|
||||
* Checks whether the given tile is valid.
|
||||
@@ -33,21 +33,21 @@ public:
|
||||
* @return The size of the map in tiles.
|
||||
* @post Return value is always positive.
|
||||
*/
|
||||
static TileIndex GetMapSize();
|
||||
static SQInteger GetMapSize();
|
||||
|
||||
/**
|
||||
* Gets the amount of tiles along the SW and NE border.
|
||||
* @return The length along the SW and NE borders.
|
||||
* @post Return value is always positive.
|
||||
*/
|
||||
static uint32 GetMapSizeX();
|
||||
static SQInteger GetMapSizeX();
|
||||
|
||||
/**
|
||||
* Gets the amount of tiles along the SE and NW border.
|
||||
* @return The length along the SE and NW borders.
|
||||
* @post Return value is always positive.
|
||||
*/
|
||||
static uint32 GetMapSizeY();
|
||||
static SQInteger GetMapSizeY();
|
||||
|
||||
/**
|
||||
* Gets the place along the SW/NE border (X-value).
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
* @return The X-value.
|
||||
* @post Return value is always lower than GetMapSizeX().
|
||||
*/
|
||||
static int32 GetTileX(TileIndex tile);
|
||||
static SQInteger GetTileX(TileIndex tile);
|
||||
|
||||
/**
|
||||
* Gets the place along the SE/NW border (Y-value).
|
||||
@@ -65,17 +65,18 @@ public:
|
||||
* @return The Y-value.
|
||||
* @post Return value is always lower than GetMapSizeY().
|
||||
*/
|
||||
static int32 GetTileY(TileIndex tile);
|
||||
static SQInteger GetTileY(TileIndex tile);
|
||||
|
||||
/**
|
||||
* Gets the TileIndex given a x,y-coordinate.
|
||||
* @param x The X coordinate.
|
||||
* @param y The Y coordinate.
|
||||
* @pre x < GetMapSizeX().
|
||||
* @pre y < GetMapSizeY().
|
||||
* @return The TileIndex for the given (x,y) coordinate.
|
||||
* @post When 0 <= x && x < GetMapSizeX() && 0 <= y && y < GetMapSizeY(), then a valid tile index is returned.
|
||||
* Otherwise it may be invalid, but could be used to calculated neighbouring tiles, e.g. tile + AIMap.GetTileIndex(-1, -1) gets
|
||||
* the tile index of the tile to the north. But be aware that even when tile is a valid tile, the result might not be a valid tile.
|
||||
*/
|
||||
static TileIndex GetTileIndex(uint32 x, uint32 y);
|
||||
static TileIndex GetTileIndex(SQInteger x, SQInteger y);
|
||||
|
||||
/**
|
||||
* Calculates the Manhattan distance; the difference of
|
||||
@@ -86,7 +87,7 @@ public:
|
||||
* @pre IsValidTile(tile_to).
|
||||
* @return The Manhattan distance between the tiles.
|
||||
*/
|
||||
static int32 DistanceManhattan(TileIndex tile_from, TileIndex tile_to);
|
||||
static SQInteger DistanceManhattan(TileIndex tile_from, TileIndex tile_to);
|
||||
|
||||
/**
|
||||
* Calculates the distance between two tiles via 1D calculation.
|
||||
@@ -98,7 +99,7 @@ public:
|
||||
* @pre IsValidTile(tile_to).
|
||||
* @return The maximum distance between the tiles.
|
||||
*/
|
||||
static int32 DistanceMax(TileIndex tile_from, TileIndex tile_to);
|
||||
static SQInteger DistanceMax(TileIndex tile_from, TileIndex tile_to);
|
||||
|
||||
/**
|
||||
* The squared distance between the two tiles.
|
||||
@@ -110,7 +111,7 @@ public:
|
||||
* @pre IsValidTile(tile_to).
|
||||
* @return The squared distance between the tiles.
|
||||
*/
|
||||
static int32 DistanceSquare(TileIndex tile_from, TileIndex tile_to);
|
||||
static SQInteger DistanceSquare(TileIndex tile_from, TileIndex tile_to);
|
||||
|
||||
/**
|
||||
* Calculates the shortest distance to the edge.
|
||||
@@ -118,7 +119,7 @@ public:
|
||||
* @pre IsValidTile(tile).
|
||||
* @return The distances to the closest edge.
|
||||
*/
|
||||
static int32 DistanceFromEdge(TileIndex tile);
|
||||
static SQInteger DistanceFromEdge(TileIndex tile);
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_MAP_HPP */
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
|
||||
/* static */ bool ScriptMarine::BuildWaterDepot(TileIndex tile, TileIndex front)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, ::IsValidTile(front));
|
||||
EnforcePrecondition(false, (::TileX(front) == ::TileX(tile)) != (::TileY(front) == ::TileY(tile)));
|
||||
@@ -88,7 +88,7 @@
|
||||
|
||||
/* static */ bool ScriptMarine::BuildDock(TileIndex tile, StationID station_id)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id));
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
|
||||
/* static */ bool ScriptMarine::BuildBuoy(TileIndex tile)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
|
||||
return ScriptObject::Command<CMD_BUILD_BUOY>::Do(tile);
|
||||
@@ -105,7 +105,7 @@
|
||||
|
||||
/* static */ bool ScriptMarine::BuildLock(TileIndex tile)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
|
||||
return ScriptObject::Command<CMD_BUILD_LOCK>::Do(tile);
|
||||
@@ -113,7 +113,7 @@
|
||||
|
||||
/* static */ bool ScriptMarine::BuildCanal(TileIndex tile)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
|
||||
return ScriptObject::Command<CMD_BUILD_CANAL>::Do(tile, tile, WATER_CLASS_CANAL, false);
|
||||
@@ -121,7 +121,7 @@
|
||||
|
||||
/* static */ bool ScriptMarine::RemoveWaterDepot(TileIndex tile)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, IsWaterDepotTile(tile));
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
|
||||
/* static */ bool ScriptMarine::RemoveDock(TileIndex tile)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, IsDockTile(tile));
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
|
||||
/* static */ bool ScriptMarine::RemoveBuoy(TileIndex tile)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, IsBuoyTile(tile));
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
|
||||
/* static */ bool ScriptMarine::RemoveLock(TileIndex tile)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, IsLockTile(tile));
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
|
||||
/* static */ bool ScriptMarine::RemoveCanal(TileIndex tile)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, IsCanalTile(tile));
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ public:
|
||||
* @param front A tile on the same axis with 'tile' as the depot shall be oriented.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @pre ScriptMap::IsValidTile(front).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
* @exception ScriptError::ERR_SITE_UNSUITABLE
|
||||
* @exception ScriptMarine::ERR_MARINE_MUST_BE_BUILT_ON_WATER
|
||||
@@ -115,7 +115,7 @@ public:
|
||||
* @param station_id The station to join, ScriptStation::STATION_NEW or ScriptStation::STATION_JOIN_ADJACENT.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @pre station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
* @exception ScriptError::ERR_SITE_UNSUITABLE
|
||||
* @exception ScriptStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION
|
||||
@@ -128,7 +128,7 @@ public:
|
||||
* Builds a buoy on tile.
|
||||
* @param tile The tile where the buoy will be build.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
* @exception ScriptError::ERR_SITE_UNSUITABLE
|
||||
* @exception ScriptStation::ERR_STATION_TOO_MANY_STATIONS
|
||||
@@ -140,7 +140,7 @@ public:
|
||||
* Builds a lock on tile.
|
||||
* @param tile The tile where the lock will be build.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_LAND_SLOPED_WRONG
|
||||
* @exception ScriptError::ERR_SITE_UNSUITABLE
|
||||
* @return Whether the lock has been/can be build or not.
|
||||
@@ -151,7 +151,7 @@ public:
|
||||
* Builds a canal on tile.
|
||||
* @param tile The tile where the canal will be build.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
* @exception ScriptError::ERR_LAND_SLOPED_WRONG
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
@@ -164,7 +164,7 @@ public:
|
||||
* Removes a water depot.
|
||||
* @param tile Any tile of the water depot.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @return Whether the water depot has been/can be removed or not.
|
||||
*/
|
||||
@@ -174,7 +174,7 @@ public:
|
||||
* Removes a dock.
|
||||
* @param tile Any tile of the dock.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @return Whether the dock has been/can be removed or not.
|
||||
*/
|
||||
@@ -184,7 +184,7 @@ public:
|
||||
* Removes a buoy.
|
||||
* @param tile Any tile of the buoy.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @return Whether the buoy has been/can be removed or not.
|
||||
*/
|
||||
@@ -194,7 +194,7 @@ public:
|
||||
* Removes a lock.
|
||||
* @param tile Any tile of the lock.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @return Whether the lock has been/can be removed or not.
|
||||
*/
|
||||
@@ -204,7 +204,7 @@ public:
|
||||
* Removes a canal.
|
||||
* @param tile Any tile of the canal.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @return Whether the canal has been/can be removed or not.
|
||||
*/
|
||||
|
||||
@@ -24,9 +24,9 @@ ScriptNewGRFList::ScriptNewGRFList()
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ bool ScriptNewGRF::IsLoaded(uint32 grfid)
|
||||
/* static */ bool ScriptNewGRF::IsLoaded(SQInteger grfid)
|
||||
{
|
||||
grfid = BSWAP32(grfid); // Match people's expectations.
|
||||
grfid = BSWAP32(GB(grfid, 0, 32)); // Match people's expectations.
|
||||
|
||||
for (auto c = _grfconfig; c != nullptr; c = c->next) {
|
||||
if (!HasBit(c->flags, GCF_STATIC) && c->ident.grfid == grfid) {
|
||||
@@ -37,9 +37,9 @@ ScriptNewGRFList::ScriptNewGRFList()
|
||||
return false;
|
||||
}
|
||||
|
||||
/* static */ uint32 ScriptNewGRF::GetVersion(uint32 grfid)
|
||||
/* static */ SQInteger ScriptNewGRF::GetVersion(SQInteger grfid)
|
||||
{
|
||||
grfid = BSWAP32(grfid); // Match people's expectations.
|
||||
grfid = BSWAP32(GB(grfid, 0, 32)); // Match people's expectations.
|
||||
|
||||
for (auto c = _grfconfig; c != nullptr; c = c->next) {
|
||||
if (!HasBit(c->flags, GCF_STATIC) && c->ident.grfid == grfid) {
|
||||
@@ -50,15 +50,15 @@ ScriptNewGRFList::ScriptNewGRFList()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* static */ char *ScriptNewGRF::GetName(uint32 grfid)
|
||||
/* static */ std::optional<std::string> ScriptNewGRF::GetName(SQInteger grfid)
|
||||
{
|
||||
grfid = BSWAP32(grfid); // Match people's expectations.
|
||||
grfid = BSWAP32(GB(grfid, 0, 32)); // Match people's expectations.
|
||||
|
||||
for (auto c = _grfconfig; c != nullptr; c = c->next) {
|
||||
if (!HasBit(c->flags, GCF_STATIC) && c->ident.grfid == grfid) {
|
||||
return ::stredup(c->GetName());
|
||||
return c->GetName();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
* @param grfid The grfid to check.
|
||||
* @return True if and only if a NewGRF with the given grfid is loaded in the game.
|
||||
*/
|
||||
static bool IsLoaded(uint32 grfid);
|
||||
static bool IsLoaded(SQInteger grfid);
|
||||
|
||||
/**
|
||||
* Get the version of a loaded NewGRF.
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
* @pre ScriptNewGRF::IsLoaded(grfid).
|
||||
* @return Version of the NewGRF or 0 if the NewGRF specifies no version.
|
||||
*/
|
||||
static uint32 GetVersion(uint32 grfid);
|
||||
static SQInteger GetVersion(SQInteger grfid);
|
||||
|
||||
/**
|
||||
* Get the name of a loaded NewGRF.
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
* @pre ScriptNewGRF::IsLoaded(grfid).
|
||||
* @return The name of the NewGRF or null if no name is defined.
|
||||
*/
|
||||
static char *GetName(uint32 grfid);
|
||||
static std::optional<std::string> GetName(SQInteger grfid);
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_NEWGRF_HPP */
|
||||
|
||||
@@ -20,12 +20,13 @@
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
/* static */ bool ScriptNews::Create(NewsType type, Text *text, ScriptCompany::CompanyID company, NewsReferenceType ref_type, uint32 reference)
|
||||
/* static */ bool ScriptNews::Create(NewsType type, Text *text, ScriptCompany::CompanyID company, NewsReferenceType ref_type, SQInteger reference)
|
||||
{
|
||||
CCountedPtr<Text> counter(text);
|
||||
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, text != nullptr);
|
||||
const char *encoded = text->GetEncodedText();
|
||||
std::string encoded = text->GetEncodedText();
|
||||
EnforcePreconditionEncodedText(false, encoded);
|
||||
EnforcePrecondition(false, type == NT_ECONOMY || type == NT_SUBSIDIES || type == NT_GENERAL);
|
||||
EnforcePrecondition(false, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID);
|
||||
@@ -35,7 +36,7 @@
|
||||
(ref_type == NR_INDUSTRY && ScriptIndustry::IsValidIndustry(reference)) ||
|
||||
(ref_type == NR_TOWN && ScriptTown::IsValidTown(reference)));
|
||||
|
||||
uint8 c = company;
|
||||
uint8_t c = company;
|
||||
if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY;
|
||||
|
||||
if (ref_type == NR_NONE) reference = 0;
|
||||
|
||||
@@ -62,8 +62,9 @@ public:
|
||||
* @pre text != null.
|
||||
* @pre company == COMPANY_INVALID || ResolveCompanyID(company) != COMPANY_INVALID.
|
||||
* @pre The \a reference condition must be fulfilled.
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
*/
|
||||
static bool Create(NewsType type, Text *text, ScriptCompany::CompanyID company, NewsReferenceType ref_type, uint32 reference);
|
||||
static bool Create(NewsType type, Text *text, ScriptCompany::CompanyID company, NewsReferenceType ref_type, SQInteger reference);
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_NEWS_HPP */
|
||||
|
||||
@@ -82,6 +82,22 @@ ScriptObject::ActiveInstance::~ActiveInstance()
|
||||
return GetStorage()->mode_instance;
|
||||
}
|
||||
|
||||
/* static */ void ScriptObject::SetDoCommandAsyncMode(ScriptAsyncModeProc *proc, ScriptObject *instance)
|
||||
{
|
||||
GetStorage()->async_mode = proc;
|
||||
GetStorage()->async_mode_instance = instance;
|
||||
}
|
||||
|
||||
/* static */ ScriptAsyncModeProc *ScriptObject::GetDoCommandAsyncMode()
|
||||
{
|
||||
return GetStorage()->async_mode;
|
||||
}
|
||||
|
||||
/* static */ ScriptObject *ScriptObject::GetDoCommandAsyncModeInstance()
|
||||
{
|
||||
return GetStorage()->async_mode_instance;
|
||||
}
|
||||
|
||||
/* static */ void ScriptObject::SetLastCommand(const CommandDataBuffer &data, Commands cmd)
|
||||
{
|
||||
ScriptStorage *s = GetStorage();
|
||||
@@ -184,6 +200,16 @@ ScriptObject::ActiveInstance::~ActiveInstance()
|
||||
return GetStorage()->allow_do_command;
|
||||
}
|
||||
|
||||
/* static */ void ScriptObject::SetTimeMode(bool calendar)
|
||||
{
|
||||
GetStorage()->time_mode = calendar;
|
||||
}
|
||||
|
||||
/* static */ bool ScriptObject::IsCalendarTimeMode()
|
||||
{
|
||||
return GetStorage()->time_mode;
|
||||
}
|
||||
|
||||
/* static */ void ScriptObject::SetCompany(CompanyID company)
|
||||
{
|
||||
if (GetStorage()->root_company == INVALID_OWNER) GetStorage()->root_company = company;
|
||||
@@ -213,17 +239,14 @@ ScriptObject::ActiveInstance::~ActiveInstance()
|
||||
return GetStorage()->event_data;
|
||||
}
|
||||
|
||||
/* static */ void *&ScriptObject::GetLogPointer()
|
||||
/* static */ ScriptLogTypes::LogData &ScriptObject::GetLogData()
|
||||
{
|
||||
return GetStorage()->log_data;
|
||||
}
|
||||
|
||||
/* static */ char *ScriptObject::GetString(StringID string)
|
||||
/* static */ std::string ScriptObject::GetString(StringID string)
|
||||
{
|
||||
char buffer[64];
|
||||
::GetString(buffer, string, lastof(buffer));
|
||||
::StrMakeValidInPlace(buffer, lastof(buffer), SVS_NONE);
|
||||
return ::stredup(buffer);
|
||||
return ::StrMakeValid(::GetString(string));
|
||||
}
|
||||
|
||||
/* static */ void ScriptObject::SetCallbackVariable(int index, int value)
|
||||
@@ -242,7 +265,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
|
||||
return ScriptObject::GetActiveInstance()->GetDoCommandCallback();
|
||||
}
|
||||
|
||||
std::tuple<bool, bool, bool> ScriptObject::DoCommandPrep()
|
||||
std::tuple<bool, bool, bool, bool> ScriptObject::DoCommandPrep()
|
||||
{
|
||||
if (!ScriptObject::CanSuspend()) {
|
||||
throw Script_FatalError("You are not allowed to execute any DoCommand (even indirect) in your constructor, Save(), Load(), and any valuator.");
|
||||
@@ -251,17 +274,20 @@ std::tuple<bool, bool, bool> ScriptObject::DoCommandPrep()
|
||||
/* Are we only interested in the estimate costs? */
|
||||
bool estimate_only = GetDoCommandMode() != nullptr && !GetDoCommandMode()();
|
||||
|
||||
/* Should the command be executed asynchronously? */
|
||||
bool asynchronous = GetDoCommandAsyncMode() != nullptr && GetDoCommandAsyncMode()();
|
||||
|
||||
bool networking = _networking && !_generating_world;
|
||||
|
||||
if (ScriptObject::GetCompany() != OWNER_DEITY && !::Company::IsValidID(ScriptObject::GetCompany())) {
|
||||
if (!ScriptCompanyMode::IsDeity() && !ScriptCompanyMode::IsValid()) {
|
||||
ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY);
|
||||
return { true, estimate_only, networking };
|
||||
return { true, estimate_only, asynchronous, networking };
|
||||
}
|
||||
|
||||
return { false, estimate_only, networking };
|
||||
return { false, estimate_only, asynchronous, networking };
|
||||
}
|
||||
|
||||
bool ScriptObject::DoCommandProcessResult(const CommandCost &res, Script_SuspendCallbackProc *callback, bool estimate_only)
|
||||
bool ScriptObject::DoCommandProcessResult(const CommandCost &res, Script_SuspendCallbackProc *callback, bool estimate_only, bool asynchronous)
|
||||
{
|
||||
/* Set the default callback to return a true/false result of the DoCommand */
|
||||
if (callback == nullptr) callback = &ScriptInstance::DoCommandReturn;
|
||||
@@ -285,8 +311,13 @@ bool ScriptObject::DoCommandProcessResult(const CommandCost &res, Script_Suspend
|
||||
SetLastCost(res.GetCost());
|
||||
SetLastCommandRes(true);
|
||||
|
||||
if (_generating_world) {
|
||||
if (_generating_world || asynchronous) {
|
||||
IncreaseDoCommandCosts(res.GetCost());
|
||||
if (!_generating_world) {
|
||||
/* Charge a nominal fee for asynchronously executed commands */
|
||||
Squirrel *engine = ScriptObject::GetActiveInstance()->engine;
|
||||
Squirrel::DecreaseOps(engine->GetVM(), 100);
|
||||
}
|
||||
if (callback != nullptr) {
|
||||
/* Insert return value into to stack and throw a control code that
|
||||
* the return value in the stack should be used. */
|
||||
@@ -309,3 +340,19 @@ bool ScriptObject::DoCommandProcessResult(const CommandCost &res, Script_Suspend
|
||||
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
||||
|
||||
/* static */ Randomizer ScriptObject::random_states[OWNER_END];
|
||||
|
||||
Randomizer &ScriptObject::GetRandomizer(Owner owner)
|
||||
{
|
||||
return ScriptObject::random_states[owner];
|
||||
}
|
||||
|
||||
void ScriptObject::InitializeRandomizers()
|
||||
{
|
||||
Randomizer random = _random;
|
||||
for (Owner owner = OWNER_BEGIN; owner < OWNER_END; owner++) {
|
||||
ScriptObject::GetRandomizer(owner).SetSeed(random.Next());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,16 +15,25 @@
|
||||
#include "../../rail_type.h"
|
||||
#include "../../string_func.h"
|
||||
#include "../../command_func.h"
|
||||
#include "../../core/random_func.hpp"
|
||||
|
||||
#include "script_types.hpp"
|
||||
#include "script_log_types.hpp"
|
||||
#include "../script_suspend.hpp"
|
||||
#include "../squirrel.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
/**
|
||||
* The callback function for Mode-classes.
|
||||
*/
|
||||
typedef bool (ScriptModeProc)();
|
||||
|
||||
/**
|
||||
* The callback function for Async Mode-classes.
|
||||
*/
|
||||
typedef bool (ScriptAsyncModeProc)();
|
||||
|
||||
/**
|
||||
* Uper-parent object of all API classes. You should never use this class in
|
||||
* your script, as it doesn't publish any public functions. It is used
|
||||
@@ -35,6 +44,7 @@ typedef bool (ScriptModeProc)();
|
||||
class ScriptObject : public SimpleCountedObject {
|
||||
friend class ScriptInstance;
|
||||
friend class ScriptController;
|
||||
friend class TestScriptController;
|
||||
protected:
|
||||
/**
|
||||
* A class that handles the current active instance. By instantiating it at
|
||||
@@ -73,6 +83,18 @@ public:
|
||||
*/
|
||||
static class ScriptInstance *GetActiveInstance();
|
||||
|
||||
/**
|
||||
* Get a reference of the randomizer that brings this script random values.
|
||||
* @param owner The owner/script to get the randomizer for. This defaults to ScriptObject::GetRootCompany()
|
||||
*/
|
||||
static Randomizer &GetRandomizer(Owner owner = ScriptObject::GetRootCompany());
|
||||
|
||||
/**
|
||||
* Initialize/reset the script random states. The state of the scripts are
|
||||
* based on the current _random seed, but _random does not get changed.
|
||||
*/
|
||||
static void InitializeRandomizers();
|
||||
|
||||
protected:
|
||||
template<Commands TCmd, typename T> struct ScriptDoCommandHelper;
|
||||
|
||||
@@ -172,6 +194,21 @@ protected:
|
||||
*/
|
||||
static ScriptObject *GetDoCommandModeInstance();
|
||||
|
||||
/**
|
||||
* Set the current async mode of your script to this proc.
|
||||
*/
|
||||
static void SetDoCommandAsyncMode(ScriptAsyncModeProc *proc, ScriptObject *instance);
|
||||
|
||||
/**
|
||||
* Get the current async mode your script is currently under.
|
||||
*/
|
||||
static ScriptModeProc *GetDoCommandAsyncMode();
|
||||
|
||||
/**
|
||||
* Get the instance of the current async mode your script is currently under.
|
||||
*/
|
||||
static ScriptObject *GetDoCommandAsyncModeInstance();
|
||||
|
||||
/**
|
||||
* Set the delay of the DoCommand.
|
||||
*/
|
||||
@@ -207,6 +244,20 @@ protected:
|
||||
*/
|
||||
static bool GetAllowDoCommand();
|
||||
|
||||
/**
|
||||
* Set if the script is running in calendar time or economy time mode.
|
||||
* Calendar time is used by OpenTTD for technology like vehicle introductions and expiration, and variable snowline. It can be sped up or slowed down by the player.
|
||||
* Economy time always runs at the same pace and handles things like cargo production, everything related to money, etc.
|
||||
* @param Calendar Should we use calendar time mode? (Set to false for economy time mode.)
|
||||
*/
|
||||
static void SetTimeMode(bool calendar);
|
||||
|
||||
/**
|
||||
* Check if the script is operating in calendar time mode, or in economy time mode. See SetTimeMode() for more information.
|
||||
* @return True if we are in calendar time mode, false if we are in economy time mode.
|
||||
*/
|
||||
static bool IsCalendarTimeMode();
|
||||
|
||||
/**
|
||||
* Set the current company to execute commands for or request
|
||||
* information about.
|
||||
@@ -261,18 +312,19 @@ protected:
|
||||
/**
|
||||
* Get the pointer to store log message in.
|
||||
*/
|
||||
static void *&GetLogPointer();
|
||||
static ScriptLogTypes::LogData &GetLogData();
|
||||
|
||||
/**
|
||||
* Get an allocated string with all control codes stripped off.
|
||||
*/
|
||||
static char *GetString(StringID string);
|
||||
static std::string GetString(StringID string);
|
||||
|
||||
private:
|
||||
/* Helper functions for DoCommand. */
|
||||
static std::tuple<bool, bool, bool> DoCommandPrep();
|
||||
static bool DoCommandProcessResult(const CommandCost &res, Script_SuspendCallbackProc *callback, bool estimate_only);
|
||||
static std::tuple<bool, bool, bool, bool> DoCommandPrep();
|
||||
static bool DoCommandProcessResult(const CommandCost &res, Script_SuspendCallbackProc *callback, bool estimate_only, bool asynchronous);
|
||||
static CommandCallbackData *GetDoCommandCallback();
|
||||
static Randomizer random_states[OWNER_END]; ///< Random states for each of the scripts (game script uses OWNER_DEITY)
|
||||
};
|
||||
|
||||
namespace ScriptObjectInternal {
|
||||
@@ -321,7 +373,7 @@ namespace ScriptObjectInternal {
|
||||
template <Commands Tcmd, typename Tret, typename... Targs>
|
||||
bool ScriptObject::ScriptDoCommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...)>::Execute(Script_SuspendCallbackProc *callback, std::tuple<Targs...> args)
|
||||
{
|
||||
auto [err, estimate_only, networking] = ScriptObject::DoCommandPrep();
|
||||
auto [err, estimate_only, asynchronous, networking] = ScriptObject::DoCommandPrep();
|
||||
if (err) return false;
|
||||
|
||||
if ((::GetCommandFlags<Tcmd>() & CMD_STR_CTRL) == 0) {
|
||||
@@ -334,7 +386,7 @@ bool ScriptObject::ScriptDoCommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...)>
|
||||
}
|
||||
|
||||
/* Do not even think about executing out-of-bounds tile-commands. */
|
||||
if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (GetCommandFlags<Tcmd>() & CMD_ALL_TILES) == 0))) return false;
|
||||
if (tile != 0 && (tile >= Map::Size() || (!IsValidTile(tile) && (GetCommandFlags<Tcmd>() & CMD_ALL_TILES) == 0))) return false;
|
||||
|
||||
/* Only set ClientID parameters when the command does not come from the network. */
|
||||
if constexpr ((::GetCommandFlags<Tcmd>() & CMD_CLIENT_ID) != 0) ScriptObjectInternal::SetClientIds(args, std::index_sequence_for<Targs...>{});
|
||||
@@ -346,11 +398,75 @@ bool ScriptObject::ScriptDoCommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...)>
|
||||
Tret res = ::Command<Tcmd>::Unsafe((StringID)0, networking ? ScriptObject::GetDoCommandCallback() : nullptr, false, estimate_only, tile, args);
|
||||
|
||||
if constexpr (std::is_same_v<Tret, CommandCost>) {
|
||||
return ScriptObject::DoCommandProcessResult(res, callback, estimate_only);
|
||||
return ScriptObject::DoCommandProcessResult(res, callback, estimate_only, asynchronous);
|
||||
} else {
|
||||
ScriptObject::SetLastCommandResData(EndianBufferWriter<CommandDataBuffer>::FromValue(ScriptObjectInternal::RemoveFirstTupleElement(res)));
|
||||
return ScriptObject::DoCommandProcessResult(std::get<0>(res), callback, estimate_only);
|
||||
return ScriptObject::DoCommandProcessResult(std::get<0>(res), callback, estimate_only, asynchronous);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internally used class to automate the ScriptObject reference counting.
|
||||
* @api -all
|
||||
*/
|
||||
template <typename T>
|
||||
class ScriptObjectRef {
|
||||
private:
|
||||
T *data; ///< The reference counted object.
|
||||
public:
|
||||
/**
|
||||
* Create the reference counter for the given ScriptObject instance.
|
||||
* @param data The underlying object.
|
||||
*/
|
||||
ScriptObjectRef(T *data) : data(data)
|
||||
{
|
||||
this->data->AddRef();
|
||||
}
|
||||
|
||||
/* No copy constructor. */
|
||||
ScriptObjectRef(const ScriptObjectRef<T> &ref) = delete;
|
||||
|
||||
/* Move constructor. */
|
||||
ScriptObjectRef(ScriptObjectRef<T> &&ref) noexcept : data(std::exchange(ref.data, nullptr))
|
||||
{
|
||||
}
|
||||
|
||||
/* No copy assignment. */
|
||||
ScriptObjectRef& operator=(const ScriptObjectRef<T> &other) = delete;
|
||||
|
||||
/* Move assignment. */
|
||||
ScriptObjectRef& operator=(ScriptObjectRef<T> &&other) noexcept
|
||||
{
|
||||
std::swap(this->data, other.data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the reference counted object.
|
||||
*/
|
||||
~ScriptObjectRef()
|
||||
{
|
||||
if (this->data != nullptr) this->data->Release();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dereferencing this reference returns a reference to the reference
|
||||
* counted object
|
||||
* @return Reference to the underlying object.
|
||||
*/
|
||||
T &operator*()
|
||||
{
|
||||
return *this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* The arrow operator on this reference returns the reference counted object.
|
||||
* @return Pointer to the underlying object.
|
||||
*/
|
||||
T *operator->()
|
||||
{
|
||||
return this->data;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_OBJECT_HPP */
|
||||
|
||||
@@ -19,36 +19,38 @@
|
||||
|
||||
/* static */ bool ScriptObjectType::IsValidObjectType(ObjectType object_type)
|
||||
{
|
||||
if (object_type >= NUM_OBJECTS) return false;
|
||||
if (object_type >= ObjectSpec::Count()) return false;
|
||||
return ObjectSpec::Get(object_type)->IsEverAvailable();
|
||||
}
|
||||
|
||||
/* static */ char *ScriptObjectType::GetName(ObjectType object_type)
|
||||
/* static */ std::optional<std::string> ScriptObjectType::GetName(ObjectType object_type)
|
||||
{
|
||||
EnforcePrecondition(nullptr, IsValidObjectType(object_type));
|
||||
EnforcePrecondition(std::nullopt, IsValidObjectType(object_type));
|
||||
|
||||
return GetString(ObjectSpec::Get(object_type)->name);
|
||||
}
|
||||
|
||||
/* static */ uint8 ScriptObjectType::GetViews(ObjectType object_type)
|
||||
/* static */ SQInteger ScriptObjectType::GetViews(ObjectType object_type)
|
||||
{
|
||||
EnforcePrecondition(0, IsValidObjectType(object_type));
|
||||
|
||||
return ObjectSpec::Get(object_type)->views;
|
||||
}
|
||||
|
||||
/* static */ bool ScriptObjectType::BuildObject(ObjectType object_type, uint8 view, TileIndex tile)
|
||||
/* static */ bool ScriptObjectType::BuildObject(ObjectType object_type, SQInteger view, TileIndex tile)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidObjectType(object_type));
|
||||
EnforcePrecondition(false, view >= 0 && view < GetViews(object_type));
|
||||
EnforcePrecondition(false, ScriptMap::IsValidTile(tile));
|
||||
|
||||
return ScriptObject::Command<CMD_BUILD_OBJECT>::Do(tile, object_type, view);
|
||||
}
|
||||
|
||||
/* static */ ObjectType ScriptObjectType::ResolveNewGRFID(uint32 grfid, uint16 grf_local_id)
|
||||
/* static */ ObjectType ScriptObjectType::ResolveNewGRFID(SQInteger grfid, SQInteger grf_local_id)
|
||||
{
|
||||
EnforcePrecondition(INVALID_OBJECT_TYPE, IsInsideBS(grf_local_id, 0x00, NUM_OBJECTS_PER_GRF));
|
||||
|
||||
grfid = BSWAP32(grfid); // Match people's expectations.
|
||||
grfid = BSWAP32(GB(grfid, 0, 32)); // Match people's expectations.
|
||||
return _object_mngr.GetID(grf_local_id, grfid);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
* @pre IsValidObjectType(object_type).
|
||||
* @return The name of an object.
|
||||
*/
|
||||
static char *GetName(ObjectType object_type);
|
||||
static std::optional<std::string> GetName(ObjectType object_type);
|
||||
|
||||
/**
|
||||
* Get the number of views for an object-type.
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
* @pre IsValidObjectType(object_type).
|
||||
* @return The number of views for an object.
|
||||
*/
|
||||
static uint8 GetViews(ObjectType object_type);
|
||||
static SQInteger GetViews(ObjectType object_type);
|
||||
|
||||
/**
|
||||
* Build an object of the specified type.
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
* @pre IsValidObjectType(object_type).
|
||||
* @return True if the object was successfully build.
|
||||
*/
|
||||
static bool BuildObject(ObjectType object_type, uint8 view, TileIndex tile);
|
||||
static bool BuildObject(ObjectType object_type, SQInteger view, TileIndex tile);
|
||||
|
||||
/**
|
||||
* Get a specific object-type from a grf.
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
* @pre 0x00 <= grf_local_id < NUM_OBJECTS_PER_GRF.
|
||||
* @return the object-type ID, local to the current game (this diverges from the grf_local_id).
|
||||
*/
|
||||
static ObjectType ResolveNewGRFID(uint32 grfid, uint16 grf_local_id);
|
||||
static ObjectType ResolveNewGRFID(SQInteger grfid, SQInteger grf_local_id);
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_OBJECTTYPE_HPP */
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
|
||||
ScriptObjectTypeList::ScriptObjectTypeList()
|
||||
{
|
||||
for (int i = 0; i < NUM_OBJECTS; i++) {
|
||||
const ObjectSpec *spec = ObjectSpec::Get(i);
|
||||
if (!spec->IsEverAvailable()) continue;
|
||||
this->AddItem(i);
|
||||
for (const auto &spec : ObjectSpec::Specs()) {
|
||||
if (!spec.IsEverAvailable()) continue;
|
||||
this->AddItem(spec.Index());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ static OrderType GetOrderTypeByTile(TileIndex t)
|
||||
|
||||
/* static */ bool ScriptOrder::IsValidVehicleOrder(VehicleID vehicle_id, OrderPosition order_position)
|
||||
{
|
||||
return ScriptVehicle::IsValidVehicle(vehicle_id) && order_position >= 0 && (order_position < ::Vehicle::Get(vehicle_id)->GetNumManualOrders() || order_position == ORDER_CURRENT);
|
||||
return ScriptVehicle::IsPrimaryVehicle(vehicle_id) && order_position >= 0 && (order_position < ::Vehicle::Get(vehicle_id)->GetNumManualOrders() || order_position == ORDER_CURRENT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,6 +68,7 @@ static const Order *ResolveOrder(VehicleID vehicle_id, ScriptOrder::OrderPositio
|
||||
if (order_position == ScriptOrder::ORDER_INVALID) return nullptr;
|
||||
}
|
||||
const Order *order = v->GetFirstOrder();
|
||||
assert(order != nullptr);
|
||||
while (order->GetType() == OT_IMPLICIT) order = order->next;
|
||||
while (order_position > 0) {
|
||||
order_position = (ScriptOrder::OrderPosition)(order_position - 1);
|
||||
@@ -92,6 +93,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
|
||||
int res = (int)order_position;
|
||||
const Order *order = v->orders->GetFirstOrder();
|
||||
assert(order != nullptr);
|
||||
for (; order->GetType() == OT_IMPLICIT; order = order->next) res++;
|
||||
while (order_position > 0) {
|
||||
order_position = (ScriptOrder::OrderPosition)(order_position - 1);
|
||||
@@ -132,6 +134,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
if (!IsValidVehicleOrder(vehicle_id, order_position)) return false;
|
||||
|
||||
const Order *order = ::Vehicle::Get(vehicle_id)->GetOrder(ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position));
|
||||
assert(order != nullptr);
|
||||
return order->GetType() == OT_CONDITIONAL;
|
||||
}
|
||||
|
||||
@@ -141,6 +144,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
if (!IsValidVehicleOrder(vehicle_id, order_position)) return false;
|
||||
|
||||
const Order *order = ::ResolveOrder(vehicle_id, order_position);
|
||||
assert(order != nullptr);
|
||||
return order->GetType() == OT_DUMMY;
|
||||
}
|
||||
|
||||
@@ -154,7 +158,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
|
||||
/* static */ bool ScriptOrder::IsCurrentOrderPartOfOrderList(VehicleID vehicle_id)
|
||||
{
|
||||
if (!ScriptVehicle::IsValidVehicle(vehicle_id)) return false;
|
||||
if (!ScriptVehicle::IsPrimaryVehicle(vehicle_id)) return false;
|
||||
if (GetOrderCount(vehicle_id) == 0) return false;
|
||||
|
||||
const Order *order = &::Vehicle::Get(vehicle_id)->current_order;
|
||||
@@ -164,7 +168,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
|
||||
/* static */ ScriptOrder::OrderPosition ScriptOrder::ResolveOrderPosition(VehicleID vehicle_id, OrderPosition order_position)
|
||||
{
|
||||
if (!ScriptVehicle::IsValidVehicle(vehicle_id)) return ORDER_INVALID;
|
||||
if (!ScriptVehicle::IsPrimaryVehicle(vehicle_id)) return ORDER_INVALID;
|
||||
|
||||
int num_manual_orders = ::Vehicle::Get(vehicle_id)->GetNumManualOrders();
|
||||
if (num_manual_orders == 0) return ORDER_INVALID;
|
||||
@@ -172,6 +176,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
if (order_position == ORDER_CURRENT) {
|
||||
int cur_order_pos = ::Vehicle::Get(vehicle_id)->cur_real_order_index;
|
||||
const Order *order = ::Vehicle::Get(vehicle_id)->GetFirstOrder();
|
||||
assert(order != nullptr);
|
||||
int num_implicit_orders = 0;
|
||||
for (int i = 0; i < cur_order_pos; i++) {
|
||||
if (order->GetType() == OT_IMPLICIT) num_implicit_orders++;
|
||||
@@ -229,9 +234,9 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptOrder::GetOrderCount(VehicleID vehicle_id)
|
||||
/* static */ SQInteger ScriptOrder::GetOrderCount(VehicleID vehicle_id)
|
||||
{
|
||||
return ScriptVehicle::IsValidVehicle(vehicle_id) ? ::Vehicle::Get(vehicle_id)->GetNumManualOrders() : -1;
|
||||
return ScriptVehicle::IsPrimaryVehicle(vehicle_id) ? ::Vehicle::Get(vehicle_id)->GetNumManualOrders() : -1;
|
||||
}
|
||||
|
||||
/* static */ TileIndex ScriptOrder::GetOrderDestination(VehicleID vehicle_id, OrderPosition order_position)
|
||||
@@ -344,13 +349,13 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
return (CompareFunction)order->GetConditionComparator();
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptOrder::GetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position)
|
||||
/* static */ SQInteger ScriptOrder::GetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position)
|
||||
{
|
||||
if (!IsValidVehicleOrder(vehicle_id, order_position)) return -1;
|
||||
if (order_position == ORDER_CURRENT || !IsConditionalOrder(vehicle_id, order_position)) return -1;
|
||||
|
||||
const Order *order = ::ResolveOrder(vehicle_id, order_position);
|
||||
int32 value = order->GetConditionValue();
|
||||
SQInteger value = order->GetConditionValue();
|
||||
if (order->GetConditionVariable() == OCV_MAX_SPEED) value = value * 16 / 10;
|
||||
return value;
|
||||
}
|
||||
@@ -367,15 +372,16 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
|
||||
/* static */ CargoID ScriptOrder::GetOrderRefit(VehicleID vehicle_id, OrderPosition order_position)
|
||||
{
|
||||
if (!IsValidVehicleOrder(vehicle_id, order_position)) return CT_NO_REFIT;
|
||||
if (order_position != ORDER_CURRENT && !IsGotoStationOrder(vehicle_id, order_position) && !IsGotoDepotOrder(vehicle_id, order_position)) return CT_NO_REFIT;
|
||||
if (!IsValidVehicleOrder(vehicle_id, order_position)) return CARGO_NO_REFIT;
|
||||
if (order_position != ORDER_CURRENT && !IsGotoStationOrder(vehicle_id, order_position) && !IsGotoDepotOrder(vehicle_id, order_position)) return CARGO_NO_REFIT;
|
||||
|
||||
const Order *order = ::ResolveOrder(vehicle_id, order_position);
|
||||
return order->IsRefit() ? order->GetRefitCargo() : (CargoID)CT_NO_REFIT;
|
||||
return order->IsRefit() ? order->GetRefitCargo() : CARGO_NO_REFIT;
|
||||
}
|
||||
|
||||
/* static */ bool ScriptOrder::SetOrderJumpTo(VehicleID vehicle_id, OrderPosition order_position, OrderPosition jump_to)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
|
||||
EnforcePrecondition(false, order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position));
|
||||
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, jump_to) && jump_to != ORDER_CURRENT);
|
||||
@@ -385,6 +391,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
|
||||
/* static */ bool ScriptOrder::SetOrderCondition(VehicleID vehicle_id, OrderPosition order_position, OrderCondition condition)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
|
||||
EnforcePrecondition(false, order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position));
|
||||
EnforcePrecondition(false, condition >= OC_LOAD_PERCENTAGE && condition <= OC_REMAINING_LIFETIME);
|
||||
@@ -395,6 +402,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
|
||||
/* static */ bool ScriptOrder::SetOrderCompareFunction(VehicleID vehicle_id, OrderPosition order_position, CompareFunction compare)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
|
||||
EnforcePrecondition(false, order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position));
|
||||
EnforcePrecondition(false, compare >= CF_EQUALS && compare <= CF_IS_FALSE);
|
||||
@@ -403,8 +411,9 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
return ScriptObject::Command<CMD_MODIFY_ORDER>::Do(0, vehicle_id, order_pos, MOF_COND_COMPARATOR, compare);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptOrder::SetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position, int32 value)
|
||||
/* static */ bool ScriptOrder::SetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position, SQInteger value)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
|
||||
EnforcePrecondition(false, order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position));
|
||||
EnforcePrecondition(false, value >= 0 && value < 2048);
|
||||
@@ -416,6 +425,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
|
||||
/* static */ bool ScriptOrder::SetStopLocation(VehicleID vehicle_id, OrderPosition order_position, StopLocation stop_location)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
|
||||
EnforcePrecondition(false, ScriptVehicle::GetVehicleType(vehicle_id) == ScriptVehicle::VT_RAIL);
|
||||
EnforcePrecondition(false, IsGotoStationOrder(vehicle_id, order_position));
|
||||
@@ -429,16 +439,18 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
|
||||
/* static */ bool ScriptOrder::SetOrderRefit(VehicleID vehicle_id, OrderPosition order_position, CargoID refit_cargo)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
|
||||
EnforcePrecondition(false, IsGotoStationOrder(vehicle_id, order_position) || (IsGotoDepotOrder(vehicle_id, order_position) && refit_cargo != CT_AUTO_REFIT));
|
||||
EnforcePrecondition(false, ScriptCargo::IsValidCargo(refit_cargo) || refit_cargo == CT_AUTO_REFIT || refit_cargo == CT_NO_REFIT);
|
||||
EnforcePrecondition(false, IsGotoStationOrder(vehicle_id, order_position) || (IsGotoDepotOrder(vehicle_id, order_position) && refit_cargo != CARGO_AUTO_REFIT));
|
||||
EnforcePrecondition(false, ScriptCargo::IsValidCargo(refit_cargo) || refit_cargo == CARGO_AUTO_REFIT || refit_cargo == CARGO_NO_REFIT);
|
||||
|
||||
return ScriptObject::Command<CMD_ORDER_REFIT>::Do(0, vehicle_id, ScriptOrderPositionToRealOrderPosition(vehicle_id, ScriptOrder::ResolveOrderPosition(vehicle_id, order_position)), refit_cargo);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptOrder::AppendOrder(VehicleID vehicle_id, TileIndex destination, ScriptOrderFlags order_flags)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id));
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id));
|
||||
EnforcePrecondition(false, AreOrderFlagsValid(destination, order_flags));
|
||||
|
||||
return InsertOrder(vehicle_id, (ScriptOrder::OrderPosition)::Vehicle::Get(vehicle_id)->GetNumManualOrders(), destination, order_flags);
|
||||
@@ -446,7 +458,8 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
|
||||
/* static */ bool ScriptOrder::AppendConditionalOrder(VehicleID vehicle_id, OrderPosition jump_to)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id));
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id));
|
||||
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, jump_to));
|
||||
|
||||
return InsertConditionalOrder(vehicle_id, (ScriptOrder::OrderPosition)::Vehicle::Get(vehicle_id)->GetNumManualOrders(), jump_to);
|
||||
@@ -457,7 +470,8 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
/* IsValidVehicleOrder is not good enough because it does not allow appending. */
|
||||
if (order_position == ORDER_CURRENT) order_position = ScriptOrder::ResolveOrderPosition(vehicle_id, order_position);
|
||||
|
||||
EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id));
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id));
|
||||
EnforcePrecondition(false, order_position >= 0 && order_position <= ::Vehicle::Get(vehicle_id)->GetNumManualOrders());
|
||||
EnforcePrecondition(false, AreOrderFlagsValid(destination, order_flags));
|
||||
|
||||
@@ -511,7 +525,8 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
/* IsValidVehicleOrder is not good enough because it does not allow appending. */
|
||||
if (order_position == ORDER_CURRENT) order_position = ScriptOrder::ResolveOrderPosition(vehicle_id, order_position);
|
||||
|
||||
EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id));
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id));
|
||||
EnforcePrecondition(false, order_position >= 0 && order_position <= ::Vehicle::Get(vehicle_id)->GetNumManualOrders());
|
||||
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, jump_to) && jump_to != ORDER_CURRENT);
|
||||
|
||||
@@ -526,6 +541,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
{
|
||||
order_position = ScriptOrder::ResolveOrderPosition(vehicle_id, order_position);
|
||||
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
|
||||
|
||||
int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position);
|
||||
@@ -536,6 +552,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
{
|
||||
next_order = ScriptOrder::ResolveOrderPosition(vehicle_id, next_order);
|
||||
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, next_order));
|
||||
|
||||
int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, next_order);
|
||||
@@ -572,6 +589,7 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance)
|
||||
|
||||
order_position = ScriptOrder::ResolveOrderPosition(vehicle_id, order_position);
|
||||
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
|
||||
EnforcePrecondition(false, AreOrderFlagsValid(GetOrderDestination(vehicle_id, order_position), order_flags));
|
||||
|
||||
@@ -629,6 +647,7 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance)
|
||||
order_position_move = ScriptOrder::ResolveOrderPosition(vehicle_id, order_position_move);
|
||||
order_position_target = ScriptOrder::ResolveOrderPosition(vehicle_id, order_position_target);
|
||||
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position_move));
|
||||
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position_target));
|
||||
EnforcePrecondition(false, order_position_move != order_position_target);
|
||||
@@ -640,28 +659,31 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance)
|
||||
|
||||
/* static */ bool ScriptOrder::CopyOrders(VehicleID vehicle_id, VehicleID main_vehicle_id)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id));
|
||||
EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(main_vehicle_id));
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id));
|
||||
EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(main_vehicle_id));
|
||||
|
||||
return ScriptObject::Command<CMD_CLONE_ORDER>::Do(0, CO_COPY, vehicle_id, main_vehicle_id);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptOrder::ShareOrders(VehicleID vehicle_id, VehicleID main_vehicle_id)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id));
|
||||
EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(main_vehicle_id));
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id));
|
||||
EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(main_vehicle_id));
|
||||
|
||||
return ScriptObject::Command<CMD_CLONE_ORDER>::Do(0, CO_SHARE, vehicle_id, main_vehicle_id);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptOrder::UnshareOrders(VehicleID vehicle_id)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id));
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id));
|
||||
|
||||
return ScriptObject::Command<CMD_CLONE_ORDER>::Do(0, CO_UNSHARE, vehicle_id, 0);
|
||||
}
|
||||
|
||||
/* static */ uint ScriptOrder::GetOrderDistance(ScriptVehicle::VehicleType vehicle_type, TileIndex origin_tile, TileIndex dest_tile)
|
||||
/* static */ SQInteger ScriptOrder::GetOrderDistance(ScriptVehicle::VehicleType vehicle_type, TileIndex origin_tile, TileIndex dest_tile)
|
||||
{
|
||||
if (vehicle_type == ScriptVehicle::VT_AIR) {
|
||||
if (ScriptTile::IsStationTile(origin_tile)) {
|
||||
|
||||
@@ -142,7 +142,7 @@ public:
|
||||
* Checks whether the given order id is valid for the given vehicle.
|
||||
* @param vehicle_id The vehicle to check the order index for.
|
||||
* @param order_position The order index to check.
|
||||
* @pre ScriptVehicle::IsValidVehicle(vehicle_id).
|
||||
* @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id).
|
||||
* @return True if and only if the order_position is valid for the given vehicle.
|
||||
*/
|
||||
static bool IsValidVehicleOrder(VehicleID vehicle_id, OrderPosition order_position);
|
||||
@@ -207,7 +207,7 @@ public:
|
||||
/**
|
||||
* Checks whether the current order is part of the orderlist.
|
||||
* @param vehicle_id The vehicle to check.
|
||||
* @pre ScriptVehicle::IsValidVehicle(vehicle_id).
|
||||
* @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id).
|
||||
* @return True if and only if the current order is part of the order list.
|
||||
* @note If the order is a non-'non-stop' order, and the vehicle is currently
|
||||
* (un)loading at a station that is not the final destination, this function
|
||||
@@ -222,7 +222,7 @@ public:
|
||||
* given index does not exist it will return ORDER_INVALID.
|
||||
* @param vehicle_id The vehicle to check the order index for.
|
||||
* @param order_position The order index to resolve.
|
||||
* @pre ScriptVehicle::IsValidVehicle(vehicle_id).
|
||||
* @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id).
|
||||
* @return The resolved order index.
|
||||
*/
|
||||
static OrderPosition ResolveOrderPosition(VehicleID vehicle_id, OrderPosition order_position);
|
||||
@@ -246,11 +246,11 @@ public:
|
||||
/**
|
||||
* Returns the number of orders for the given vehicle.
|
||||
* @param vehicle_id The vehicle to get the order count of.
|
||||
* @pre ScriptVehicle::IsValidVehicle(vehicle_id).
|
||||
* @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id).
|
||||
* @return The number of orders for the given vehicle or a negative
|
||||
* value when the vehicle does not exist.
|
||||
*/
|
||||
static int32 GetOrderCount(VehicleID vehicle_id);
|
||||
static SQInteger GetOrderCount(VehicleID vehicle_id);
|
||||
|
||||
/**
|
||||
* Gets the destination of the given order for the given vehicle.
|
||||
@@ -320,7 +320,7 @@ public:
|
||||
* @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position).
|
||||
* @return The value to compare against of the order.
|
||||
*/
|
||||
static int32 GetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position);
|
||||
static SQInteger GetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position);
|
||||
|
||||
/**
|
||||
* Gets the stoplocation of the given order for the given train.
|
||||
@@ -356,8 +356,8 @@ public:
|
||||
* @pre IsValidVehicleOrder(vehicle_id, order_position).
|
||||
* @pre IsValidVehicleOrder(vehicle_id, jump_to).
|
||||
* @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return Whether the order has been/can be changed.
|
||||
* @api -game
|
||||
*/
|
||||
static bool SetOrderJumpTo(VehicleID vehicle_id, OrderPosition order_position, OrderPosition jump_to);
|
||||
|
||||
@@ -369,8 +369,8 @@ public:
|
||||
* @pre IsValidVehicleOrder(vehicle_id, order_position).
|
||||
* @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position).
|
||||
* @pre condition >= OC_LOAD_PERCENTAGE && condition <= OC_UNCONDITIONALLY.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return Whether the order has been/can be changed.
|
||||
* @api -game
|
||||
*/
|
||||
static bool SetOrderCondition(VehicleID vehicle_id, OrderPosition order_position, OrderCondition condition);
|
||||
|
||||
@@ -382,8 +382,8 @@ public:
|
||||
* @pre IsValidVehicleOrder(vehicle_id, order_position).
|
||||
* @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position).
|
||||
* @pre compare >= CF_EQUALS && compare <= CF_IS_FALSE.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return Whether the order has been/can be changed.
|
||||
* @api -game
|
||||
*/
|
||||
static bool SetOrderCompareFunction(VehicleID vehicle_id, OrderPosition order_position, CompareFunction compare);
|
||||
|
||||
@@ -395,10 +395,10 @@ public:
|
||||
* @pre IsValidVehicleOrder(vehicle_id, order_position).
|
||||
* @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position).
|
||||
* @pre value >= 0 && value < 2048.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return Whether the order has been/can be changed.
|
||||
* @api -game
|
||||
*/
|
||||
static bool SetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position, int32 value);
|
||||
static bool SetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position, SQInteger value);
|
||||
|
||||
/**
|
||||
* Sets the stoplocation of the given order for the given train.
|
||||
@@ -409,8 +409,8 @@ public:
|
||||
* @pre ScriptVehicle::GetVehicleType(vehicle_id) == ScriptVehicle::VT_RAIL.
|
||||
* @pre IsGotoStationOrder(vehicle_id, order_position).
|
||||
* @pre stop_location >= STOPLOCATION_NEAR && stop_location <= STOPLOCATION_FAR
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return Whether the order has been/can be changed.
|
||||
* @api -game
|
||||
*/
|
||||
static bool SetStopLocation(VehicleID vehicle_id, OrderPosition order_position, StopLocation stop_location);
|
||||
|
||||
@@ -422,8 +422,8 @@ public:
|
||||
* @pre IsValidVehicleOrder(vehicle_id, order_position).
|
||||
* @pre IsGotoStationOrder(vehicle_id, order_position) || (IsGotoDepotOrder(vehicle_id, order_position) && refit_cargo != CT_AUTO_REFIT).
|
||||
* @pre ScriptCargo::IsValidCargo(refit_cargo) || refit_cargo == CT_AUTO_REFIT || refit_cargo == CT_NO_REFIT
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return Whether the order has been/can be changed.
|
||||
* @api -game
|
||||
*/
|
||||
static bool SetOrderRefit(VehicleID vehicle_id, OrderPosition order_position, CargoID refit_cargo);
|
||||
|
||||
@@ -432,13 +432,13 @@ public:
|
||||
* @param vehicle_id The vehicle to append the order to.
|
||||
* @param destination The destination of the order.
|
||||
* @param order_flags The flags given to the order.
|
||||
* @pre ScriptVehicle::IsValidVehicle(vehicle_id).
|
||||
* @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id).
|
||||
* @pre AreOrderFlagsValid(destination, order_flags).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @exception ScriptOrder::ERR_ORDER_TOO_MANY
|
||||
* @exception ScriptOrder::ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION
|
||||
* @return True if and only if the order was appended.
|
||||
* @api -game
|
||||
*/
|
||||
static bool AppendOrder(VehicleID vehicle_id, TileIndex destination, ScriptOrderFlags order_flags);
|
||||
|
||||
@@ -446,12 +446,12 @@ public:
|
||||
* Appends a conditional order to the end of the vehicle's order list.
|
||||
* @param vehicle_id The vehicle to append the order to.
|
||||
* @param jump_to The OrderPosition to jump to if the condition is true.
|
||||
* @pre ScriptVehicle::IsValidVehicle(vehicle_id).
|
||||
* @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id).
|
||||
* @pre IsValidVehicleOrder(vehicle_id, jump_to).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @exception ScriptOrder::ERR_ORDER_TOO_MANY
|
||||
* @return True if and only if the order was appended.
|
||||
* @api -game
|
||||
*/
|
||||
static bool AppendConditionalOrder(VehicleID vehicle_id, OrderPosition jump_to);
|
||||
|
||||
@@ -461,13 +461,14 @@ public:
|
||||
* @param order_position The order to place the new order before.
|
||||
* @param destination The destination of the order.
|
||||
* @param order_flags The flags given to the order.
|
||||
* @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id)
|
||||
* @pre IsValidVehicleOrder(vehicle_id, order_position).
|
||||
* @pre AreOrderFlagsValid(destination, order_flags).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @exception ScriptOrder::ERR_ORDER_TOO_MANY
|
||||
* @exception ScriptOrder::ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION
|
||||
* @return True if and only if the order was inserted.
|
||||
* @api -game
|
||||
*/
|
||||
static bool InsertOrder(VehicleID vehicle_id, OrderPosition order_position, TileIndex destination, ScriptOrderFlags order_flags);
|
||||
|
||||
@@ -476,12 +477,13 @@ public:
|
||||
* @param vehicle_id The vehicle to add the order to.
|
||||
* @param order_position The order to place the new order before.
|
||||
* @param jump_to The OrderPosition to jump to if the condition is true.
|
||||
* @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id).
|
||||
* @pre IsValidVehicleOrder(vehicle_id, order_position).
|
||||
* @pre IsValidVehicleOrder(vehicle_id, jump_to).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @exception ScriptOrder::ERR_ORDER_TOO_MANY
|
||||
* @return True if and only if the order was inserted.
|
||||
* @api -game
|
||||
*/
|
||||
static bool InsertConditionalOrder(VehicleID vehicle_id, OrderPosition order_position, OrderPosition jump_to);
|
||||
|
||||
@@ -490,9 +492,9 @@ public:
|
||||
* @param vehicle_id The vehicle to remove the order from.
|
||||
* @param order_position The order to remove from the order list.
|
||||
* @pre IsValidVehicleOrder(vehicle_id, order_position).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @return True if and only if the order was removed.
|
||||
* @api -game
|
||||
*/
|
||||
static bool RemoveOrder(VehicleID vehicle_id, OrderPosition order_position);
|
||||
|
||||
@@ -510,9 +512,9 @@ public:
|
||||
* @pre IsValidVehicleOrder(vehicle_id, order_position).
|
||||
* @pre AreOrderFlagsValid(GetOrderDestination(vehicle_id, order_position), order_flags).
|
||||
* @pre (order_flags & OF_GOTO_NEAREST_DEPOT) == (GetOrderFlags(vehicle_id, order_position) & OF_GOTO_NEAREST_DEPOT).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @return True if and only if the order was changed.
|
||||
* @api -game
|
||||
*/
|
||||
static bool SetOrderFlags(VehicleID vehicle_id, OrderPosition order_position, ScriptOrderFlags order_flags);
|
||||
|
||||
@@ -524,13 +526,13 @@ public:
|
||||
* @pre IsValidVehicleOrder(vehicle_id, order_position_move).
|
||||
* @pre IsValidVehicleOrder(vehicle_id, order_position_target).
|
||||
* @pre order_position_move != order_position_target.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @return True if and only if the order was moved.
|
||||
* @note If the order is moved to a lower place (e.g. from 7 to 2)
|
||||
* the target order is moved upwards (e.g. 3). If the order is moved
|
||||
* to a higher place (e.g. from 7 to 9) the target will be moved
|
||||
* downwards (e.g. 8).
|
||||
* @api -game
|
||||
*/
|
||||
static bool MoveOrder(VehicleID vehicle_id, OrderPosition order_position_move, OrderPosition order_position_target);
|
||||
|
||||
@@ -539,9 +541,9 @@ public:
|
||||
* @param vehicle_id The vehicle that should skip some orders.
|
||||
* @param next_order The order the vehicle should skip to.
|
||||
* @pre IsValidVehicleOrder(vehicle_id, next_order).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @return True if and only the current order was changed.
|
||||
* @api -game
|
||||
*/
|
||||
static bool SkipToOrder(VehicleID vehicle_id, OrderPosition next_order);
|
||||
|
||||
@@ -550,13 +552,13 @@ public:
|
||||
* are going to be the orders of the changed vehicle.
|
||||
* @param vehicle_id The vehicle to copy the orders to.
|
||||
* @param main_vehicle_id The vehicle to copy the orders from.
|
||||
* @pre ScriptVehicle::IsValidVehicle(vehicle_id).
|
||||
* @pre ScriptVehicle::IsValidVehicle(main_vehicle_id).
|
||||
* @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id).
|
||||
* @pre ScriptVehicle::IsPrimaryVehicle(main_vehicle_id).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @exception ScriptOrder::ERR_ORDER_TOO_MANY
|
||||
* @exception ScriptOrder::ERR_ORDER_AIRCRAFT_NOT_ENOUGH_RANGE
|
||||
* @return True if and only if the copying succeeded.
|
||||
* @api -game
|
||||
*/
|
||||
static bool CopyOrders(VehicleID vehicle_id, VehicleID main_vehicle_id);
|
||||
|
||||
@@ -565,12 +567,12 @@ public:
|
||||
* vehicle are going to be the orders of the changed vehicle.
|
||||
* @param vehicle_id The vehicle to add to the shared order list.
|
||||
* @param main_vehicle_id The vehicle to share the orders with.
|
||||
* @pre ScriptVehicle::IsValidVehicle(vehicle_id).
|
||||
* @pre ScriptVehicle::IsValidVehicle(main_vehicle_id).
|
||||
* @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id).
|
||||
* @pre ScriptVehicle::IsPrimaryVehicle(main_vehicle_id).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @exception ScriptOrder::ERR_ORDER_AIRCRAFT_NOT_ENOUGH_RANGE
|
||||
* @return True if and only if the sharing succeeded.
|
||||
* @api -game
|
||||
*/
|
||||
static bool ShareOrders(VehicleID vehicle_id, VehicleID main_vehicle_id);
|
||||
|
||||
@@ -578,9 +580,9 @@ public:
|
||||
* Removes the given vehicle from a shared orders list.
|
||||
* After unsharing orders, the orders list of the vehicle is empty.
|
||||
* @param vehicle_id The vehicle to remove from the shared order list.
|
||||
* @pre ScriptVehicle::IsValidVehicle(vehicle_id).
|
||||
* @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id).
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True if and only if the unsharing succeeded.
|
||||
* @api -game
|
||||
*/
|
||||
static bool UnshareOrders(VehicleID vehicle_id);
|
||||
|
||||
@@ -599,7 +601,7 @@ public:
|
||||
* not be compared with map distances
|
||||
* @see ScriptEngine::GetMaximumOrderDistance and ScriptVehicle::GetMaximumOrderDistance
|
||||
*/
|
||||
static uint GetOrderDistance(ScriptVehicle::VehicleType vehicle_type, TileIndex origin_tile, TileIndex dest_tile);
|
||||
static SQInteger GetOrderDistance(ScriptVehicle::VehicleType vehicle_type, TileIndex origin_tile, TileIndex dest_tile);
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(ScriptOrder::ScriptOrderFlags)
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ ScriptPriorityQueue::~ScriptPriorityQueue()
|
||||
SQInteger ScriptPriorityQueue::Insert(HSQUIRRELVM vm)
|
||||
{
|
||||
HSQOBJECT item;
|
||||
int64 priority;
|
||||
SQInteger priority;
|
||||
sq_resetobject(&item);
|
||||
sq_getstackobj(vm, 2, &item);
|
||||
sq_getinteger(vm, 3, &priority);
|
||||
@@ -45,7 +45,7 @@ SQInteger ScriptPriorityQueue::Insert(HSQUIRRELVM vm)
|
||||
this->queue.emplace_back(priority, item);
|
||||
std::push_heap(this->queue.begin(), this->queue.end(), this->comp);
|
||||
|
||||
return SQConvert::Return(vm, true);
|
||||
return SQConvert::Return<bool>::Set(vm, true);
|
||||
}
|
||||
|
||||
SQInteger ScriptPriorityQueue::Pop(HSQUIRRELVM vm)
|
||||
@@ -61,7 +61,7 @@ SQInteger ScriptPriorityQueue::Pop(HSQUIRRELVM vm)
|
||||
this->queue.pop_back();
|
||||
|
||||
/* Store the object on the Squirrel stack before releasing it to make sure the ref count can't drop to zero. */
|
||||
auto ret = SQConvert::Return(vm, item);
|
||||
auto ret = SQConvert::Return<HSQOBJECT>::Set(vm, item);
|
||||
sq_release(vm, &item);
|
||||
return ret;
|
||||
}
|
||||
@@ -74,7 +74,7 @@ SQInteger ScriptPriorityQueue::Peek(HSQUIRRELVM vm)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return SQConvert::Return(vm, this->queue.front().second);
|
||||
return SQConvert::Return<HSQOBJECT>::Set(vm, this->queue.front().second);
|
||||
}
|
||||
|
||||
SQInteger ScriptPriorityQueue::Exists(HSQUIRRELVM vm)
|
||||
@@ -83,7 +83,7 @@ SQInteger ScriptPriorityQueue::Exists(HSQUIRRELVM vm)
|
||||
sq_resetobject(&item);
|
||||
sq_getstackobj(vm, 2, &item);
|
||||
|
||||
return SQConvert::Return(vm, std::find(this->queue.cbegin(), this->queue.cend(), item) != this->queue.cend());
|
||||
return SQConvert::Return<bool>::Set(vm, std::find(this->queue.cbegin(), this->queue.cend(), item) != this->queue.cend());
|
||||
}
|
||||
|
||||
SQInteger ScriptPriorityQueue::Clear(HSQUIRRELVM vm)
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
#include "script_object.hpp"
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Class that creates a queue which keeps its items ordered by an item priority.
|
||||
@@ -21,7 +20,7 @@
|
||||
*/
|
||||
class ScriptPriorityQueue : public ScriptObject {
|
||||
public:
|
||||
typedef std::pair<int64, HSQOBJECT> PriorityItem;
|
||||
typedef std::pair<SQInteger, HSQOBJECT> PriorityItem;
|
||||
private:
|
||||
struct PriorityComparator {
|
||||
bool operator()(const PriorityItem &lhs, const PriorityItem &rhs) const noexcept
|
||||
@@ -43,7 +42,7 @@ public:
|
||||
* @param priority The priority to assign the item.
|
||||
* @return True if the item was inserted, false if it was already in the queue.
|
||||
*/
|
||||
bool Insert(void *item, int64 priority);
|
||||
bool Insert(void *item, SQInteger priority);
|
||||
|
||||
/**
|
||||
* Remove and return the item with the lowest priority.
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
/* static */ char *ScriptRail::GetName(RailType rail_type)
|
||||
/* static */ std::optional<std::string> ScriptRail::GetName(RailType rail_type)
|
||||
{
|
||||
if (!IsRailTypeAvailable(rail_type)) return nullptr;
|
||||
if (!IsRailTypeAvailable(rail_type)) return std::nullopt;
|
||||
|
||||
return GetString(GetRailTypeInfo((::RailType)rail_type)->strings.menu_text);
|
||||
}
|
||||
@@ -69,9 +69,10 @@
|
||||
|
||||
/* static */ bool ScriptRail::IsRailTypeAvailable(RailType rail_type)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
if ((::RailType)rail_type >= RAILTYPE_END) return false;
|
||||
|
||||
return ScriptObject::GetCompany() == OWNER_DEITY || ::HasRailtypeAvail(ScriptObject::GetCompany(), (::RailType)rail_type);
|
||||
return ScriptCompanyMode::IsDeity() || ::HasRailTypeAvail(ScriptObject::GetCompany(), (::RailType)rail_type);
|
||||
}
|
||||
|
||||
/* static */ ScriptRail::RailType ScriptRail::GetCurrentRailType()
|
||||
@@ -111,7 +112,7 @@
|
||||
|
||||
/* static */ bool ScriptRail::ConvertRailType(TileIndex start_tile, TileIndex end_tile, ScriptRail::RailType convert_to)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(start_tile));
|
||||
EnforcePrecondition(false, ::IsValidTile(end_tile));
|
||||
EnforcePrecondition(false, IsRailTypeAvailable(convert_to));
|
||||
@@ -135,7 +136,7 @@
|
||||
|
||||
/* static */ bool ScriptRail::BuildRailDepot(TileIndex tile, TileIndex front)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, tile != front);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, ::IsValidTile(front));
|
||||
@@ -147,9 +148,9 @@
|
||||
return ScriptObject::Command<CMD_BUILD_TRAIN_DEPOT>::Do(tile, (::RailType)ScriptObject::GetRailType(), entrance_dir);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptRail::BuildRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id)
|
||||
/* static */ bool ScriptRail::BuildRailStation(TileIndex tile, RailTrack direction, SQInteger num_platforms, SQInteger platform_length, StationID station_id)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW);
|
||||
EnforcePrecondition(false, num_platforms > 0 && num_platforms <= 0xFF);
|
||||
@@ -161,9 +162,9 @@
|
||||
return ScriptObject::Command<CMD_BUILD_RAIL_STATION>::Do(tile, (::RailType)GetCurrentRailType(), direction == RAILTRACK_NW_SE ? AXIS_Y : AXIS_X, num_platforms, platform_length, STAT_CLASS_DFLT, 0, ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION, adjacent);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptRail::BuildNewGRFRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, int distance, bool source_station)
|
||||
/* static */ bool ScriptRail::BuildNewGRFRailStation(TileIndex tile, RailTrack direction, SQInteger num_platforms, SQInteger platform_length, StationID station_id, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, SQInteger distance, bool source_station)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW);
|
||||
EnforcePrecondition(false, num_platforms > 0 && num_platforms <= 0xFF);
|
||||
@@ -175,16 +176,16 @@
|
||||
EnforcePrecondition(false, goal_industry == ScriptIndustryType::INDUSTRYTYPE_UNKNOWN || goal_industry == ScriptIndustryType::INDUSTRYTYPE_TOWN || ScriptIndustryType::IsValidIndustryType(goal_industry));
|
||||
|
||||
const GRFFile *file;
|
||||
uint16 res = GetAiPurchaseCallbackResult(
|
||||
uint16_t res = GetAiPurchaseCallbackResult(
|
||||
GSF_STATIONS,
|
||||
cargo_id,
|
||||
0,
|
||||
source_industry,
|
||||
goal_industry,
|
||||
std::min(255, distance / 2),
|
||||
ClampTo<uint8_t>(distance / 2),
|
||||
AICE_STATION_GET_STATION_ID,
|
||||
source_station ? 0 : 1,
|
||||
std::min(15u, num_platforms) << 4 | std::min(15u, platform_length),
|
||||
std::min<SQInteger>(15u, num_platforms) << 4 | std::min<SQInteger>(15u, platform_length),
|
||||
&file
|
||||
);
|
||||
|
||||
@@ -207,7 +208,7 @@
|
||||
|
||||
/* static */ bool ScriptRail::BuildRailWaypoint(TileIndex tile)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, IsRailTile(tile));
|
||||
EnforcePrecondition(false, GetRailTracks(tile) == RAILTRACK_NE_SW || GetRailTracks(tile) == RAILTRACK_NW_SE);
|
||||
@@ -218,7 +219,7 @@
|
||||
|
||||
/* static */ bool ScriptRail::RemoveRailWaypointTileRectangle(TileIndex tile, TileIndex tile2, bool keep_rail)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, ::IsValidTile(tile2));
|
||||
|
||||
@@ -227,7 +228,7 @@
|
||||
|
||||
/* static */ bool ScriptRail::RemoveRailStationTileRectangle(TileIndex tile, TileIndex tile2, bool keep_rail)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, ::IsValidTile(tile2));
|
||||
|
||||
@@ -246,10 +247,10 @@
|
||||
|
||||
/* static */ bool ScriptRail::BuildRailTrack(TileIndex tile, RailTrack rail_track)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, rail_track != 0);
|
||||
EnforcePrecondition(false, (rail_track & ~::TRACK_BIT_ALL) == 0);
|
||||
EnforcePrecondition(false, (static_cast<uint>(rail_track) & ~static_cast<uint>(::TRACK_BIT_ALL)) == 0);
|
||||
EnforcePrecondition(false, KillFirstBit((uint)rail_track) == 0);
|
||||
EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType()));
|
||||
|
||||
@@ -258,7 +259,7 @@
|
||||
|
||||
/* static */ bool ScriptRail::RemoveRailTrack(TileIndex tile, RailTrack rail_track)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, ::IsPlainRailTile(tile) || ::IsLevelCrossingTile(tile));
|
||||
EnforcePrecondition(false, GetRailTracks(tile) & rail_track);
|
||||
@@ -276,11 +277,11 @@
|
||||
|
||||
if (tile - from == 1) {
|
||||
if (to - tile == 1) return (GetRailTracks(tile) & RAILTRACK_NE_SW) != 0;
|
||||
if (to - tile == ::MapSizeX()) return (GetRailTracks(tile) & RAILTRACK_NE_SE) != 0;
|
||||
} else if (tile - from == ::MapSizeX()) {
|
||||
if (to - tile == (int)ScriptMap::GetMapSizeX()) return (GetRailTracks(tile) & RAILTRACK_NE_SE) != 0;
|
||||
} else if (tile - from == (int)ScriptMap::GetMapSizeX()) {
|
||||
if (tile - to == 1) return (GetRailTracks(tile) & RAILTRACK_NW_NE) != 0;
|
||||
if (to - tile == 1) return (GetRailTracks(tile) & RAILTRACK_NW_SW) != 0;
|
||||
if (to - tile == ::MapSizeX()) return (GetRailTracks(tile) & RAILTRACK_NW_SE) != 0;
|
||||
if (to - tile == (int)ScriptMap::GetMapSizeX()) return (GetRailTracks(tile) & RAILTRACK_NW_SE) != 0;
|
||||
} else {
|
||||
return (GetRailTracks(tile) & RAILTRACK_SW_SE) != 0;
|
||||
}
|
||||
@@ -301,7 +302,7 @@ static Track SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to)
|
||||
*to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1);
|
||||
} else if (::TileX(from) == ::TileX(*to)) {
|
||||
track = TRACK_Y;
|
||||
*to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
|
||||
*to -= ScriptMap::GetMapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
|
||||
} else if (::TileY(from) < ::TileY(tile)) {
|
||||
if (::TileX(*to) < ::TileX(tile)) {
|
||||
track = TRACK_UPPER;
|
||||
@@ -311,7 +312,7 @@ static Track SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to)
|
||||
if (diag_offset != 0) {
|
||||
*to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1);
|
||||
} else {
|
||||
*to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
|
||||
*to -= ScriptMap::GetMapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
|
||||
}
|
||||
} else if (::TileY(from) > ::TileY(tile)) {
|
||||
if (::TileX(*to) < ::TileX(tile)) {
|
||||
@@ -322,7 +323,7 @@ static Track SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to)
|
||||
if (diag_offset != 0) {
|
||||
*to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1);
|
||||
} else {
|
||||
*to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
|
||||
*to -= ScriptMap::GetMapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
|
||||
}
|
||||
} else if (::TileX(from) < ::TileX(tile)) {
|
||||
if (::TileY(*to) < ::TileY(tile)) {
|
||||
@@ -333,7 +334,7 @@ static Track SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to)
|
||||
if (diag_offset == 0) {
|
||||
*to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1);
|
||||
} else {
|
||||
*to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
|
||||
*to -= ScriptMap::GetMapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
|
||||
}
|
||||
} else if (::TileX(from) > ::TileX(tile)) {
|
||||
if (::TileY(*to) < ::TileY(tile)) {
|
||||
@@ -344,7 +345,7 @@ static Track SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to)
|
||||
if (diag_offset == 0) {
|
||||
*to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1);
|
||||
} else {
|
||||
*to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
|
||||
*to -= ScriptMap::GetMapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
|
||||
}
|
||||
}
|
||||
return track;
|
||||
@@ -352,7 +353,7 @@ static Track SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to)
|
||||
|
||||
/* static */ bool ScriptRail::BuildRail(TileIndex from, TileIndex tile, TileIndex to)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(from));
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, ::IsValidTile(to));
|
||||
@@ -370,7 +371,7 @@ static Track SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to)
|
||||
|
||||
/* static */ bool ScriptRail::RemoveRail(TileIndex from, TileIndex tile, TileIndex to)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(from));
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, ::IsValidTile(to));
|
||||
@@ -443,13 +444,13 @@ static bool IsValidSignalType(int signal_type)
|
||||
|
||||
/* static */ bool ScriptRail::BuildSignal(TileIndex tile, TileIndex front, SignalType signal)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ScriptMap::DistanceManhattan(tile, front) == 1)
|
||||
EnforcePrecondition(false, ::IsPlainRailTile(tile));
|
||||
EnforcePrecondition(false, ::IsValidSignalType(signal));
|
||||
|
||||
Track track = INVALID_TRACK;
|
||||
uint signal_cycles;
|
||||
uint signal_cycles = 0;
|
||||
|
||||
int data_index = 2 + (::TileX(front) - ::TileX(tile)) + 2 * (::TileY(front) - ::TileY(tile));
|
||||
for (int i = 0; i < NUM_TRACK_DIRECTIONS; i++) {
|
||||
@@ -468,12 +469,12 @@ static bool IsValidSignalType(int signal_type)
|
||||
}
|
||||
::SignalType sig_type = (::SignalType)(signal >= SIGNALTYPE_TWOWAY ? signal ^ SIGNALTYPE_TWOWAY : signal);
|
||||
|
||||
return ScriptObject::Command<CMD_BUILD_SIGNALS>::Do(tile, track, sig_type, ::SIG_ELECTRIC, false, false, false, ::SIGTYPE_NORMAL, ::SIGTYPE_NORMAL, signal_cycles, 0);
|
||||
return ScriptObject::Command<CMD_BUILD_SINGLE_SIGNAL>::Do(tile, track, sig_type, ::SIG_ELECTRIC, false, false, false, ::SIGTYPE_BLOCK, ::SIGTYPE_BLOCK, signal_cycles, 0);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptRail::RemoveSignal(TileIndex tile, TileIndex front)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ScriptMap::DistanceManhattan(tile, front) == 1)
|
||||
EnforcePrecondition(false, GetSignalType(tile, front) != SIGNALTYPE_NONE);
|
||||
|
||||
@@ -487,7 +488,7 @@ static bool IsValidSignalType(int signal_type)
|
||||
}
|
||||
EnforcePrecondition(false, track != INVALID_TRACK);
|
||||
|
||||
return ScriptObject::Command<CMD_REMOVE_SIGNALS>::Do(tile, track);
|
||||
return ScriptObject::Command<CMD_REMOVE_SINGLE_SIGNAL>::Do(tile, track);
|
||||
}
|
||||
|
||||
/* static */ Money ScriptRail::GetBuildCost(RailType railtype, BuildType build_type)
|
||||
@@ -504,14 +505,14 @@ static bool IsValidSignalType(int signal_type)
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptRail::GetMaxSpeed(RailType railtype)
|
||||
/* static */ SQInteger ScriptRail::GetMaxSpeed(RailType railtype)
|
||||
{
|
||||
if (!ScriptRail::IsRailTypeAvailable(railtype)) return -1;
|
||||
|
||||
return ::GetRailTypeInfo((::RailType)railtype)->max_speed;
|
||||
}
|
||||
|
||||
/* static */ uint16 ScriptRail::GetMaintenanceCostFactor(RailType railtype)
|
||||
/* static */ SQInteger ScriptRail::GetMaintenanceCostFactor(RailType railtype)
|
||||
{
|
||||
if (!ScriptRail::IsRailTypeAvailable(railtype)) return 0;
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
*/
|
||||
enum SignalType {
|
||||
/* Note: these values represent part of the in-game SignalType enum */
|
||||
SIGNALTYPE_NORMAL = ::SIGTYPE_NORMAL, ///< Normal signal.
|
||||
SIGNALTYPE_NORMAL = ::SIGTYPE_BLOCK, ///< Block signal.
|
||||
SIGNALTYPE_ENTRY = ::SIGTYPE_ENTRY, ///< Entry presignal.
|
||||
SIGNALTYPE_EXIT = ::SIGTYPE_EXIT, ///< Exit signal.
|
||||
SIGNALTYPE_COMBO = ::SIGTYPE_COMBO, ///< Combo signal.
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
* means that the name could be something like "Maglev construction" instead
|
||||
* of just "Maglev".
|
||||
*/
|
||||
static char *GetName(RailType rail_type);
|
||||
static std::optional<std::string> GetName(RailType rail_type);
|
||||
|
||||
/**
|
||||
* Checks whether the given tile is actually a tile with rail that can be
|
||||
@@ -201,7 +201,7 @@ public:
|
||||
* @pre ScriptMap::IsValidTile(start_tile).
|
||||
* @pre ScriptMap::IsValidTile(end_tile).
|
||||
* @pre IsRailTypeAvailable(convert_to).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptRail::ERR_UNSUITABLE_TRACK
|
||||
* @return Whether at least some rail has been converted successfully.
|
||||
*/
|
||||
@@ -231,7 +231,7 @@ public:
|
||||
* @pre ScriptMap::IsValidTile(front).
|
||||
* @pre 'tile' is not equal to 'front', but in a straight line of it.
|
||||
* @pre IsRailTypeAvailable(GetCurrentRailType()).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_FLAT_LAND_REQUIRED
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
* @return Whether the rail depot has been/can be build or not.
|
||||
@@ -251,7 +251,7 @@ public:
|
||||
* @pre num_platforms > 0 && num_platforms <= 255.
|
||||
* @pre platform_length > 0 && platform_length <= 255.
|
||||
* @pre station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
* @exception ScriptError::ERR_FLAT_LAND_REQUIRED
|
||||
@@ -260,7 +260,7 @@ public:
|
||||
* @exception ScriptStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN
|
||||
* @return Whether the station has been/can be build or not.
|
||||
*/
|
||||
static bool BuildRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id);
|
||||
static bool BuildRailStation(TileIndex tile, RailTrack direction, SQInteger num_platforms, SQInteger platform_length, StationID station_id);
|
||||
|
||||
/**
|
||||
* Build a NewGRF rail station. This calls callback 18 to let a NewGRF
|
||||
@@ -288,7 +288,7 @@ public:
|
||||
* @pre ScriptCargo::IsValidCargo(cargo_type)
|
||||
* @pre source_industry == ScriptIndustryType::INDUSTRYTYPE_UNKNOWN || source_industry == ScriptIndustryType::INDUSTRYTYPE_TOWN || ScriptIndustryType::IsValidIndustryType(source_industry).
|
||||
* @pre goal_industry == ScriptIndustryType::INDUSTRYTYPE_UNKNOWN || goal_industry == ScriptIndustryType::INDUSTRYTYPE_TOWN || ScriptIndustryType::IsValidIndustryType(goal_industry).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
* @exception ScriptError::ERR_FLAT_LAND_REQUIRED
|
||||
@@ -297,7 +297,7 @@ public:
|
||||
* @exception ScriptStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN
|
||||
* @return Whether the station has been/can be build or not.
|
||||
*/
|
||||
static bool BuildNewGRFRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, int distance, bool source_station);
|
||||
static bool BuildNewGRFRailStation(TileIndex tile, RailTrack direction, SQInteger num_platforms, SQInteger platform_length, StationID station_id, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, SQInteger distance, bool source_station);
|
||||
|
||||
/**
|
||||
* Build a rail waypoint.
|
||||
@@ -306,7 +306,7 @@ public:
|
||||
* @pre IsRailTile(tile).
|
||||
* @pre GetRailTracks(tile) == RAILTRACK_NE_SW || GetRailTracks(tile) == RAILTRACK_NW_SE.
|
||||
* @pre IsRailTypeAvailable(GetCurrentRailType()).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_FLAT_LAND_REQUIRED
|
||||
* @return Whether the rail waypoint has been/can be build or not.
|
||||
*/
|
||||
@@ -319,7 +319,7 @@ public:
|
||||
* @param keep_rail Whether to keep the rail after removal.
|
||||
* @pre IsValidTile(tile).
|
||||
* @pre IsValidTile(tile2).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptRail::ERR_UNSUITABLE_TRACK
|
||||
* @return Whether at least one tile has been/can be cleared or not.
|
||||
*/
|
||||
@@ -332,7 +332,7 @@ public:
|
||||
* @param keep_rail Whether to keep the rail after removal.
|
||||
* @pre IsValidTile(tile).
|
||||
* @pre IsValidTile(tile2).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptRail::ERR_UNSUITABLE_TRACK
|
||||
* @return Whether at least one tile has been/can be cleared or not.
|
||||
*/
|
||||
@@ -353,7 +353,7 @@ public:
|
||||
* @param rail_track The RailTrack to build.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @pre IsRailTypeAvailable(GetCurrentRailType()).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
* @exception ScriptError::ERR_LAND_SLOPED_WRONG
|
||||
* @exception ScriptRoad::ERR_ROAD_WORKS_IN_PROGRESS
|
||||
@@ -371,7 +371,7 @@ public:
|
||||
* @param rail_track The RailTrack to remove.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @pre (GetRailTracks(tile) & rail_track) != 0.
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptRail::ERR_UNSUITABLE_TRACK
|
||||
* @return Whether the rail has been/can be removed or not.
|
||||
* @note You can only remove a single track with this function so do not
|
||||
@@ -404,7 +404,7 @@ public:
|
||||
* (ScriptMap::GetTileX(from) == ScriptMap::GetTileX(tile) && ScriptMap::GetTileX(tile) == ScriptMap::GetTileX(to)) ||
|
||||
* (ScriptMap::GetTileY(from) == ScriptMap::GetTileY(tile) && ScriptMap::GetTileY(tile) == ScriptMap::GetTileY(to)).
|
||||
* @pre IsRailTypeAvailable(GetCurrentRailType()).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
* @exception ScriptError::ERR_LAND_SLOPED_WRONG
|
||||
* @exception ScriptRail::ERR_CROSSING_ON_ONEWAY_ROAD
|
||||
@@ -427,7 +427,7 @@ public:
|
||||
* abs(ScriptMap::GetTileY(to) - ScriptMap::GetTileY(tile))) <= 1) ||
|
||||
* (ScriptMap::GetTileX(from) == ScriptMap::GetTileX(tile) && ScriptMap::GetTileX(tile) == ScriptMap::GetTileX(to)) ||
|
||||
* (ScriptMap::GetTileY(from) == ScriptMap::GetTileY(tile) && ScriptMap::GetTileY(tile) == ScriptMap::GetTileY(to)).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptRail::ERR_UNSUITABLE_TRACK
|
||||
* @return Whether the rail has been/can be removed or not.
|
||||
*/
|
||||
@@ -449,7 +449,7 @@ public:
|
||||
* @param signal The SignalType to build.
|
||||
* @pre ScriptMap::DistanceManhattan(tile, front) == 1.
|
||||
* @pre IsRailTile(tile) && !IsRailStationTile(tile) && !IsRailWaypointTile(tile).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptRail::ERR_UNSUITABLE_TRACK
|
||||
* @return Whether the signal has been/can be build or not.
|
||||
*/
|
||||
@@ -461,7 +461,7 @@ public:
|
||||
* @param front The tile in front of the signal.
|
||||
* @pre ScriptMap::DistanceManhattan(tile, front) == 1.
|
||||
* @pre GetSignalType(tile, front) != SIGNALTYPE_NONE.
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptRail::ERR_UNSUITABLE_TRACK
|
||||
* @return Whether the signal has been/can be removed or not.
|
||||
*/
|
||||
@@ -486,7 +486,7 @@ public:
|
||||
* This is mph / 1.6, which is roughly km/h.
|
||||
* To get km/h multiply this number by 1.00584.
|
||||
*/
|
||||
static int32 GetMaxSpeed(RailType railtype);
|
||||
static SQInteger GetMaxSpeed(RailType railtype);
|
||||
|
||||
/**
|
||||
* Get the maintenance cost factor of a railtype.
|
||||
@@ -494,7 +494,7 @@ public:
|
||||
* @pre IsRailTypeAvailable(railtype)
|
||||
* @return Maintenance cost factor of the railtype.
|
||||
*/
|
||||
static uint16 GetMaintenanceCostFactor(RailType railtype);
|
||||
static SQInteger GetMaintenanceCostFactor(RailType railtype);
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_RAIL_HPP */
|
||||
|
||||
@@ -9,13 +9,17 @@
|
||||
|
||||
#include "../../stdafx.h"
|
||||
#include "script_railtypelist.hpp"
|
||||
#include "script_error.hpp"
|
||||
#include "../../rail.h"
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
ScriptRailTypeList::ScriptRailTypeList()
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid_Void();
|
||||
bool is_deity = ScriptCompanyMode::IsDeity();
|
||||
CompanyID owner = ScriptObject::GetCompany();
|
||||
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
|
||||
if (ScriptObject::GetCompany() == OWNER_DEITY || ::HasRailtypeAvail(ScriptObject::GetCompany(), rt)) this->AddItem(rt);
|
||||
if (is_deity || ::HasRailTypeAvail(owner, rt)) this->AddItem(rt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "../../landscape_cmd.h"
|
||||
#include "../../road_cmd.h"
|
||||
#include "../../station_cmd.h"
|
||||
#include "../../newgrf_roadstop.h"
|
||||
#include "../../script/squirrel_helper_type.hpp"
|
||||
|
||||
#include "../../safeguards.h"
|
||||
@@ -24,9 +25,9 @@
|
||||
return ScriptCargo::HasCargoClass(cargo_type, ScriptCargo::CC_PASSENGERS) ? ROADVEHTYPE_BUS : ROADVEHTYPE_TRUCK;
|
||||
}
|
||||
|
||||
/* static */ char *ScriptRoad::GetName(RoadType road_type)
|
||||
/* static */ std::optional<std::string> ScriptRoad::GetName(RoadType road_type)
|
||||
{
|
||||
if (!IsRoadTypeAvailable(road_type)) return nullptr;
|
||||
if (!IsRoadTypeAvailable(road_type)) return std::nullopt;
|
||||
|
||||
return GetString(GetRoadTypeInfo((::RoadType)road_type)->strings.name);
|
||||
}
|
||||
@@ -66,6 +67,7 @@
|
||||
|
||||
/* static */ bool ScriptRoad::IsRoadTypeAvailable(RoadType road_type)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
return (::RoadType)road_type < ROADTYPE_END && ::HasRoadTypeAvail(ScriptObject::GetCompany(), (::RoadType)road_type);
|
||||
}
|
||||
|
||||
@@ -124,7 +126,7 @@
|
||||
|
||||
/* static */ bool ScriptRoad::ConvertRoadType(TileIndex start_tile, TileIndex end_tile, RoadType road_type)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(start_tile));
|
||||
EnforcePrecondition(false, ::IsValidTile(end_tile));
|
||||
EnforcePrecondition(false, IsRoadTypeAvailable(road_type));
|
||||
@@ -148,9 +150,9 @@
|
||||
* @param end The part that will be build second.
|
||||
* @return True if and only if the road bits can be build.
|
||||
*/
|
||||
static bool CheckAutoExpandedRoadBits(const Array *existing, int32 start, int32 end)
|
||||
static bool CheckAutoExpandedRoadBits(const Array<> &existing, int32_t start, int32_t end)
|
||||
{
|
||||
return (start + end == 0) && (existing->size == 0 || existing->array[0] == start || existing->array[0] == end);
|
||||
return (start + end == 0) && (existing.empty() || existing[0] == start || existing[0] == end);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,7 +165,7 @@ static bool CheckAutoExpandedRoadBits(const Array *existing, int32 start, int32
|
||||
* they are build or 2 when building the first part automatically
|
||||
* builds the second part.
|
||||
*/
|
||||
static int32 LookupWithoutBuildOnSlopes(::Slope slope, const Array *existing, int32 start, int32 end)
|
||||
static int32_t LookupWithoutBuildOnSlopes(::Slope slope, const Array<> &existing, int32_t start, int32_t end)
|
||||
{
|
||||
switch (slope) {
|
||||
/* Flat slopes can always be build. */
|
||||
@@ -175,9 +177,9 @@ static int32 LookupWithoutBuildOnSlopes(::Slope slope, const Array *existing, in
|
||||
* in the game have been changed.
|
||||
*/
|
||||
case SLOPE_NE: case SLOPE_SW:
|
||||
return (CheckAutoExpandedRoadBits(existing, start, end) && (start == 1 || end == 1)) ? (existing->size == 0 ? 2 : 1) : 0;
|
||||
return (CheckAutoExpandedRoadBits(existing, start, end) && (start == 1 || end == 1)) ? (existing.empty() ? 2 : 1) : 0;
|
||||
case SLOPE_SE: case SLOPE_NW:
|
||||
return (CheckAutoExpandedRoadBits(existing, start, end) && (start != 1 && end != 1)) ? (existing->size == 0 ? 2 : 1) : 0;
|
||||
return (CheckAutoExpandedRoadBits(existing, start, end) && (start != 1 && end != 1)) ? (existing.empty() ? 2 : 1) : 0;
|
||||
|
||||
/* Any other tile cannot be built on. */
|
||||
default:
|
||||
@@ -190,7 +192,7 @@ static int32 LookupWithoutBuildOnSlopes(::Slope slope, const Array *existing, in
|
||||
* @param neighbour The neighbour.
|
||||
* @return The rotate neighbour data.
|
||||
*/
|
||||
static int32 RotateNeighbour(int32 neighbour)
|
||||
static int32_t RotateNeighbour(int32_t neighbour)
|
||||
{
|
||||
switch (neighbour) {
|
||||
case -2: return -1;
|
||||
@@ -206,7 +208,7 @@ static int32 RotateNeighbour(int32 neighbour)
|
||||
* @param neighbour The neighbour.
|
||||
* @return The bits representing the direction.
|
||||
*/
|
||||
static RoadBits NeighbourToRoadBits(int32 neighbour)
|
||||
static RoadBits NeighbourToRoadBits(int32_t neighbour)
|
||||
{
|
||||
switch (neighbour) {
|
||||
case -2: return ROAD_NW;
|
||||
@@ -227,7 +229,7 @@ static RoadBits NeighbourToRoadBits(int32 neighbour)
|
||||
* they are build or 2 when building the first part automatically
|
||||
* builds the second part.
|
||||
*/
|
||||
static int32 LookupWithBuildOnSlopes(::Slope slope, Array *existing, int32 start, int32 end)
|
||||
static int32_t LookupWithBuildOnSlopes(::Slope slope, const Array<> &existing, int32_t start, int32_t end)
|
||||
{
|
||||
/* Steep slopes behave the same as slopes with one corner raised. */
|
||||
if (IsSteepSlope(slope)) {
|
||||
@@ -277,9 +279,6 @@ static int32 LookupWithBuildOnSlopes(::Slope slope, Array *existing, int32 start
|
||||
|
||||
/* Now perform the actual rotation. */
|
||||
for (int j = 0; j < base_rotate; j++) {
|
||||
for (size_t i = 0; i < existing->size; i++) {
|
||||
existing->array[i] = RotateNeighbour(existing->array[i]);
|
||||
}
|
||||
start = RotateNeighbour(start);
|
||||
end = RotateNeighbour(end);
|
||||
}
|
||||
@@ -288,8 +287,11 @@ static int32 LookupWithBuildOnSlopes(::Slope slope, Array *existing, int32 start
|
||||
RoadBits start_roadbits = NeighbourToRoadBits(start);
|
||||
RoadBits new_roadbits = start_roadbits | NeighbourToRoadBits(end);
|
||||
RoadBits existing_roadbits = ROAD_NONE;
|
||||
for (size_t i = 0; i < existing->size; i++) {
|
||||
existing_roadbits |= NeighbourToRoadBits(existing->array[i]);
|
||||
for (int32_t neighbour : existing) {
|
||||
for (int j = 0; j < base_rotate; j++) {
|
||||
neighbour = RotateNeighbour(neighbour);
|
||||
}
|
||||
existing_roadbits |= NeighbourToRoadBits(neighbour);
|
||||
}
|
||||
|
||||
switch (slope) {
|
||||
@@ -363,7 +365,7 @@ static int32 LookupWithBuildOnSlopes(::Slope slope, Array *existing, int32 start
|
||||
* @param tile The tile to normalise.
|
||||
* @return True if and only if the tile offset is valid.
|
||||
*/
|
||||
static bool NormaliseTileOffset(int32 *tile)
|
||||
static bool NormaliseTileOffset(int32_t *tile)
|
||||
{
|
||||
if (*tile == 1 || *tile == -1) return true;
|
||||
if (*tile == ::TileDiffXY(0, -1)) {
|
||||
@@ -377,17 +379,17 @@ static bool NormaliseTileOffset(int32 *tile)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptRoad::CanBuildConnectedRoadParts(ScriptTile::Slope slope_, Array *existing, TileIndex start_, TileIndex end_)
|
||||
/* static */ SQInteger ScriptRoad::CanBuildConnectedRoadParts(ScriptTile::Slope slope_, Array<> &&existing, TileIndex start_, TileIndex end_)
|
||||
{
|
||||
::Slope slope = (::Slope)slope_;
|
||||
int32 start = start_;
|
||||
int32 end = end_;
|
||||
int32_t start = start_.base();
|
||||
int32_t end = end_.base();
|
||||
|
||||
/* The start tile and end tile cannot be the same tile either. */
|
||||
if (start == end) return -1;
|
||||
|
||||
for (size_t i = 0; i < existing->size; i++) {
|
||||
if (!NormaliseTileOffset(&existing->array[i])) return -1;
|
||||
for (size_t i = 0; i < existing.size(); i++) {
|
||||
if (!NormaliseTileOffset(&existing[i])) return -1;
|
||||
}
|
||||
|
||||
if (!NormaliseTileOffset(&start)) return -1;
|
||||
@@ -398,15 +400,13 @@ static bool NormaliseTileOffset(int32 *tile)
|
||||
return _settings_game.construction.build_on_slopes ? LookupWithBuildOnSlopes(slope, existing, start, end) : LookupWithoutBuildOnSlopes(slope, existing, start, end);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptRoad::CanBuildConnectedRoadPartsHere(TileIndex tile, TileIndex start, TileIndex end)
|
||||
/* static */ SQInteger ScriptRoad::CanBuildConnectedRoadPartsHere(TileIndex tile, TileIndex start, TileIndex end)
|
||||
{
|
||||
if (!::IsValidTile(tile) || !::IsValidTile(start) || !::IsValidTile(end)) return -1;
|
||||
if (::DistanceManhattan(tile, start) != 1 || ::DistanceManhattan(tile, end) != 1) return -1;
|
||||
|
||||
/* ROAD_NW ROAD_SW ROAD_SE ROAD_NE */
|
||||
const TileIndexDiff neighbours[] = {::TileDiffXY(0, -1), ::TileDiffXY(1, 0), ::TileDiffXY(0, 1), ::TileDiffXY(-1, 0)};
|
||||
Array *existing = (Array*)alloca(sizeof(Array) + lengthof(neighbours) * sizeof(int32));
|
||||
existing->size = 0;
|
||||
|
||||
::RoadBits rb = ::ROAD_NONE;
|
||||
if (::IsNormalRoadTile(tile)) {
|
||||
@@ -414,11 +414,13 @@ static bool NormaliseTileOffset(int32 *tile)
|
||||
} else {
|
||||
rb = ::GetAnyRoadBits(tile, RTT_ROAD) | ::GetAnyRoadBits(tile, RTT_TRAM);
|
||||
}
|
||||
|
||||
Array<> existing;
|
||||
for (uint i = 0; i < lengthof(neighbours); i++) {
|
||||
if (HasBit(rb, i)) existing->array[existing->size++] = neighbours[i];
|
||||
if (HasBit(rb, i)) existing.emplace_back(neighbours[i]);
|
||||
}
|
||||
|
||||
return ScriptRoad::CanBuildConnectedRoadParts(ScriptTile::GetSlope(tile), existing, start - tile, end - tile);
|
||||
return ScriptRoad::CanBuildConnectedRoadParts(ScriptTile::GetSlope(tile), std::move(existing), start - tile, end - tile);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -449,13 +451,13 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptRoad::GetNeighbourRoadCount(TileIndex tile)
|
||||
/* static */ SQInteger ScriptRoad::GetNeighbourRoadCount(TileIndex tile)
|
||||
{
|
||||
if (!::IsValidTile(tile)) return false;
|
||||
if (!IsRoadTypeAvailable(GetCurrentRoadType())) return false;
|
||||
if (!::IsValidTile(tile)) return -1;
|
||||
if (!IsRoadTypeAvailable(GetCurrentRoadType())) return -1;
|
||||
|
||||
::RoadType rt = (::RoadType)GetCurrentRoadType();
|
||||
int32 neighbour = 0;
|
||||
int32_t neighbour = 0;
|
||||
|
||||
if (TileX(tile) > 0 && NeighbourHasReachableRoad(rt, tile, DIAGDIR_NE)) neighbour++;
|
||||
if (NeighbourHasReachableRoad(rt, tile, DIAGDIR_SE)) neighbour++;
|
||||
@@ -488,6 +490,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD
|
||||
|
||||
/* static */ bool ScriptRoad::_BuildRoadInternal(TileIndex start, TileIndex end, bool one_way, bool full)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
EnforcePrecondition(false, start != end);
|
||||
EnforcePrecondition(false, ::IsValidTile(start));
|
||||
EnforcePrecondition(false, ::IsValidTile(end));
|
||||
@@ -506,7 +509,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD
|
||||
|
||||
/* static */ bool ScriptRoad::BuildOneWayRoad(TileIndex start, TileIndex end)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
return _BuildRoadInternal(start, end, true, false);
|
||||
}
|
||||
|
||||
@@ -517,13 +520,13 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD
|
||||
|
||||
/* static */ bool ScriptRoad::BuildOneWayRoadFull(TileIndex start, TileIndex end)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
return _BuildRoadInternal(start, end, true, true);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptRoad::BuildRoadDepot(TileIndex tile, TileIndex front)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, tile != front);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, ::IsValidTile(front));
|
||||
@@ -537,7 +540,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD
|
||||
|
||||
/* static */ bool ScriptRoad::_BuildRoadStationInternal(TileIndex tile, TileIndex front, RoadVehicleType road_veh_type, bool drive_through, StationID station_id)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, tile != front);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, ::IsValidTile(front));
|
||||
@@ -549,7 +552,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD
|
||||
DiagDirection entrance_dir = DiagdirBetweenTiles(tile, front);
|
||||
RoadStopType stop_type = road_veh_type == ROADVEHTYPE_TRUCK ? ROADSTOP_TRUCK : ROADSTOP_BUS;
|
||||
StationID to_join = ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION;
|
||||
return ScriptObject::Command<CMD_BUILD_ROAD_STOP>::Do(tile, 1, 1, stop_type, drive_through, entrance_dir, ScriptObject::GetRoadType(), to_join, station_id != ScriptStation::STATION_JOIN_ADJACENT);
|
||||
return ScriptObject::Command<CMD_BUILD_ROAD_STOP>::Do(tile, 1, 1, stop_type, drive_through, entrance_dir, ScriptObject::GetRoadType(), ROADSTOP_CLASS_DFLT, 0, to_join, station_id != ScriptStation::STATION_JOIN_ADJACENT);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptRoad::BuildRoadStation(TileIndex tile, TileIndex front, RoadVehicleType road_veh_type, StationID station_id)
|
||||
@@ -564,7 +567,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD
|
||||
|
||||
/* static */ bool ScriptRoad::RemoveRoad(TileIndex start, TileIndex end)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, start != end);
|
||||
EnforcePrecondition(false, ::IsValidTile(start));
|
||||
EnforcePrecondition(false, ::IsValidTile(end));
|
||||
@@ -576,7 +579,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD
|
||||
|
||||
/* static */ bool ScriptRoad::RemoveRoadFull(TileIndex start, TileIndex end)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, start != end);
|
||||
EnforcePrecondition(false, ::IsValidTile(start));
|
||||
EnforcePrecondition(false, ::IsValidTile(end));
|
||||
@@ -588,7 +591,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD
|
||||
|
||||
/* static */ bool ScriptRoad::RemoveRoadDepot(TileIndex tile)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, IsTileType(tile, MP_ROAD))
|
||||
EnforcePrecondition(false, GetRoadTileType(tile) == ROAD_TILE_DEPOT);
|
||||
@@ -598,7 +601,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD
|
||||
|
||||
/* static */ bool ScriptRoad::RemoveRoadStation(TileIndex tile)
|
||||
{
|
||||
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, ::IsValidTile(tile));
|
||||
EnforcePrecondition(false, IsTileType(tile, MP_STATION));
|
||||
EnforcePrecondition(false, IsRoadStop(tile));
|
||||
@@ -624,14 +627,14 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD
|
||||
return (RoadTramTypes)(1 << ::GetRoadTramType((::RoadType)roadtype));
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptRoad::GetMaxSpeed(RoadType road_type)
|
||||
/* static */ SQInteger ScriptRoad::GetMaxSpeed(RoadType road_type)
|
||||
{
|
||||
if (!ScriptRoad::IsRoadTypeAvailable(road_type)) return 0;
|
||||
if (!ScriptRoad::IsRoadTypeAvailable(road_type)) return -1;
|
||||
|
||||
return GetRoadTypeInfo((::RoadType)road_type)->max_speed;
|
||||
}
|
||||
|
||||
/* static */ uint16 ScriptRoad::GetMaintenanceCostFactor(RoadType roadtype)
|
||||
/* static */ SQInteger ScriptRoad::GetMaintenanceCostFactor(RoadType roadtype)
|
||||
{
|
||||
if (!ScriptRoad::IsRoadTypeAvailable(roadtype)) return 0;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define SCRIPT_ROAD_HPP
|
||||
|
||||
#include "script_tile.hpp"
|
||||
#include "../squirrel_helper_type.hpp"
|
||||
#include "../../../road.h"
|
||||
|
||||
/**
|
||||
@@ -60,7 +61,7 @@ public:
|
||||
/**
|
||||
* Road/tram types
|
||||
*/
|
||||
enum RoadTramTypes : uint8 {
|
||||
enum RoadTramTypes : uint8_t {
|
||||
ROADTRAMTYPES_ROAD = ::RTTB_ROAD, ///< Road road types.
|
||||
ROADTRAMTYPES_TRAM = ::RTTB_TRAM, ///< Tram road types.
|
||||
};
|
||||
@@ -89,7 +90,7 @@ public:
|
||||
* @pre IsRoadTypeAvailable(road_type).
|
||||
* @return The name the road type has.
|
||||
*/
|
||||
static char *GetName(RoadType road_type);
|
||||
static std::optional<std::string> GetName(RoadType road_type);
|
||||
|
||||
/**
|
||||
* Determines whether a busstop or a truckstop is needed to transport a certain cargo.
|
||||
@@ -140,7 +141,7 @@ public:
|
||||
/**
|
||||
* Check if a given RoadType is available.
|
||||
* @param road_type The RoadType to check for.
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @return True if this RoadType can be used.
|
||||
*/
|
||||
static bool IsRoadTypeAvailable(RoadType road_type);
|
||||
@@ -186,7 +187,7 @@ public:
|
||||
* @pre ScriptMap::IsValidTile(start_tile).
|
||||
* @pre ScriptMap::IsValidTile(end_tile).
|
||||
* @pre IsRoadTypeAvailable(road_type).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptRoad::ERR_UNSUITABLE_ROAD
|
||||
* @return Whether at least some road has been converted successfully.
|
||||
*/
|
||||
@@ -245,7 +246,7 @@ public:
|
||||
* they are build or 2 when building the first part automatically
|
||||
* builds the second part. -1 means the preconditions are not met.
|
||||
*/
|
||||
static int32 CanBuildConnectedRoadParts(ScriptTile::Slope slope, struct Array *existing, TileIndex start, TileIndex end);
|
||||
static SQInteger CanBuildConnectedRoadParts(ScriptTile::Slope slope, Array<> &&existing, TileIndex start, TileIndex end);
|
||||
|
||||
/**
|
||||
* Lookup function for building road parts independent of whether the
|
||||
@@ -266,7 +267,7 @@ public:
|
||||
* they are build or 2 when building the first part automatically
|
||||
* builds the second part. -1 means the preconditions are not met.
|
||||
*/
|
||||
static int32 CanBuildConnectedRoadPartsHere(TileIndex tile, TileIndex start, TileIndex end);
|
||||
static SQInteger CanBuildConnectedRoadPartsHere(TileIndex tile, TileIndex start, TileIndex end);
|
||||
|
||||
/**
|
||||
* Count how many neighbours are road.
|
||||
@@ -275,7 +276,7 @@ public:
|
||||
* @pre IsRoadTypeAvailable(GetCurrentRoadType()).
|
||||
* @return 0 means no neighbour road; max value is 4.
|
||||
*/
|
||||
static int32 GetNeighbourRoadCount(TileIndex tile);
|
||||
static SQInteger GetNeighbourRoadCount(TileIndex tile);
|
||||
|
||||
/**
|
||||
* Gets the tile in front of a road depot.
|
||||
@@ -321,7 +322,7 @@ public:
|
||||
* @exception ScriptRoad::ERR_ROAD_WORKS_IN_PROGRESS
|
||||
* @exception ScriptError::ERR_VEHICLE_IN_THE_WAY
|
||||
* @note Construction will fail if an obstacle is found between the start and end tiles.
|
||||
* @game @note Building a piece of road (without CompanyMode) results in a piece of road owned by towns.
|
||||
* @game @note Building a piece of road as deity (ScriptCompanyMode::IsDeity()) results in a piece of road owned by towns.
|
||||
* @return Whether the road has been/can be build or not.
|
||||
*/
|
||||
static bool BuildRoad(TileIndex start, TileIndex end);
|
||||
@@ -342,7 +343,7 @@ public:
|
||||
* ScriptMap::GetTileX(start) == ScriptMap::GetTileX(end) or
|
||||
* ScriptMap::GetTileY(start) == ScriptMap::GetTileY(end).
|
||||
* @pre GetCurrentRoadType() == ROADTYPE_ROAD.
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_ALREADY_BUILT
|
||||
* @exception ScriptError::ERR_LAND_SLOPED_WRONG
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
@@ -373,7 +374,7 @@ public:
|
||||
* @exception ScriptRoad::ERR_ROAD_WORKS_IN_PROGRESS
|
||||
* @exception ScriptError::ERR_VEHICLE_IN_THE_WAY
|
||||
* @note Construction will fail if an obstacle is found between the start and end tiles.
|
||||
* @game @note Building a piece of road (without CompanyMode) results in a piece of road owned by towns.
|
||||
* @game @note Building a piece of road as deity (ScriptCompanyMode::IsDeity()) results in a piece of road owned by towns.
|
||||
* @return Whether the road has been/can be build or not.
|
||||
*/
|
||||
static bool BuildRoadFull(TileIndex start, TileIndex end);
|
||||
@@ -394,7 +395,7 @@ public:
|
||||
* ScriptMap::GetTileX(start) == ScriptMap::GetTileX(end) or
|
||||
* ScriptMap::GetTileY(start) == ScriptMap::GetTileY(end).
|
||||
* @pre GetCurrentRoadType() == ROADTYPE_ROAD.
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_ALREADY_BUILT
|
||||
* @exception ScriptError::ERR_LAND_SLOPED_WRONG
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
@@ -414,7 +415,7 @@ public:
|
||||
* @pre ScriptMap::IsValidTile(front).
|
||||
* @pre 'tile' is not equal to 'front', but in a straight line of it.
|
||||
* @pre IsRoadTypeAvailable(GetCurrentRoadType()).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_FLAT_LAND_REQUIRED
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
* @return Whether the road depot has been/can be build or not.
|
||||
@@ -432,7 +433,7 @@ public:
|
||||
* @pre 'tile' is not equal to 'front', but in a straight line of it.
|
||||
* @pre station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id).
|
||||
* @pre GetCurrentRoadType() == ROADTYPE_ROAD.
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
* @exception ScriptError::ERR_FLAT_LAND_REQUIRED
|
||||
@@ -457,7 +458,7 @@ public:
|
||||
* @pre 'tile' is not equal to 'front', but in a straight line of it.
|
||||
* @pre station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id).
|
||||
* @pre IsRoadTypeAvailable(GetCurrentRoadType()).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @exception ScriptError::ERR_AREA_NOT_CLEAR
|
||||
* @exception ScriptError::ERR_FLAT_LAND_REQUIRED
|
||||
@@ -482,7 +483,7 @@ public:
|
||||
* ScriptMap::GetTileX(start) == ScriptMap::GetTileX(end) or
|
||||
* ScriptMap::GetTileY(start) == ScriptMap::GetTileY(end).
|
||||
* @pre IsRoadTypeAvailable(GetCurrentRoadType()).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @exception ScriptError::ERR_VEHICLE_IN_THE_WAY
|
||||
* @exception ScriptRoad::ERR_ROAD_WORKS_IN_PROGRESS
|
||||
@@ -502,7 +503,7 @@ public:
|
||||
* ScriptMap::GetTileX(start) == ScriptMap::GetTileX(end) or
|
||||
* ScriptMap::GetTileY(start) == ScriptMap::GetTileY(end).
|
||||
* @pre IsRoadTypeAvailable(GetCurrentRoadType()).
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @exception ScriptError::ERR_VEHICLE_IN_THE_WAY
|
||||
* @exception ScriptRoad::ERR_ROAD_WORKS_IN_PROGRESS
|
||||
@@ -515,7 +516,7 @@ public:
|
||||
* @param tile Place to remove the depot from.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @pre Tile is a road depot.
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @exception ScriptError::ERR_VEHICLE_IN_THE_WAY
|
||||
* @return Whether the road depot has been/can be removed or not.
|
||||
@@ -527,7 +528,7 @@ public:
|
||||
* @param tile Place to remove the station from.
|
||||
* @pre ScriptMap::IsValidTile(tile).
|
||||
* @pre Tile is a road station.
|
||||
* @game @pre Valid ScriptCompanyMode active in scope.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
|
||||
* @exception ScriptError::ERR_VEHICLE_IN_THE_WAY
|
||||
* @return Whether the station has been/can be removed or not.
|
||||
@@ -560,7 +561,7 @@ public:
|
||||
* This is mph / 0.8, which is roughly 0.5 km/h.
|
||||
* To get km/h multiply this number by 2.01168.
|
||||
*/
|
||||
static int32 GetMaxSpeed(RoadType road_type);
|
||||
static SQInteger GetMaxSpeed(RoadType road_type);
|
||||
|
||||
/**
|
||||
* Get the maintenance cost factor of a road type.
|
||||
@@ -568,7 +569,7 @@ public:
|
||||
* @pre IsRoadTypeAvailable(roadtype)
|
||||
* @return Maintenance cost factor of the roadtype.
|
||||
*/
|
||||
static uint16 GetMaintenanceCostFactor(RoadType roadtype);
|
||||
static SQInteger GetMaintenanceCostFactor(RoadType roadtype);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
|
||||
ScriptRoadTypeList::ScriptRoadTypeList(ScriptRoad::RoadTramTypes rtts)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid_Void();
|
||||
CompanyID owner = ScriptObject::GetCompany();
|
||||
for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
|
||||
if (!HasBit(rtts, GetRoadTramType(rt))) continue;
|
||||
if (ScriptObject::GetCompany() == OWNER_DEITY || ::HasRoadTypeAvail(ScriptObject::GetCompany(), rt)) this->AddItem(rt);
|
||||
if (::HasRoadTypeAvail(owner, rt)) this->AddItem(rt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
/* static */ bool ScriptSign::IsValidSign(SignID sign_id)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
const Sign *si = ::Sign::GetIfValid(sign_id);
|
||||
return si != nullptr && (si->owner == ScriptObject::GetCompany() || si->owner == OWNER_DEITY);
|
||||
}
|
||||
@@ -36,18 +37,19 @@
|
||||
{
|
||||
CCountedPtr<Text> counter(name);
|
||||
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidSign(sign_id));
|
||||
EnforcePrecondition(false, name != nullptr);
|
||||
const char *text = name->GetDecodedText();
|
||||
const std::string &text = name->GetDecodedText();
|
||||
EnforcePreconditionEncodedText(false, text);
|
||||
EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_SIGN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG);
|
||||
|
||||
return ScriptObject::Command<CMD_RENAME_SIGN>::Do(sign_id, text);
|
||||
}
|
||||
|
||||
/* static */ char *ScriptSign::GetName(SignID sign_id)
|
||||
/* static */ std::optional<std::string> ScriptSign::GetName(SignID sign_id)
|
||||
{
|
||||
if (!IsValidSign(sign_id)) return nullptr;
|
||||
if (!IsValidSign(sign_id)) return std::nullopt;
|
||||
|
||||
::SetDParam(0, sign_id);
|
||||
return GetString(STR_SIGN_NAME);
|
||||
@@ -63,6 +65,7 @@
|
||||
|
||||
/* static */ bool ScriptSign::RemoveSign(SignID sign_id)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidSign(sign_id));
|
||||
return ScriptObject::Command<CMD_RENAME_SIGN>::Do(sign_id, "");
|
||||
}
|
||||
@@ -71,9 +74,10 @@
|
||||
{
|
||||
CCountedPtr<Text> counter(name);
|
||||
|
||||
EnforceDeityOrCompanyModeValid(INVALID_SIGN);
|
||||
EnforcePrecondition(INVALID_SIGN, ::IsValidTile(location));
|
||||
EnforcePrecondition(INVALID_SIGN, name != nullptr);
|
||||
const char *text = name->GetDecodedText();
|
||||
const std::string &text = name->GetDecodedText();
|
||||
EnforcePreconditionEncodedText(INVALID_SIGN, text);
|
||||
EnforcePreconditionCustomError(INVALID_SIGN, ::Utf8StringLength(text) < MAX_LENGTH_SIGN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG);
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
* @pre IsValidSign(sign_id).
|
||||
* @return The name of the sign.
|
||||
*/
|
||||
static char *GetName(SignID sign_id);
|
||||
static std::optional<std::string> GetName(SignID sign_id);
|
||||
|
||||
/**
|
||||
* Get the owner of a sign.
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
ScriptSignList::ScriptSignList()
|
||||
ScriptSignList::ScriptSignList(HSQUIRRELVM vm)
|
||||
{
|
||||
for (const Sign *s : Sign::Iterate()) {
|
||||
if (ScriptSign::IsValidSign(s->index)) this->AddItem(s->index);
|
||||
}
|
||||
ScriptList::FillList<Sign>(vm, this,
|
||||
[](const Sign *s) { return ScriptSign::IsValidSign(s->index); }
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,29 @@
|
||||
*/
|
||||
class ScriptSignList : public ScriptList {
|
||||
public:
|
||||
#ifdef DOXYGEN_API
|
||||
ScriptSignList();
|
||||
|
||||
/**
|
||||
* Apply a filter when building the list.
|
||||
* @param filter_function The function which will be doing the filtering.
|
||||
* @param params The params to give to the filters (minus the first param,
|
||||
* which is always the index-value).
|
||||
* @note You can write your own filters and use them. Just remember that
|
||||
* the first parameter should be the index-value, and it should return
|
||||
* a bool.
|
||||
* @note Example:
|
||||
* function Contains(sign_id, str)
|
||||
* {
|
||||
* local name = ScriptSign.GetName(sign_id);
|
||||
* return name != null && name.find(str) != null;
|
||||
* }
|
||||
* ScriptSignList(Contains, "something");
|
||||
*/
|
||||
ScriptSignList(void *filter_function, int params, ...);
|
||||
#else
|
||||
ScriptSignList(HSQUIRRELVM);
|
||||
#endif /* DOXYGEN_API */
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_SIGNLIST_HPP */
|
||||
|
||||
@@ -21,8 +21,9 @@
|
||||
|
||||
/* static */ bool ScriptStation::IsValidStation(StationID station_id)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid(false);
|
||||
const Station *st = ::Station::GetIfValid(station_id);
|
||||
return st != nullptr && (st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY || st->owner == OWNER_NONE);
|
||||
return st != nullptr && (st->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity() || st->owner == OWNER_NONE);
|
||||
}
|
||||
|
||||
/* static */ ScriptCompany::CompanyID ScriptStation::GetOwner(StationID station_id)
|
||||
@@ -50,7 +51,7 @@ template<bool Tfrom, bool Tvia>
|
||||
}
|
||||
|
||||
template<bool Tfrom, bool Tvia>
|
||||
/* static */ int32 ScriptStation::CountCargoWaiting(StationID station_id,
|
||||
/* static */ SQInteger ScriptStation::CountCargoWaiting(StationID station_id,
|
||||
StationID from_station_id, StationID via_station_id, CargoID cargo_id)
|
||||
{
|
||||
if (!ScriptStation::IsCargoRequestValid<Tfrom, Tvia>(station_id, from_station_id,
|
||||
@@ -61,44 +62,44 @@ template<bool Tfrom, bool Tvia>
|
||||
const StationCargoList &cargo_list = ::Station::Get(station_id)->goods[cargo_id].cargo;
|
||||
if (!Tfrom && !Tvia) return cargo_list.TotalCount();
|
||||
|
||||
uint16 cargo_count = 0;
|
||||
uint16_t cargo_count = 0;
|
||||
std::pair<StationCargoList::ConstIterator, StationCargoList::ConstIterator> range = Tvia ?
|
||||
cargo_list.Packets()->equal_range(via_station_id) :
|
||||
std::make_pair(StationCargoList::ConstIterator(cargo_list.Packets()->begin()),
|
||||
StationCargoList::ConstIterator(cargo_list.Packets()->end()));
|
||||
for (StationCargoList::ConstIterator it = range.first; it != range.second; it++) {
|
||||
const CargoPacket *cp = *it;
|
||||
if (!Tfrom || cp->SourceStation() == from_station_id) cargo_count += cp->Count();
|
||||
if (!Tfrom || cp->GetFirstStation() == from_station_id) cargo_count += cp->Count();
|
||||
}
|
||||
|
||||
return cargo_count;
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptStation::GetCargoWaiting(StationID station_id, CargoID cargo_id)
|
||||
/* static */ SQInteger ScriptStation::GetCargoWaiting(StationID station_id, CargoID cargo_id)
|
||||
{
|
||||
return CountCargoWaiting<false, false>(station_id, STATION_INVALID, STATION_INVALID, cargo_id);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptStation::GetCargoWaitingFrom(StationID station_id,
|
||||
/* static */ SQInteger ScriptStation::GetCargoWaitingFrom(StationID station_id,
|
||||
StationID from_station_id, CargoID cargo_id)
|
||||
{
|
||||
return CountCargoWaiting<true, false>(station_id, from_station_id, STATION_INVALID, cargo_id);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptStation::GetCargoWaitingVia(StationID station_id,
|
||||
/* static */ SQInteger ScriptStation::GetCargoWaitingVia(StationID station_id,
|
||||
StationID via_station_id, CargoID cargo_id)
|
||||
{
|
||||
return CountCargoWaiting<false, true>(station_id, STATION_INVALID, via_station_id, cargo_id);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptStation::GetCargoWaitingFromVia(StationID station_id,
|
||||
/* static */ SQInteger ScriptStation::GetCargoWaitingFromVia(StationID station_id,
|
||||
StationID from_station_id, StationID via_station_id, CargoID cargo_id)
|
||||
{
|
||||
return CountCargoWaiting<true, true>(station_id, from_station_id, via_station_id, cargo_id);
|
||||
}
|
||||
|
||||
template<bool Tfrom, bool Tvia>
|
||||
/* static */ int32 ScriptStation::CountCargoPlanned(StationID station_id,
|
||||
/* static */ SQInteger ScriptStation::CountCargoPlanned(StationID station_id,
|
||||
StationID from_station_id, StationID via_station_id, CargoID cargo_id)
|
||||
{
|
||||
if (!ScriptStation::IsCargoRequestValid<Tfrom, Tvia>(station_id, from_station_id,
|
||||
@@ -115,24 +116,24 @@ template<bool Tfrom, bool Tvia>
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptStation::GetCargoPlanned(StationID station_id, CargoID cargo_id)
|
||||
/* static */ SQInteger ScriptStation::GetCargoPlanned(StationID station_id, CargoID cargo_id)
|
||||
{
|
||||
return CountCargoPlanned<false, false>(station_id, STATION_INVALID, STATION_INVALID, cargo_id);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptStation::GetCargoPlannedFrom(StationID station_id,
|
||||
/* static */ SQInteger ScriptStation::GetCargoPlannedFrom(StationID station_id,
|
||||
StationID from_station_id, CargoID cargo_id)
|
||||
{
|
||||
return CountCargoPlanned<true, false>(station_id, from_station_id, STATION_INVALID, cargo_id);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptStation::GetCargoPlannedVia(StationID station_id,
|
||||
/* static */ SQInteger ScriptStation::GetCargoPlannedVia(StationID station_id,
|
||||
StationID via_station_id, CargoID cargo_id)
|
||||
{
|
||||
return CountCargoPlanned<false, true>(station_id, STATION_INVALID, via_station_id, cargo_id);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptStation::GetCargoPlannedFromVia(StationID station_id,
|
||||
/* static */ SQInteger ScriptStation::GetCargoPlannedFromVia(StationID station_id,
|
||||
StationID from_station_id, StationID via_station_id, CargoID cargo_id)
|
||||
{
|
||||
return CountCargoPlanned<true, true>(station_id, from_station_id, via_station_id, cargo_id);
|
||||
@@ -146,14 +147,14 @@ template<bool Tfrom, bool Tvia>
|
||||
return ::Station::Get(station_id)->goods[cargo_id].HasRating();
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptStation::GetCargoRating(StationID station_id, CargoID cargo_id)
|
||||
/* static */ SQInteger ScriptStation::GetCargoRating(StationID station_id, CargoID cargo_id)
|
||||
{
|
||||
if (!ScriptStation::HasCargoRating(station_id, cargo_id)) return -1;
|
||||
|
||||
return ::ToPercent8(::Station::Get(station_id)->goods[cargo_id].rating);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptStation::GetCoverageRadius(ScriptStation::StationType station_type)
|
||||
/* static */ SQInteger ScriptStation::GetCoverageRadius(ScriptStation::StationType station_type)
|
||||
{
|
||||
if (station_type == STATION_AIRPORT) return -1;
|
||||
if (!HasExactlyOneBit(station_type)) return -1;
|
||||
@@ -169,21 +170,21 @@ template<bool Tfrom, bool Tvia>
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptStation::GetStationCoverageRadius(StationID station_id)
|
||||
/* static */ SQInteger ScriptStation::GetStationCoverageRadius(StationID station_id)
|
||||
{
|
||||
if (!IsValidStation(station_id)) return -1;
|
||||
|
||||
return Station::Get(station_id)->GetCatchmentRadius();
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptStation::GetDistanceManhattanToTile(StationID station_id, TileIndex tile)
|
||||
/* static */ SQInteger ScriptStation::GetDistanceManhattanToTile(StationID station_id, TileIndex tile)
|
||||
{
|
||||
if (!IsValidStation(station_id)) return -1;
|
||||
|
||||
return ScriptMap::DistanceManhattan(tile, GetLocation(station_id));
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptStation::GetDistanceSquareToTile(StationID station_id, TileIndex tile)
|
||||
/* static */ SQInteger ScriptStation::GetDistanceSquareToTile(StationID station_id, TileIndex tile)
|
||||
{
|
||||
if (!IsValidStation(station_id)) return -1;
|
||||
|
||||
@@ -202,7 +203,7 @@ template<bool Tfrom, bool Tvia>
|
||||
if (!IsValidStation(station_id)) return false;
|
||||
if (!HasExactlyOneBit(station_type)) return false;
|
||||
|
||||
return (::Station::Get(station_id)->facilities & station_type) != 0;
|
||||
return (::Station::Get(station_id)->facilities & static_cast<StationFacility>(station_type)) != 0;
|
||||
}
|
||||
|
||||
/* static */ bool ScriptStation::HasRoadType(StationID station_id, ScriptRoad::RoadType road_type)
|
||||
@@ -237,6 +238,7 @@ template<bool Tfrom, bool Tvia>
|
||||
|
||||
/* static */ bool ScriptStation::OpenCloseAirport(StationID station_id)
|
||||
{
|
||||
EnforceCompanyModeValid(false);
|
||||
EnforcePrecondition(false, IsValidStation(station_id));
|
||||
EnforcePrecondition(false, HasStationType(station_id, STATION_AIRPORT));
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
* @pre IsValidCargo(cargo_id).
|
||||
* @return The amount of units waiting at the station.
|
||||
*/
|
||||
static int32 GetCargoWaiting(StationID station_id, CargoID cargo_id);
|
||||
static SQInteger GetCargoWaiting(StationID station_id, CargoID cargo_id);
|
||||
|
||||
/**
|
||||
* See how much cargo with a specific source station there is waiting on a station.
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
* @return The amount of units waiting at the station originating from from_station_id.
|
||||
* @note source station means, the station where cargo was first loaded.
|
||||
*/
|
||||
static int32 GetCargoWaitingFrom(StationID station_id, StationID from_station_id, CargoID cargo_id);
|
||||
static SQInteger GetCargoWaitingFrom(StationID station_id, StationID from_station_id, CargoID cargo_id);
|
||||
|
||||
/**
|
||||
* See how much cargo with a specific via-station there is waiting on a station.
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
* @return The amount of units waiting at the station with via_station_id as next hop.
|
||||
* @note if ScriptCargo.GetCargoDistributionType(cargo_id) == ScriptCargo.DT_MANUAL, then all waiting cargo will have STATION_INVALID as next hop.
|
||||
*/
|
||||
static int32 GetCargoWaitingVia(StationID station_id, StationID via_station_id, CargoID cargo_id);
|
||||
static SQInteger GetCargoWaitingVia(StationID station_id, StationID via_station_id, CargoID cargo_id);
|
||||
|
||||
/**
|
||||
* See how much cargo with a specific via-station and source station there is waiting on a station.
|
||||
@@ -123,7 +123,7 @@ public:
|
||||
* @return The amount of units waiting at the station with from_station_id as source and via_station_id as next hop.
|
||||
* @note if ScriptCargo.GetCargoDistributionType(cargo_id) == ScriptCargo.DT_MANUAL, then all waiting cargo will have STATION_INVALID as next hop.
|
||||
*/
|
||||
static int32 GetCargoWaitingFromVia(StationID station_id, StationID from_station_id, StationID via_station_id, CargoID cargo_id);
|
||||
static SQInteger GetCargoWaitingFromVia(StationID station_id, StationID from_station_id, StationID via_station_id, CargoID cargo_id);
|
||||
|
||||
/**
|
||||
* See how much cargo was planned to pass (including production and consumption) this station per month.
|
||||
@@ -133,7 +133,7 @@ public:
|
||||
* @pre IsValidCargo(cargo_id).
|
||||
* @return The amount of cargo units planned to pass the station per month.
|
||||
*/
|
||||
static int32 GetCargoPlanned(StationID station_id, CargoID cargo_id);
|
||||
static SQInteger GetCargoPlanned(StationID station_id, CargoID cargo_id);
|
||||
|
||||
/**
|
||||
* See how much cargo from the specified origin was planned to pass (including production and consumption) this station per month.
|
||||
@@ -145,7 +145,7 @@ public:
|
||||
* @pre IsValidCargo(cargo_id).
|
||||
* @return The amount of cargo units from the specified origin planned to pass the station per month.
|
||||
*/
|
||||
static int32 GetCargoPlannedFrom(StationID station_id, StationID from_station_id, CargoID cargo_id);
|
||||
static SQInteger GetCargoPlannedFrom(StationID station_id, StationID from_station_id, CargoID cargo_id);
|
||||
|
||||
/**
|
||||
* See how much cargo was planned to pass (including production and consumption) this station per month, heading for the specified next hop.
|
||||
@@ -158,7 +158,7 @@ public:
|
||||
* @return The amount of cargo units planned to pass the station per month, going via the specified next hop.
|
||||
* @note Cargo planned to go "via" the same station that's being queried is actually planned to be consumed there.
|
||||
*/
|
||||
static int32 GetCargoPlannedVia(StationID station_id, StationID via_station_id, CargoID cargo_id);
|
||||
static SQInteger GetCargoPlannedVia(StationID station_id, StationID via_station_id, CargoID cargo_id);
|
||||
|
||||
/**
|
||||
* See how much cargo from the specified origin was planned to pass this station per month,
|
||||
@@ -175,7 +175,7 @@ public:
|
||||
* @note Cargo planned to go "via" the same station that's being queried is actually planned to be consumed there.
|
||||
* @note Cargo planned to pass "from" the same station that's being queried is actually produced there.
|
||||
*/
|
||||
static int32 GetCargoPlannedFromVia(StationID station_id, StationID from_station_id, StationID via_station_id, CargoID cargo_id);
|
||||
static SQInteger GetCargoPlannedFromVia(StationID station_id, StationID from_station_id, StationID via_station_id, CargoID cargo_id);
|
||||
|
||||
/**
|
||||
* Check whether the given cargo at the given station a rating.
|
||||
@@ -196,7 +196,7 @@ public:
|
||||
* @pre HasCargoRating(station_id, cargo_id).
|
||||
* @return The rating in percent of the cargo on the station.
|
||||
*/
|
||||
static int32 GetCargoRating(StationID station_id, CargoID cargo_id);
|
||||
static SQInteger GetCargoRating(StationID station_id, CargoID cargo_id);
|
||||
|
||||
/**
|
||||
* Get the coverage radius of this type of station.
|
||||
@@ -205,7 +205,7 @@ public:
|
||||
* @return The radius in tiles.
|
||||
* @note Coverage radius of airports needs to be requested via ScriptAirport::GetAirportCoverageRadius(), as it requires AirportType.
|
||||
*/
|
||||
static int32 GetCoverageRadius(ScriptStation::StationType station_type);
|
||||
static SQInteger GetCoverageRadius(ScriptStation::StationType station_type);
|
||||
|
||||
/**
|
||||
* Get the coverage radius of this station.
|
||||
@@ -213,7 +213,7 @@ public:
|
||||
* @pre IsValidStation(station_id).
|
||||
* @return The radius in tiles.
|
||||
*/
|
||||
static int32 GetStationCoverageRadius(StationID station_id);
|
||||
static SQInteger GetStationCoverageRadius(StationID station_id);
|
||||
|
||||
/**
|
||||
* Get the manhattan distance from the tile to the ScriptStation::GetLocation()
|
||||
@@ -223,7 +223,7 @@ public:
|
||||
* @pre IsValidStation(station_id).
|
||||
* @return The distance between station and tile.
|
||||
*/
|
||||
static int32 GetDistanceManhattanToTile(StationID station_id, TileIndex tile);
|
||||
static SQInteger GetDistanceManhattanToTile(StationID station_id, TileIndex tile);
|
||||
|
||||
/**
|
||||
* Get the square distance from the tile to the ScriptStation::GetLocation()
|
||||
@@ -233,7 +233,7 @@ public:
|
||||
* @pre IsValidStation(station_id).
|
||||
* @return The distance between station and tile.
|
||||
*/
|
||||
static int32 GetDistanceSquareToTile(StationID station_id, TileIndex tile);
|
||||
static SQInteger GetDistanceSquareToTile(StationID station_id, TileIndex tile);
|
||||
|
||||
/**
|
||||
* Find out if this station is within the rating influence of a town.
|
||||
@@ -287,6 +287,7 @@ public:
|
||||
/**
|
||||
* Toggle the open/closed state of an airport.
|
||||
* @param station_id The airport to modify.
|
||||
* @game @pre ScriptCompanyMode::IsValid().
|
||||
* @pre IsValidStation(station_id).
|
||||
* @pre HasStationType(station_id, STATION_AIRPORT).
|
||||
* @return True if the state was toggled successfully.
|
||||
@@ -299,11 +300,11 @@ private:
|
||||
StationID via_station_id, CargoID cargo_id);
|
||||
|
||||
template<bool Tfrom, bool Tvia>
|
||||
static int32 CountCargoWaiting(StationID station_id, StationID from_station_id,
|
||||
static SQInteger CountCargoWaiting(StationID station_id, StationID from_station_id,
|
||||
StationID via_station_id, CargoID cargo_id);
|
||||
|
||||
template<bool Tfrom, bool Tvia>
|
||||
static int32 CountCargoPlanned(StationID station_id, StationID from_station_id,
|
||||
static SQInteger CountCargoPlanned(StationID station_id, StationID from_station_id,
|
||||
StationID via_station_id, CargoID cargo_id);
|
||||
|
||||
};
|
||||
|
||||
@@ -18,14 +18,19 @@
|
||||
|
||||
ScriptStationList::ScriptStationList(ScriptStation::StationType station_type)
|
||||
{
|
||||
for (Station *st : Station::Iterate()) {
|
||||
if ((st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && (st->facilities & station_type) != 0) this->AddItem(st->index);
|
||||
}
|
||||
EnforceDeityOrCompanyModeValid_Void();
|
||||
bool is_deity = ScriptCompanyMode::IsDeity();
|
||||
CompanyID owner = ScriptObject::GetCompany();
|
||||
ScriptList::FillList<Station>(this,
|
||||
[is_deity, owner, station_type](const Station *st) {
|
||||
return (is_deity || st->owner == owner) && (st->facilities & static_cast<StationFacility>(station_type)) != 0;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
ScriptStationList_Vehicle::ScriptStationList_Vehicle(VehicleID vehicle_id)
|
||||
{
|
||||
if (!ScriptVehicle::IsValidVehicle(vehicle_id)) return;
|
||||
if (!ScriptVehicle::IsPrimaryVehicle(vehicle_id)) return;
|
||||
|
||||
Vehicle *v = ::Vehicle::Get(vehicle_id);
|
||||
|
||||
@@ -148,13 +153,13 @@ void CargoCollector::Update(StationID from, StationID via, uint amount)
|
||||
switch (Tselector) {
|
||||
case ScriptStationList_Cargo::CS_VIA_BY_FROM:
|
||||
if (via != this->other_station) return;
|
||||
FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
case ScriptStationList_Cargo::CS_BY_FROM:
|
||||
key = from;
|
||||
break;
|
||||
case ScriptStationList_Cargo::CS_FROM_BY_VIA:
|
||||
if (from != this->other_station) return;
|
||||
FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
case ScriptStationList_Cargo::CS_BY_VIA:
|
||||
key = via;
|
||||
break;
|
||||
@@ -178,7 +183,7 @@ void ScriptStationList_CargoWaiting::Add(StationID station_id, CargoID cargo, St
|
||||
StationCargoList::ConstIterator iter = collector.GE()->cargo.Packets()->begin();
|
||||
StationCargoList::ConstIterator end = collector.GE()->cargo.Packets()->end();
|
||||
for (; iter != end; ++iter) {
|
||||
collector.Update<Tselector>((*iter)->SourceStation(), iter.GetKey(), (*iter)->Count());
|
||||
collector.Update<Tselector>((*iter)->GetFirstStation(), iter.GetKey(), (*iter)->Count());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,7 +222,7 @@ ScriptStationList_CargoWaitingViaByFrom::ScriptStationList_CargoWaitingViaByFrom
|
||||
std::pair<StationCargoList::ConstIterator, StationCargoList::ConstIterator> range =
|
||||
collector.GE()->cargo.Packets()->equal_range(via);
|
||||
for (StationCargoList::ConstIterator iter = range.first; iter != range.second; ++iter) {
|
||||
collector.Update<CS_VIA_BY_FROM>((*iter)->SourceStation(), iter.GetKey(), (*iter)->Count());
|
||||
collector.Update<CS_VIA_BY_FROM>((*iter)->GetFirstStation(), iter.GetKey(), (*iter)->Count());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user