Merge remote-tracking branch 'upstream/master'

This commit is contained in:
dP
2025-06-14 17:01:17 +05:00
1132 changed files with 59430 additions and 52889 deletions

View File

@@ -137,7 +137,7 @@ EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = ai_includes.hpp
EXCLUDE_SYMBOLS = GetClassName \
DECLARE_ENUM_AS_BIT_SET \
DECLARE_POSTFIX_INCREMENT
DECLARE_INCREMENT_DECREMENT_OPERATORS
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO

View File

@@ -137,7 +137,7 @@ EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = game_includes.hpp
EXCLUDE_SYMBOLS = GetClassName \
DECLARE_ENUM_AS_BIT_SET \
DECLARE_POSTFIX_INCREMENT
DECLARE_INCREMENT_DECREMENT_OPERATORS
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO

View File

@@ -7,7 +7,7 @@
#include "../script_controller.hpp"
template <> const char *GetClassName<ScriptController, ScriptType::AI>() { return "AIController"; }
template <> SQInteger PushClassName<ScriptController, ScriptType::AI>(HSQUIRRELVM vm) { sq_pushstring(vm, "AIController", -1); return 1; }
void SQAIController_Register(Squirrel *engine)
{

View File

@@ -19,6 +19,19 @@
*
* API additions:
* \li AIEventVehicleCrashed::GetVictims
* \li AIEventVehicleCrashed::GetVehicleOwner
* \li AIEventCompanyRenamed
* \li AIEventPresidentRenamed
* \li AICargo::CC_OVERSIZED
* \li AICargo::CC_POWDERIZED
* \li AICargo::CC_NON_POURABLE
* \li AICargo::CC_POTABLE
* \li AICargo::CC_NON_POTABLE
*
* Other changes:
* \li AIBridge::GetBridgeID renamed to AIBridge::GetBridgeType
* \li AIWaypoint::GetWaypointID now returns the StationID of any type of waypoint
* \li AIList instances can now be saved
*
* \b 14.0
*

View File

@@ -84,9 +84,6 @@ BEGIN {
api_selected = "false"
}
public = "false"
cls_param[0] = ""
cls_param[1] = 1
cls_param[2] = "x"
cls_in_api = api_selected
api_selected = ""
cls = $2
@@ -211,7 +208,7 @@ BEGIN {
}
# Maybe the end of the class, if so we can start with the Squirrel export pretty soon
/};/ {
/^[ ]*};/ {
comment_buffer = ""
cls_level--
if (cls_level != 0) {
@@ -258,7 +255,7 @@ BEGIN {
}
# Add a const (non-enum) value
/^[ ]*static const \w+ \w+ = [^;]+;/ {
/^[ ]*static const(expr)? \w+ \w+ = [^;]+;/ {
if (api_selected == "") api_selected = cls_in_api
if (api_selected == "false") {
api_selected = ""
@@ -275,8 +272,10 @@ BEGIN {
/^.*\(.*\).*$/ {
if (cls_level != 1) next
if (!match($0, ";")) {
gsub(/ :$/, ";")
skip_function_body = "true"
if (!match($0, "}$")) {
skip_function_body = "true"
}
gsub(/ :.*$/, ";")
}
if (match($0, "~")) {
if (api_selected != "") {

View File

@@ -7,7 +7,7 @@
#include "../script_controller.hpp"
template <> const char *GetClassName<ScriptController, ScriptType::GS>() { return "GSController"; }
template <> SQInteger PushClassName<ScriptController, ScriptType::GS>(HSQUIRRELVM vm) { sq_pushstring(vm, "GSController", -1); return 1; }
void SQGSController_Register(Squirrel *engine)
{

View File

@@ -19,6 +19,19 @@
*
* API additions:
* \li GSEventVehicleCrashed::GetVictims
* \li GSEventVehicleCrashed::GetVehicleOwner
* \li GSEventCompanyRenamed
* \li GSEventPresidentRenamed
* \li GSCargo::CC_OVERSIZED
* \li GSCargo::CC_POWDERIZED
* \li GSCargo::CC_NON_POURABLE
* \li GSCargo::CC_POTABLE
* \li GSCargo::CC_NON_POTABLE
*
* Other changes:
* \li GSBridge::GetBridgeID renamed to GSBridge::GetBridgeType
* \li GSWaypoint::GetWaypointID now returns the StationID of any type of waypoint
* \li GSList instances can now be saved
*
* \b 14.0
*
@@ -287,7 +300,7 @@
* \li GSEngine::IsValidEngine and GSEngine::IsBuildable when outside GSCompanyMode scope
* \li GSEventExclusiveTransportRights
* \li GSEventRoadReconstruction
* \li GSNews::NT_ACCIDENT, GSNews::NT_COMPANY_INFO, GSNews::NT_ADVICE, GSNews::NT_ACCEPTANCE
* \li GSNews::NewsType::Accident, GSNews::NewsType::CompanyInfo, GSNews::NewsType::Advice, GSNews::NewsType::Acceptance
* \li GSIndustryType::IsProcessingIndustry
* \li GSStation::IsAirportClosed
* \li GSStation::OpenCloseAirport

View File

@@ -91,7 +91,7 @@ bool ScriptAdminMakeJSON(nlohmann::json &json, HSQUIRRELVM vm, SQInteger index,
return false;
}
json[key] = value;
json[std::move(key)] = std::move(value);
}
sq_pop(vm, 1);
return true;

View File

@@ -77,7 +77,7 @@
EnforcePrecondition(false, IsValidAirportType(type));
EnforcePrecondition(false, station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id));
return ScriptObject::Command<CMD_BUILD_AIRPORT>::Do(tile, type, 0, (ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION), station_id != ScriptStation::STATION_JOIN_ADJACENT);
return ScriptObject::Command<CMD_BUILD_AIRPORT>::Do(tile, type, 0, (ScriptStation::IsValidStation(station_id) ? station_id : StationID::Invalid()), station_id != ScriptStation::STATION_JOIN_ADJACENT);
}
/* static */ bool ScriptAirport::RemoveAirport(TileIndex tile)
@@ -97,7 +97,7 @@
const Station *st = ::Station::GetByTile(tile);
if (st->owner != ScriptObject::GetCompany() && ScriptCompanyMode::IsValid()) return -1;
if ((st->facilities & FACIL_AIRPORT) == 0) return -1;
if (!st->facilities.Test(StationFacility::Airport)) return -1;
return st->airport.GetNumHangars();
}
@@ -111,7 +111,7 @@
const Station *st = ::Station::GetByTile(tile);
if (st->owner != ScriptObject::GetCompany() && ScriptCompanyMode::IsValid()) return INVALID_TILE;
if ((st->facilities & FACIL_AIRPORT) == 0) return INVALID_TILE;
if (!st->facilities.Test(StationFacility::Airport)) return INVALID_TILE;
return st->airport.GetHangarTile(0);
}
@@ -148,11 +148,11 @@
/* static */ TownID ScriptAirport::GetNearestTown(TileIndex tile, AirportType type)
{
if (!::IsValidTile(tile)) return INVALID_TOWN;
if (!IsAirportInformationAvailable(type)) return INVALID_TOWN;
if (!::IsValidTile(tile)) return TownID::Invalid();
if (!IsAirportInformationAvailable(type)) return TownID::Invalid();
const AirportSpec *as = AirportSpec::Get(type);
if (!as->IsWithinMapBounds(0, tile)) return INVALID_TOWN;
if (!as->IsWithinMapBounds(0, tile)) return TownID::Invalid();
uint dist;
const auto &layout = as->layouts[0];

View File

@@ -12,6 +12,7 @@
#include "script_object.hpp"
#include "../../airport.h"
#include "../../station_type.h"
/**
* Class that handles all airport related functions.

View File

@@ -16,6 +16,7 @@
#include "../../station_cmd.h"
#include "../../waypoint_cmd.h"
#include "../../timer/timer_game_calendar.h"
#include "table/strings.h"
#include "../../safeguards.h"
@@ -31,8 +32,7 @@
{
if (!IsValidBaseStation(station_id)) return std::nullopt;
::SetDParam(0, station_id);
return GetString(::Station::IsValidID(station_id) ? STR_STATION_NAME : STR_WAYPOINT_NAME);
return ::StrMakeValid(::GetString(::Station::IsValidID(station_id) ? STR_STATION_NAME : STR_WAYPOINT_NAME, station_id));
}
/* static */ bool ScriptBaseStation::SetName(StationID station_id, Text *name)

View File

@@ -12,6 +12,7 @@
#include "script_text.hpp"
#include "script_date.hpp"
#include "../../station_type.h"
/**
* Base class for stations and waypoints.
@@ -19,15 +20,9 @@
*/
class ScriptBaseStation : public ScriptObject {
public:
/**
* Special station IDs for building adjacent/new stations when
* the adjacent/distant join features are enabled.
*/
enum SpecialStationIDs {
STATION_NEW = 0xFFFD, ///< Build a new station
STATION_JOIN_ADJACENT = 0xFFFE, ///< Join an neighbouring station if one exists
STATION_INVALID = 0xFFFF, ///< Invalid station id.
};
static constexpr StationID STATION_NEW = ::NEW_STATION; ///< Build a new station
static constexpr StationID STATION_JOIN_ADJACENT = ::ADJACENT_STATION; ///< Join an neighbouring station if one exists
static constexpr StationID STATION_INVALID = ::StationID::Invalid(); ///< Invalid station id.
/**
* Checks whether the given basestation is valid and owned by you.

View File

@@ -17,13 +17,14 @@
#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)
/* static */ bool ScriptBridge::IsValidBridge(BridgeType bridge_type)
{
return bridge_id < MAX_BRIDGES && ::GetBridgeSpec(bridge_id)->avail_year <= TimerGameCalendar::year;
return bridge_type < MAX_BRIDGES && ::GetBridgeSpec(bridge_type)->avail_year <= TimerGameCalendar::year;
}
/* static */ bool ScriptBridge::IsBridgeTile(TileIndex tile)
@@ -32,10 +33,10 @@
return ::IsBridgeTile(tile);
}
/* static */ BridgeID ScriptBridge::GetBridgeID(TileIndex tile)
/* static */ BridgeType ScriptBridge::GetBridgeType(TileIndex tile)
{
if (!IsBridgeTile(tile)) return (BridgeID)-1;
return (BridgeID)::GetBridgeType(tile);
if (!IsBridgeTile(tile)) return (BridgeType)-1;
return (BridgeType)::GetBridgeType(tile);
}
/**
@@ -70,7 +71,7 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
NOT_REACHED();
}
/* static */ bool ScriptBridge::BuildBridge(ScriptVehicle::VehicleType vehicle_type, BridgeID bridge_id, TileIndex start, TileIndex end)
/* static */ bool ScriptBridge::BuildBridge(ScriptVehicle::VehicleType vehicle_type, BridgeType bridge_type, TileIndex start, TileIndex end)
{
EnforceDeityOrCompanyModeValid(false);
EnforcePrecondition(false, start != end);
@@ -85,11 +86,11 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
case ScriptVehicle::VT_ROAD:
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());
return ScriptObject::Command<CMD_BUILD_BRIDGE>::Do(&::_DoCommandReturnBuildBridge1, end, start, TRANSPORT_ROAD, bridge_type, ScriptRoad::GetCurrentRoadType());
case ScriptVehicle::VT_RAIL:
return ScriptObject::Command<CMD_BUILD_BRIDGE>::Do(end, start, TRANSPORT_RAIL, bridge_id, ScriptRail::GetCurrentRailType());
return ScriptObject::Command<CMD_BUILD_BRIDGE>::Do(end, start, TRANSPORT_RAIL, bridge_type, ScriptRail::GetCurrentRailType());
case ScriptVehicle::VT_WATER:
return ScriptObject::Command<CMD_BUILD_BRIDGE>::Do(end, start, TRANSPORT_WATER, bridge_id, 0);
return ScriptObject::Command<CMD_BUILD_BRIDGE>::Do(end, start, TRANSPORT_WATER, bridge_type, 0);
default: NOT_REACHED();
}
}
@@ -99,13 +100,13 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
EnforceDeityOrCompanyModeValid(false);
/* Build the piece of road on the 'start' side of the bridge */
TileIndex end = ScriptObject::GetCallbackVariable(0);
TileIndex start = ScriptObject::GetCallbackVariable(1);
TileIndex end(ScriptObject::GetCallbackVariable(0));
TileIndex start(ScriptObject::GetCallbackVariable(1));
DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
return ScriptObject::Command<CMD_BUILD_ROAD>::Do(&::_DoCommandReturnBuildBridge2, start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2), (::RoadType)ScriptRoad::GetCurrentRoadType(), DRD_NONE, 0);
return ScriptObject::Command<CMD_BUILD_ROAD>::Do(&::_DoCommandReturnBuildBridge2, start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2), (::RoadType)ScriptRoad::GetCurrentRoadType(), DRD_NONE, TownID::Invalid());
}
/* static */ bool ScriptBridge::_BuildBridgeRoad2()
@@ -113,13 +114,13 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
EnforceDeityOrCompanyModeValid(false);
/* Build the piece of road on the 'end' side of the bridge */
TileIndex end = ScriptObject::GetCallbackVariable(0);
TileIndex start = ScriptObject::GetCallbackVariable(1);
TileIndex end(ScriptObject::GetCallbackVariable(0));
TileIndex start(ScriptObject::GetCallbackVariable(1));
DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
return ScriptObject::Command<CMD_BUILD_ROAD>::Do(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1), (::RoadType)ScriptRoad::GetCurrentRoadType(), DRD_NONE, 0);
return ScriptObject::Command<CMD_BUILD_ROAD>::Do(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1), (::RoadType)ScriptRoad::GetCurrentRoadType(), DRD_NONE, TownID::Invalid());
}
/* static */ bool ScriptBridge::RemoveBridge(TileIndex tile)
@@ -129,42 +130,42 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
return ScriptObject::Command<CMD_LANDSCAPE_CLEAR>::Do(tile);
}
/* static */ std::optional<std::string> ScriptBridge::GetName(BridgeID bridge_id, ScriptVehicle::VehicleType vehicle_type)
/* static */ std::optional<std::string> ScriptBridge::GetName(BridgeType bridge_type, ScriptVehicle::VehicleType vehicle_type)
{
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;
if (!IsValidBridge(bridge_type)) return std::nullopt;
return GetString(vehicle_type == ScriptVehicle::VT_WATER ? STR_LAI_BRIDGE_DESCRIPTION_AQUEDUCT : ::GetBridgeSpec(bridge_id)->transport_name[vehicle_type]);
return ::StrMakeValid(::GetString(vehicle_type == ScriptVehicle::VT_WATER ? STR_LAI_BRIDGE_DESCRIPTION_AQUEDUCT : ::GetBridgeSpec(bridge_type)->transport_name[vehicle_type]));
}
/* static */ SQInteger ScriptBridge::GetMaxSpeed(BridgeID bridge_id)
/* static */ SQInteger ScriptBridge::GetMaxSpeed(BridgeType bridge_type)
{
if (!IsValidBridge(bridge_id)) return -1;
if (!IsValidBridge(bridge_type)) return -1;
return ::GetBridgeSpec(bridge_id)->speed; // km-ish/h
return ::GetBridgeSpec(bridge_type)->speed; // km-ish/h
}
/* static */ Money ScriptBridge::GetPrice(BridgeID bridge_id, SQInteger length)
/* static */ Money ScriptBridge::GetPrice(BridgeType bridge_type, SQInteger length)
{
if (!IsValidBridge(bridge_id)) return -1;
if (!IsValidBridge(bridge_type)) return -1;
length = Clamp<SQInteger>(length, 0, INT32_MAX);
return ::CalcBridgeLenCostFactor(length) * _price[PR_BUILD_BRIDGE] * ::GetBridgeSpec(bridge_id)->price >> 8;
return ::CalcBridgeLenCostFactor(length) * _price[PR_BUILD_BRIDGE] * ::GetBridgeSpec(bridge_type)->price >> 8;
}
/* static */ SQInteger ScriptBridge::GetMaxLength(BridgeID bridge_id)
/* static */ SQInteger ScriptBridge::GetMaxLength(BridgeType bridge_type)
{
if (!IsValidBridge(bridge_id)) return -1;
if (!IsValidBridge(bridge_type)) return -1;
return std::min<SQInteger>(::GetBridgeSpec(bridge_id)->max_length, _settings_game.construction.max_bridge_length) + 2;
return std::min<SQInteger>(::GetBridgeSpec(bridge_type)->max_length, _settings_game.construction.max_bridge_length) + 2;
}
/* static */ SQInteger ScriptBridge::GetMinLength(BridgeID bridge_id)
/* static */ SQInteger ScriptBridge::GetMinLength(BridgeType bridge_type)
{
if (!IsValidBridge(bridge_id)) return -1;
if (!IsValidBridge(bridge_type)) return -1;
return static_cast<SQInteger>(::GetBridgeSpec(bridge_id)->min_length) + 2;
return static_cast<SQInteger>(::GetBridgeSpec(bridge_type)->min_length) + 2;
}
/* static */ TileIndex ScriptBridge::GetOtherBridgeEnd(TileIndex tile)

View File

@@ -11,6 +11,7 @@
#define SCRIPT_BRIDGE_HPP
#include "script_vehicle.hpp"
#include "../../bridge.h"
/**
* Class that handles all bridge related functions.
@@ -42,10 +43,10 @@ public:
/**
* Checks whether the given bridge type is valid.
* @param bridge_id The bridge to check.
* @param bridge_type The bridge to check.
* @return True if and only if the bridge type is valid.
*/
static bool IsValidBridge(BridgeID bridge_id);
static bool IsValidBridge(BridgeType bridge_type);
/**
* Checks whether the given tile is actually a bridge start or end tile.
@@ -56,59 +57,59 @@ public:
static bool IsBridgeTile(TileIndex tile);
/**
* Get the BridgeID of a bridge at a given tile.
* @param tile The tile to get the BridgeID from.
* Get the BridgeType of a bridge at a given tile.
* @param tile The tile to get the BridgeType from.
* @pre IsBridgeTile(tile).
* @return The BridgeID from the bridge at tile 'tile'.
* @return The BridgeType from the bridge at tile 'tile'.
*/
static BridgeID GetBridgeID(TileIndex tile);
static BridgeType GetBridgeType(TileIndex tile);
/**
* Get the name of a bridge.
* @param bridge_id The bridge to get the name of.
* @param bridge_type The bridge to get the name of.
* @param vehicle_type The vehicle-type of bridge to get the name of.
* @pre IsValidBridge(bridge_id).
* @pre IsValidBridge(bridge_type).
* @pre vehicle_type == ScriptVehicle::VT_ROAD || vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_WATER
* @return The name the bridge has.
*/
static std::optional<std::string> GetName(BridgeID bridge_id, ScriptVehicle::VehicleType vehicle_type);
static std::optional<std::string> GetName(BridgeType bridge_type, ScriptVehicle::VehicleType vehicle_type);
/**
* Get the maximum speed of a bridge.
* @param bridge_id The bridge to get the maximum speed of.
* @pre IsValidBridge(bridge_id).
* @param bridge_type The bridge to get the maximum speed of.
* @pre IsValidBridge(bridge_type).
* @return The maximum speed the bridge has.
* @note The speed is in OpenTTD's internal speed unit.
* This is mph / 1.6, which is roughly km/h.
* To get km/h multiply this number by 1.00584.
*/
static SQInteger GetMaxSpeed(BridgeID bridge_id);
static SQInteger GetMaxSpeed(BridgeType bridge_type);
/**
* 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 bridge_type 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).
* @pre IsValidBridge(bridge_type).
* @return The new cost the bridge has.
*/
static Money GetPrice(BridgeID bridge_id, SQInteger length);
static Money GetPrice(BridgeType bridge_type, SQInteger length);
/**
* Get the maximum length of a bridge.
* @param bridge_id The bridge to get the maximum length of.
* @pre IsValidBridge(bridge_id).
* @param bridge_type The bridge to get the maximum length of.
* @pre IsValidBridge(bridge_type).
* @returns The maximum length the bridge has.
*/
static SQInteger GetMaxLength(BridgeID bridge_id);
static SQInteger GetMaxLength(BridgeType bridge_type);
/**
* Get the minimum length of a bridge.
* @param bridge_id The bridge to get the minimum length of.
* @pre IsValidBridge(bridge_id).
* @param bridge_type The bridge to get the minimum length of.
* @pre IsValidBridge(bridge_type).
* @returns The minimum length the bridge has.
*/
static SQInteger GetMinLength(BridgeID bridge_id);
static SQInteger GetMinLength(BridgeType bridge_type);
/**
* Internal function to help BuildBridge in case of road.
@@ -128,7 +129,7 @@ public:
* each end of the bridge, making it easier for you to connect it to your
* network.
* @param vehicle_type The vehicle-type of bridge to build.
* @param bridge_id The bridge-type to build.
* @param bridge_type The bridge-type to build.
* @param start Where to start the bridge.
* @param end Where to end the bridge.
* @pre ScriptMap::IsValidTile(start).
@@ -152,7 +153,7 @@ public:
* @note No matter if the road pieces were build or not, if building the
* bridge succeeded, this function returns true.
*/
static bool BuildBridge(ScriptVehicle::VehicleType vehicle_type, BridgeID bridge_id, TileIndex start, TileIndex end);
static bool BuildBridge(ScriptVehicle::VehicleType vehicle_type, BridgeType bridge_type, TileIndex start, TileIndex end);
/**
* Removes a bridge, by executing it on either the start or end tile.

View File

@@ -10,15 +10,15 @@
#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"
#include "table/strings.h"
#include "../../safeguards.h"
/* static */ bool ScriptCargo::IsValidCargo(CargoID cargo_type)
/* static */ bool ScriptCargo::IsValidCargo(CargoType cargo_type)
{
return (cargo_type < NUM_CARGO && ::CargoSpec::Get(cargo_type)->IsValid());
}
@@ -28,15 +28,14 @@
return (towneffect_type >= (TownEffect)TAE_BEGIN && towneffect_type < (TownEffect)TAE_END);
}
/* static */ std::optional<std::string> ScriptCargo::GetName(CargoID cargo_type)
/* static */ std::optional<std::string> ScriptCargo::GetName(CargoType cargo_type)
{
if (!IsValidCargo(cargo_type)) return std::nullopt;
::SetDParam(0, 1ULL << cargo_type);
return GetString(STR_JUST_CARGO_LIST);
return ::StrMakeValid(::GetString(STR_JUST_CARGO_LIST, 1ULL << cargo_type));
}
/* static */ std::optional<std::string> ScriptCargo::GetCargoLabel(CargoID cargo_type)
/* static */ std::optional<std::string> ScriptCargo::GetCargoLabel(CargoType cargo_type)
{
if (!IsValidCargo(cargo_type)) return std::nullopt;
const CargoSpec *cargo = ::CargoSpec::Get(cargo_type);
@@ -50,27 +49,27 @@
return cargo_label;
}
/* static */ bool ScriptCargo::IsFreight(CargoID cargo_type)
/* static */ bool ScriptCargo::IsFreight(CargoType cargo_type)
{
if (!IsValidCargo(cargo_type)) return false;
const CargoSpec *cargo = ::CargoSpec::Get(cargo_type);
return cargo->is_freight;
}
/* static */ bool ScriptCargo::HasCargoClass(CargoID cargo_type, CargoClass cargo_class)
/* static */ bool ScriptCargo::HasCargoClass(CargoType cargo_type, CargoClass cargo_class)
{
if (!IsValidCargo(cargo_type)) return false;
return ::IsCargoInClass(cargo_type, (::CargoClass)cargo_class);
return ::IsCargoInClass(cargo_type, ::CargoClasses(to_underlying(cargo_class)));
}
/* static */ ScriptCargo::TownEffect ScriptCargo::GetTownEffect(CargoID cargo_type)
/* static */ ScriptCargo::TownEffect ScriptCargo::GetTownEffect(CargoType cargo_type)
{
if (!IsValidCargo(cargo_type)) return TE_NONE;
return (ScriptCargo::TownEffect)::CargoSpec::Get(cargo_type)->town_acceptance_effect;
}
/* static */ Money ScriptCargo::GetCargoIncome(CargoID cargo_type, SQInteger distance, SQInteger days_in_transit)
/* static */ Money ScriptCargo::GetCargoIncome(CargoType cargo_type, SQInteger distance, SQInteger days_in_transit)
{
if (!IsValidCargo(cargo_type)) return -1;
@@ -79,13 +78,13 @@
return ::GetTransportedGoodsIncome(1, distance, Clamp(days_in_transit * 2 / 5, 0, UINT16_MAX), cargo_type);
}
/* static */ ScriptCargo::DistributionType ScriptCargo::GetDistributionType(CargoID cargo_type)
/* static */ ScriptCargo::DistributionType ScriptCargo::GetDistributionType(CargoType cargo_type)
{
if (!ScriptCargo::IsValidCargo(cargo_type)) return INVALID_DISTRIBUTION_TYPE;
return (ScriptCargo::DistributionType)_settings_game.linkgraph.GetDistributionType(cargo_type);
}
/* static */ SQInteger ScriptCargo::GetWeight(CargoID cargo_type, SQInteger amount)
/* static */ SQInteger ScriptCargo::GetWeight(CargoType cargo_type, SQInteger amount)
{
if (!IsValidCargo(cargo_type)) return -1;

View File

@@ -25,16 +25,21 @@ public:
*/
enum CargoClass {
/* Note: these values represent part of the in-game CargoClass enum */
CC_PASSENGERS = ::CC_PASSENGERS, ///< Passengers. Cargoes of this class appear at bus stops. Cargoes not of this class appear at truck stops.
CC_MAIL = ::CC_MAIL, ///< Mail
CC_EXPRESS = ::CC_EXPRESS, ///< Express cargo (Goods, Food, Candy, but also possible for passengers)
CC_ARMOURED = ::CC_ARMOURED, ///< Armoured cargo (Valuables, Gold, Diamonds)
CC_BULK = ::CC_BULK, ///< Bulk cargo (Coal, Grain etc., Ores, Fruit)
CC_PIECE_GOODS = ::CC_PIECE_GOODS, ///< Piece goods (Livestock, Wood, Steel, Paper)
CC_LIQUID = ::CC_LIQUID, ///< Liquids (Oil, Water, Rubber)
CC_REFRIGERATED = ::CC_REFRIGERATED, ///< Refrigerated cargo (Food, Fruit)
CC_HAZARDOUS = ::CC_HAZARDOUS, ///< Hazardous cargo (Nuclear Fuel, Explosives, etc.)
CC_COVERED = ::CC_COVERED, ///< Covered/Sheltered Freight (Transportation in Box Vans, Silo Wagons, etc.)
CC_PASSENGERS = ::CargoClasses{::CargoClass::Passengers}.base(), ///< Passengers. Cargoes of this class appear at bus stops. Cargoes not of this class appear at truck stops.
CC_MAIL = ::CargoClasses{::CargoClass::Mail}.base(), ///< Mail
CC_EXPRESS = ::CargoClasses{::CargoClass::Express}.base(), ///< Express cargo (Goods, Food, Candy, but also possible for passengers)
CC_ARMOURED = ::CargoClasses{::CargoClass::Armoured}.base(), ///< Armoured cargo (Valuables, Gold, Diamonds)
CC_BULK = ::CargoClasses{::CargoClass::Bulk}.base(), ///< Bulk cargo (Coal, Grain etc., Ores, Fruit)
CC_PIECE_GOODS = ::CargoClasses{::CargoClass::PieceGoods}.base(), ///< Piece goods (Livestock, Wood, Steel, Paper)
CC_LIQUID = ::CargoClasses{::CargoClass::Liquid}.base(), ///< Liquids (Oil, Water, Rubber)
CC_REFRIGERATED = ::CargoClasses{::CargoClass::Refrigerated}.base(), ///< Refrigerated cargo (Food, Fruit)
CC_HAZARDOUS = ::CargoClasses{::CargoClass::Hazardous}.base(), ///< Hazardous cargo (Nuclear Fuel, Explosives, etc.)
CC_COVERED = ::CargoClasses{::CargoClass::Covered}.base(), ///< Covered/Sheltered Freight (Transportation in Box Vans, Silo Wagons, etc.)
CC_OVERSIZED = ::CargoClasses{::CargoClass::Oversized}.base(), ///< Oversized (stake/flatbed wagon)
CC_POWDERIZED = ::CargoClasses{::CargoClass::Powderized}.base(), ///< Powderized, moist protected (powder/silo wagon)
CC_NON_POURABLE = ::CargoClasses{::CargoClass::NotPourable}.base(), ///< Non-pourable (open wagon, but not hopper wagon)
CC_POTABLE = ::CargoClasses{::CargoClass::Potable}.base(), ///< Potable / food / clean.
CC_NON_POTABLE = ::CargoClasses{::CargoClass::NonPotable}.base(), ///< Non-potable / non-food / dirty.
};
/**
@@ -53,7 +58,7 @@ public:
/**
* Special cargo types.
*/
enum SpecialCargoID {
enum SpecialCargoType {
/* Note: these values represent part of the in-game CargoTypes enum */
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.
@@ -75,7 +80,7 @@ public:
* @param cargo_type The cargo to check.
* @return True if and only if the cargo type is valid.
*/
static bool IsValidCargo(CargoID cargo_type);
static bool IsValidCargo(CargoType cargo_type);
/**
* Checks whether the given town effect type is valid.
@@ -90,7 +95,7 @@ public:
* @pre IsValidCargo(cargo_type).
* @return The name of the cargo type.
*/
static std::optional<std::string> GetName(CargoID cargo_type);
static std::optional<std::string> GetName(CargoType cargo_type);
/**
* Gets the string representation of the cargo label.
@@ -107,7 +112,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 std::optional<std::string> GetCargoLabel(CargoID cargo_type);
static std::optional<std::string> GetCargoLabel(CargoType cargo_type);
/**
* Checks whether the give cargo is a freight or not.
@@ -117,7 +122,7 @@ public:
* @pre ScriptCargo::IsValidCargo(cargo_type).
* @return True if and only if the cargo is freight.
*/
static bool IsFreight(CargoID cargo_type);
static bool IsFreight(CargoType cargo_type);
/**
* Check if this cargo is in the requested cargo class.
@@ -126,7 +131,7 @@ public:
* @param cargo_class The class to check for.
* @return True if and only if the cargo is in the cargo class.
*/
static bool HasCargoClass(CargoID cargo_type, CargoClass cargo_class);
static bool HasCargoClass(CargoType cargo_type, CargoClass cargo_class);
/**
* Get the effect this cargo has on a town.
@@ -134,7 +139,7 @@ public:
* @pre ScriptCargo::IsValidCargo(cargo_type).
* @return The effect this cargo has on a town, or TE_NONE if it has no effect.
*/
static TownEffect GetTownEffect(CargoID cargo_type);
static TownEffect GetTownEffect(CargoType cargo_type);
/**
* Get the income for transporting a piece of cargo over the
@@ -147,14 +152,14 @@ public:
* 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, SQInteger distance, SQInteger days_in_transit);
static Money GetCargoIncome(CargoType cargo_type, SQInteger distance, SQInteger days_in_transit);
/**
* Get the cargo distribution type for a cargo.
* @param cargo_type The cargo to check on.
* @return The cargo distribution type for the given cargo.
*/
static DistributionType GetDistributionType(CargoID cargo_type);
static DistributionType GetDistributionType(CargoType cargo_type);
/**
* Get the weight in tonnes for the given amount of
@@ -165,7 +170,7 @@ public:
* @pre ScriptCargo::IsValidCargo(cargo_type).
* @return The weight in tonnes for that quantity of cargo.
*/
static SQInteger GetWeight(CargoID cargo_type, SQInteger amount);
static SQInteger GetWeight(CargoType cargo_type, SQInteger amount);
};
#endif /* SCRIPT_CARGO_HPP */

View File

@@ -30,7 +30,7 @@ ScriptCargoList_IndustryAccepting::ScriptCargoList_IndustryAccepting(IndustryID
const Industry *ind = ::Industry::Get(industry_id);
for (const auto &a : ind->accepted) {
if (::IsValidCargoID(a.cargo)) {
if (::IsValidCargoType(a.cargo)) {
this->AddItem(a.cargo);
}
}
@@ -42,7 +42,7 @@ ScriptCargoList_IndustryProducing::ScriptCargoList_IndustryProducing(IndustryID
const Industry *ind = ::Industry::Get(industry_id);
for (const auto &p : ind->produced) {
if (::IsValidCargoID(p.cargo)) {
if (::IsValidCargoType(p.cargo)) {
this->AddItem(p.cargo);
}
}
@@ -53,7 +53,7 @@ ScriptCargoList_StationAccepting::ScriptCargoList_StationAccepting(StationID sta
if (!ScriptStation::IsValidStation(station_id)) return;
const Station *st = ::Station::Get(station_id);
for (CargoID i = 0; i < NUM_CARGO; i++) {
if (HasBit(st->goods[i].status, GoodsEntry::GES_ACCEPTANCE)) this->AddItem(i);
for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) {
if (st->goods[cargo].status.Test(GoodsEntry::State::Acceptance)) this->AddItem(cargo);
}
}

View File

@@ -11,6 +11,8 @@
#define SCRIPT_CARGOLIST_HPP
#include "script_list.hpp"
#include "../../industry_type.h"
#include "../../station_type.h"
/**
* Creates a list of cargoes that can be produced in the current game.

View File

@@ -15,9 +15,9 @@
#include "../../safeguards.h"
/* static */ SQInteger ScriptCargoMonitor::GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring)
/* static */ SQInteger ScriptCargoMonitor::GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoType cargo, TownID town_id, bool keep_monitoring)
{
CompanyID cid = static_cast<CompanyID>(company);
::CompanyID cid = ScriptCompany::FromScriptCompanyID(ScriptCompany::ResolveCompanyID((company)));
if (cid >= MAX_COMPANIES) return -1;
if (!ScriptCargo::IsValidCargo(cargo)) return -1;
if (!::Town::IsValidID(town_id)) return -1;
@@ -26,9 +26,9 @@
return GetDeliveryAmount(monitor, keep_monitoring);
}
/* static */ SQInteger ScriptCargoMonitor::GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring)
/* static */ SQInteger ScriptCargoMonitor::GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoType cargo, IndustryID industry_id, bool keep_monitoring)
{
CompanyID cid = static_cast<CompanyID>(company);
::CompanyID cid = ScriptCompany::FromScriptCompanyID(ScriptCompany::ResolveCompanyID((company)));
if (cid >= MAX_COMPANIES) return -1;
if (!ScriptCargo::IsValidCargo(cargo)) return -1;
if (!::Industry::IsValidID(industry_id)) return -1;
@@ -37,9 +37,9 @@
return GetDeliveryAmount(monitor, keep_monitoring);
}
/* static */ SQInteger ScriptCargoMonitor::GetTownPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring)
/* static */ SQInteger ScriptCargoMonitor::GetTownPickupAmount(ScriptCompany::CompanyID company, CargoType cargo, TownID town_id, bool keep_monitoring)
{
CompanyID cid = static_cast<CompanyID>(company);
::CompanyID cid = ScriptCompany::FromScriptCompanyID(ScriptCompany::ResolveCompanyID((company)));
if (cid >= MAX_COMPANIES) return -1;
if (!ScriptCargo::IsValidCargo(cargo)) return -1;
if (!::Town::IsValidID(town_id)) return -1;
@@ -48,9 +48,9 @@
return GetPickupAmount(monitor, keep_monitoring);
}
/* static */ SQInteger ScriptCargoMonitor::GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring)
/* static */ SQInteger ScriptCargoMonitor::GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoType cargo, IndustryID industry_id, bool keep_monitoring)
{
CompanyID cid = static_cast<CompanyID>(company);
::CompanyID cid = ScriptCompany::FromScriptCompanyID(ScriptCompany::ResolveCompanyID((company)));
if (cid >= MAX_COMPANIES) return -1;
if (!ScriptCargo::IsValidCargo(cargo)) return -1;
if (!::Industry::IsValidID(industry_id)) return -1;

View File

@@ -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 SQInteger GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring);
static SQInteger GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoType 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 SQInteger GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring);
static SQInteger GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoType 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 SQInteger GetTownPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring);
static SQInteger GetTownPickupAmount(ScriptCompany::CompanyID company, CargoType 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 SQInteger GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring);
static SQInteger GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoType cargo, IndustryID industry_id, bool keep_monitoring);
/** Stop monitoring everything. */
static void StopAllMonitoring();

View File

@@ -43,7 +43,7 @@ static NetworkClientInfo *FindClientInfo(ScriptClient::ClientID client)
{
NetworkClientInfo *ci = FindClientInfo(client);
if (ci == nullptr) return ScriptCompany::COMPANY_INVALID;
return (ScriptCompany::CompanyID)ci->client_playas;
return ScriptCompany::ToScriptCompanyID(ci->client_playas);
}
/* static */ ScriptDate::Date ScriptClient::GetJoinDate(ScriptClient::ClientID client)

View File

@@ -26,13 +26,13 @@ ScriptClientList::ScriptClientList()
ScriptClientList_Company::ScriptClientList_Company(ScriptCompany::CompanyID company)
{
if (!_networking) return;
CompanyID c;
::CompanyID c;
if (company == ScriptCompany::COMPANY_SPECTATOR) {
c = ::COMPANY_SPECTATOR;
} else {
company = ScriptCompany::ResolveCompanyID(company);
if (company == ScriptCompany::COMPANY_INVALID) return;
c = (CompanyID)company;
c = ScriptCompany::FromScriptCompanyID(company);
}
for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {

View File

@@ -24,24 +24,40 @@
#include "../../misc_cmd.h"
#include "../../object_cmd.h"
#include "../../settings_cmd.h"
#include "table/strings.h"
#include "../../safeguards.h"
/* static */ ::CompanyID ScriptCompany::FromScriptCompanyID(ScriptCompany::CompanyID company)
{
/* If this assert gets triggered, then ScriptCompany::ResolveCompanyID needed to be called before. */
assert(company != ScriptCompany::COMPANY_SELF && company != ScriptCompany::COMPANY_SPECTATOR);
if (company == ScriptCompany::COMPANY_INVALID) return ::CompanyID::Invalid();
return static_cast<::CompanyID>(company);
}
/* static */ ScriptCompany::CompanyID ScriptCompany::ToScriptCompanyID(::CompanyID company)
{
if (company == ::CompanyID::Invalid()) return ScriptCompany::COMPANY_INVALID;
return static_cast<::ScriptCompany::CompanyID>(company.base());
}
/* static */ ScriptCompany::CompanyID ScriptCompany::ResolveCompanyID(ScriptCompany::CompanyID company)
{
if (company == COMPANY_SELF) {
if (!::Company::IsValidID(_current_company)) return COMPANY_INVALID;
return (CompanyID)((uint8_t)_current_company);
if (company == ScriptCompany::COMPANY_SELF) {
if (!::Company::IsValidID(_current_company)) return ScriptCompany::COMPANY_INVALID;
return ScriptCompany::ToScriptCompanyID(_current_company);
}
return ::Company::IsValidID(company) ? company : COMPANY_INVALID;
return ::Company::IsValidID(ScriptCompany::FromScriptCompanyID(company)) ? company : ScriptCompany::COMPANY_INVALID;
}
/* static */ bool ScriptCompany::IsMine(ScriptCompany::CompanyID company)
{
EnforceCompanyModeValid(false);
return ResolveCompanyID(company) == ResolveCompanyID(COMPANY_SELF);
return ResolveCompanyID(company) == ResolveCompanyID(ScriptCompany::COMPANY_SELF);
}
/* static */ bool ScriptCompany::SetName(Text *name)
@@ -60,10 +76,9 @@
/* static */ std::optional<std::string> ScriptCompany::GetName(ScriptCompany::CompanyID company)
{
company = ResolveCompanyID(company);
if (company == COMPANY_INVALID) return std::nullopt;
if (company == ScriptCompany::COMPANY_INVALID) return std::nullopt;
::SetDParam(0, company);
return GetString(STR_COMPANY_NAME);
return ::StrMakeValid(::GetString(STR_COMPANY_NAME, ScriptCompany::FromScriptCompanyID(company)));
}
/* static */ bool ScriptCompany::SetPresidentName(Text *name)
@@ -82,10 +97,9 @@
/* static */ std::optional<std::string> ScriptCompany::GetPresidentName(ScriptCompany::CompanyID company)
{
company = ResolveCompanyID(company);
if (company == COMPANY_INVALID) return std::nullopt;
if (company == ScriptCompany::COMPANY_INVALID) return std::nullopt;
::SetDParam(0, company);
return GetString(STR_PRESIDENT_NAME);
return ::StrMakeValid(::GetString(STR_PRESIDENT_NAME, ScriptCompany::FromScriptCompanyID(company)));
}
/* static */ bool ScriptCompany::SetPresidentGender(Gender gender)
@@ -102,124 +116,124 @@
return ScriptObject::Command<CMD_SET_COMPANY_MANAGER_FACE>::Do(cmf);
}
/* static */ ScriptCompany::Gender ScriptCompany::GetPresidentGender(CompanyID company)
/* static */ ScriptCompany::Gender ScriptCompany::GetPresidentGender(ScriptCompany::CompanyID company)
{
company = ResolveCompanyID(company);
if (company == COMPANY_INVALID) return GENDER_INVALID;
if (company == ScriptCompany::COMPANY_INVALID) return GENDER_INVALID;
GenderEthnicity ge = (GenderEthnicity)GetCompanyManagerFaceBits(Company::Get(company)->face, CMFV_GEN_ETHN, GE_WM);
GenderEthnicity ge = (GenderEthnicity)GetCompanyManagerFaceBits(Company::Get(ScriptCompany::FromScriptCompanyID(company))->face, CMFV_GEN_ETHN, GE_WM);
return HasBit(ge, ::GENDER_FEMALE) ? GENDER_FEMALE : GENDER_MALE;
}
/* static */ Money ScriptCompany::GetQuarterlyIncome(ScriptCompany::CompanyID company, SQInteger quarter)
{
company = ResolveCompanyID(company);
if (company == COMPANY_INVALID) return -1;
if (company == ScriptCompany::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;
return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->cur_economy.income;
}
return ::Company::Get(company)->old_economy[quarter - 1].income;
return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->old_economy[quarter - 1].income;
}
/* static */ Money ScriptCompany::GetQuarterlyExpenses(ScriptCompany::CompanyID company, SQInteger quarter)
{
company = ResolveCompanyID(company);
if (company == COMPANY_INVALID) return -1;
if (company == ScriptCompany::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;
return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->cur_economy.expenses;
}
return ::Company::Get(company)->old_economy[quarter - 1].expenses;
return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->old_economy[quarter - 1].expenses;
}
/* static */ SQInteger ScriptCompany::GetQuarterlyCargoDelivered(ScriptCompany::CompanyID company, SQInteger quarter)
{
company = ResolveCompanyID(company);
if (company == COMPANY_INVALID) return -1;
if (company == ScriptCompany::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>();
return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->cur_economy.delivered_cargo.GetSum<OverflowSafeInt32>();
}
return ::Company::Get(company)->old_economy[quarter - 1].delivered_cargo.GetSum<OverflowSafeInt32>();
return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->old_economy[quarter - 1].delivered_cargo.GetSum<OverflowSafeInt32>();
}
/* static */ SQInteger ScriptCompany::GetQuarterlyPerformanceRating(ScriptCompany::CompanyID company, SQInteger quarter)
{
company = ResolveCompanyID(company);
if (company == COMPANY_INVALID) return -1;
if (company == ScriptCompany::COMPANY_INVALID) return -1;
if (quarter > EARLIEST_QUARTER) return -1;
if (quarter <= CURRENT_QUARTER) return -1;
return ::Company::Get(company)->old_economy[quarter - 1].performance_history;
return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->old_economy[quarter - 1].performance_history;
}
/* static */ Money ScriptCompany::GetQuarterlyCompanyValue(ScriptCompany::CompanyID company, SQInteger quarter)
{
company = ResolveCompanyID(company);
if (company == COMPANY_INVALID) return -1;
if (company == ScriptCompany::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));
return ::CalculateCompanyValue(::Company::Get(ScriptCompany::FromScriptCompanyID(company)));
}
return ::Company::Get(company)->old_economy[quarter - 1].company_value;
return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->old_economy[quarter - 1].company_value;
}
/* static */ Money ScriptCompany::GetBankBalance(ScriptCompany::CompanyID company)
{
company = ResolveCompanyID(company);
if (company == COMPANY_INVALID) return -1;
if (company == ScriptCompany::COMPANY_INVALID) return -1;
/* If we return INT64_MAX as usual, overflows may occur in the script. So return a smaller value. */
if (_settings_game.difficulty.infinite_money) return INT32_MAX;
return GetAvailableMoney((::CompanyID)company);
return GetAvailableMoney(ScriptCompany::FromScriptCompanyID(company));
}
/* static */ Money ScriptCompany::GetLoanAmount()
{
ScriptCompany::CompanyID company = ResolveCompanyID(COMPANY_SELF);
if (company == COMPANY_INVALID) return -1;
ScriptCompany::CompanyID company = ResolveCompanyID(ScriptCompany::COMPANY_SELF);
if (company == ScriptCompany::COMPANY_INVALID) return -1;
return ::Company::Get(company)->current_loan;
return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->current_loan;
}
/* static */ Money ScriptCompany::GetMaxLoanAmount()
{
if (ScriptCompanyMode::IsDeity()) return _economy.max_loan;
ScriptCompany::CompanyID company = ResolveCompanyID(COMPANY_SELF);
if (company == COMPANY_INVALID) return -1;
ScriptCompany::CompanyID company = ResolveCompanyID(ScriptCompany::COMPANY_SELF);
if (company == ScriptCompany::COMPANY_INVALID) return -1;
return ::Company::Get(company)->GetMaxLoan();
return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->GetMaxLoan();
}
/* static */ bool ScriptCompany::SetMaxLoanAmountForCompany(CompanyID company, Money amount)
/* static */ bool ScriptCompany::SetMaxLoanAmountForCompany(ScriptCompany::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);
EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID);
return ScriptObject::Command<CMD_SET_COMPANY_MAX_LOAN>::Do(ScriptCompany::FromScriptCompanyID(company), amount);
}
/* static */ bool ScriptCompany::ResetMaxLoanAmountForCompany(CompanyID company)
/* static */ bool ScriptCompany::ResetMaxLoanAmountForCompany(ScriptCompany::CompanyID company)
{
EnforceDeityMode(false);
company = ResolveCompanyID(company);
EnforcePrecondition(false, company != COMPANY_INVALID);
EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID);
return ScriptObject::Command<CMD_SET_COMPANY_MAX_LOAN>::Do((::CompanyID)company, COMPANY_MAX_LOAN_DEFAULT);
return ScriptObject::Command<CMD_SET_COMPANY_MAX_LOAN>::Do(ScriptCompany::FromScriptCompanyID(company), COMPANY_MAX_LOAN_DEFAULT);
}
/* static */ Money ScriptCompany::GetLoanInterval()
@@ -233,7 +247,7 @@
EnforcePrecondition(false, loan >= 0);
EnforcePrecondition(false, ((int64_t)loan % GetLoanInterval()) == 0);
EnforcePrecondition(false, loan <= GetMaxLoanAmount());
EnforcePrecondition(false, (loan - GetLoanAmount() + GetBankBalance(COMPANY_SELF)) >= 0);
EnforcePrecondition(false, (loan - GetLoanAmount() + GetBankBalance(ScriptCompany::COMPANY_SELF)) >= 0);
if (loan == GetLoanAmount()) return true;
@@ -261,17 +275,17 @@
return GetLoanAmount() == loan;
}
/* static */ bool ScriptCompany::ChangeBankBalance(CompanyID company, Money delta, ExpensesType expenses_type, TileIndex tile)
/* static */ bool ScriptCompany::ChangeBankBalance(ScriptCompany::CompanyID company, Money delta, ExpensesType expenses_type, TileIndex tile)
{
EnforceDeityMode(false);
EnforcePrecondition(false, expenses_type < (ExpensesType)::EXPENSES_END);
EnforcePrecondition(false, tile == INVALID_TILE || ::IsValidTile(tile));
company = ResolveCompanyID(company);
EnforcePrecondition(false, company != COMPANY_INVALID);
EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID);
/* Network commands only allow 0 to indicate invalid tiles, not INVALID_TILE */
return ScriptObject::Command<CMD_CHANGE_BANK_BALANCE>::Do(tile == INVALID_TILE ? (TileIndex)0U : tile, delta, (::CompanyID)company, (::ExpensesType)expenses_type);
return ScriptObject::Command<CMD_CHANGE_BANK_BALANCE>::Do(tile == INVALID_TILE ? (TileIndex)0U : tile, delta, ScriptCompany::FromScriptCompanyID(company), (::ExpensesType)expenses_type);
}
/* static */ bool ScriptCompany::BuildCompanyHQ(TileIndex tile)
@@ -282,12 +296,12 @@
return ScriptObject::Command<CMD_BUILD_OBJECT>::Do(tile, OBJECT_HQ, 0);
}
/* static */ TileIndex ScriptCompany::GetCompanyHQ(CompanyID company)
/* static */ TileIndex ScriptCompany::GetCompanyHQ(ScriptCompany::CompanyID company)
{
company = ResolveCompanyID(company);
if (company == COMPANY_INVALID) return INVALID_TILE;
if (company == ScriptCompany::COMPANY_INVALID) return INVALID_TILE;
TileIndex loc = ::Company::Get(company)->location_of_HQ;
TileIndex loc = ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->location_of_HQ;
return (loc == 0) ? INVALID_TILE : loc;
}
@@ -297,12 +311,12 @@
return ScriptObject::Command<CMD_CHANGE_COMPANY_SETTING>::Do("company.engine_renew", autorenew ? 1 : 0);
}
/* static */ bool ScriptCompany::GetAutoRenewStatus(CompanyID company)
/* static */ bool ScriptCompany::GetAutoRenewStatus(ScriptCompany::CompanyID company)
{
company = ResolveCompanyID(company);
if (company == COMPANY_INVALID) return false;
if (company == ScriptCompany::COMPANY_INVALID) return false;
return ::Company::Get(company)->settings.engine_renew;
return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->settings.engine_renew;
}
/* static */ bool ScriptCompany::SetAutoRenewMonths(SQInteger months)
@@ -313,12 +327,12 @@
return ScriptObject::Command<CMD_CHANGE_COMPANY_SETTING>::Do("company.engine_renew_months", months);
}
/* static */ SQInteger ScriptCompany::GetAutoRenewMonths(CompanyID company)
/* static */ SQInteger ScriptCompany::GetAutoRenewMonths(ScriptCompany::CompanyID company)
{
company = ResolveCompanyID(company);
if (company == COMPANY_INVALID) return 0;
if (company == ScriptCompany::COMPANY_INVALID) return 0;
return ::Company::Get(company)->settings.engine_renew_months;
return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->settings.engine_renew_months;
}
/* static */ bool ScriptCompany::SetAutoRenewMoney(Money money)
@@ -329,12 +343,12 @@
return ScriptObject::Command<CMD_CHANGE_COMPANY_SETTING>::Do("company.engine_renew_money", money);
}
/* static */ Money ScriptCompany::GetAutoRenewMoney(CompanyID company)
/* static */ Money ScriptCompany::GetAutoRenewMoney(ScriptCompany::CompanyID company)
{
company = ResolveCompanyID(company);
if (company == COMPANY_INVALID) return 0;
if (company == ScriptCompany::COMPANY_INVALID) return 0;
return ::Company::Get(company)->settings.engine_renew_money;
return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->settings.engine_renew_money;
}
/* static */ bool ScriptCompany::SetPrimaryLiveryColour(LiveryScheme scheme, Colours colour)

View File

@@ -30,8 +30,8 @@ public:
/** Different constants related to CompanyID. */
enum CompanyID {
/* Note: these values represent part of the in-game Owner enum */
COMPANY_FIRST = ::COMPANY_FIRST, ///< The first available company.
COMPANY_LAST = ::MAX_COMPANIES, ///< The last available company.
COMPANY_FIRST = ::CompanyID::Begin().base(), ///< The first available company.
COMPANY_LAST = ::CompanyID::End().base(), ///< The last available company.
/* Custom added value, only valid for this API */
COMPANY_INVALID = -1, ///< An invalid company.
@@ -39,6 +39,18 @@ public:
COMPANY_SPECTATOR = 255, ///< Constant indicating that player is spectating (gets resolved to COMPANY_INVALID)
};
/**
* Internal helper to convert from the script's company to the game's internal company.
* @api none
*/
static ::CompanyID FromScriptCompanyID(ScriptCompany::CompanyID company);
/**
* Internal helper to convert from the game's internal company to the script's company.
* @api none
*/
static ScriptCompany::CompanyID ToScriptCompanyID(::CompanyID company);
/** Possible genders for company presidents. */
enum Gender {
GENDER_MALE, ///< A male person.
@@ -124,7 +136,7 @@ public:
* @param company The company index to resolve.
* @return The resolved company index.
*/
static CompanyID ResolveCompanyID(CompanyID company);
static ScriptCompany::CompanyID ResolveCompanyID(ScriptCompany::CompanyID company);
/**
* Check if a CompanyID is your CompanyID, to ease up checks.
@@ -132,7 +144,7 @@ public:
* @game @pre ScriptCompanyMode::IsValid().
* @return True if and only if this company is your CompanyID.
*/
static bool IsMine(CompanyID company);
static bool IsMine(ScriptCompany::CompanyID company);
/**
* Set the name of your company.
@@ -150,7 +162,7 @@ public:
* @pre ResolveCompanyID(company) != COMPANY_INVALID.
* @return The name of the given company.
*/
static std::optional<std::string> GetName(CompanyID company);
static std::optional<std::string> GetName(ScriptCompany::CompanyID company);
/**
* Set the name of your president.
@@ -168,7 +180,7 @@ public:
* @pre ResolveCompanyID(company) != COMPANY_INVALID.
* @return The name of the president of the given company.
*/
static std::optional<std::string> GetPresidentName(CompanyID company);
static std::optional<std::string> GetPresidentName(ScriptCompany::CompanyID company);
/**
* Set the gender of the president of your company.
@@ -185,7 +197,7 @@ public:
* @param company The company to get the presidents gender off.
* @return The gender of the president.
*/
static Gender GetPresidentGender(CompanyID company);
static Gender GetPresidentGender(ScriptCompany::CompanyID company);
/**
* Sets the amount to loan.
@@ -235,7 +247,7 @@ public:
* @note Max loan value set with this method is not affected by inflation.
* @api -ai
*/
static bool SetMaxLoanAmountForCompany(CompanyID company, Money amount);
static bool SetMaxLoanAmountForCompany(ScriptCompany::CompanyID company, Money amount);
/**
* Makes the max amount of money company can loan follow the global max loan setting.
@@ -247,7 +259,7 @@ public:
* @note You need to create your own news message to inform about max loan change.
* @api -ai
*/
static bool ResetMaxLoanAmountForCompany(CompanyID company);
static bool ResetMaxLoanAmountForCompany(ScriptCompany::CompanyID company);
/**
* Gets the interval/loan step.
@@ -263,7 +275,7 @@ public:
* @pre ResolveCompanyID(company) != COMPANY_INVALID.
* @return The actual bank balance or INT32_MAX.
*/
static Money GetBankBalance(CompanyID company);
static Money GetBankBalance(ScriptCompany::CompanyID company);
/**
* Changes the bank balance by a delta value. This method does not affect the loan but instead
@@ -278,7 +290,7 @@ public:
* @note You need to create your own news message to inform about costs/gifts that you create using this command.
* @api -ai
*/
static bool ChangeBankBalance(CompanyID company, Money delta, ExpensesType expenses_type, TileIndex tile);
static bool ChangeBankBalance(ScriptCompany::CompanyID company, Money delta, ExpensesType expenses_type, TileIndex tile);
/**
* Get the income of the company in the given economy-quarter.
@@ -291,7 +303,7 @@ public:
* @return The gross income of the company in the given economy-quarter.
* @see \ref ScriptEconomyTime
*/
static Money GetQuarterlyIncome(CompanyID company, SQInteger quarter);
static Money GetQuarterlyIncome(ScriptCompany::CompanyID company, SQInteger quarter);
/**
* Get the expenses of the company in the given economy-quarter.
@@ -305,7 +317,7 @@ public:
* @return The expenses of the company in the given economy-quarter.
* @see \ref ScriptEconomyTime
*/
static Money GetQuarterlyExpenses(CompanyID company, SQInteger quarter);
static Money GetQuarterlyExpenses(ScriptCompany::CompanyID company, SQInteger quarter);
/**
* Get the amount of cargo delivered by the given company in the given economy-quarter.
@@ -316,7 +328,7 @@ public:
* @return The amount of cargo delivered by the given company in the given economy-quarter.
* @see \ref ScriptEconomyTime
*/
static SQInteger GetQuarterlyCargoDelivered(CompanyID company, SQInteger quarter);
static SQInteger GetQuarterlyCargoDelivered(ScriptCompany::CompanyID company, SQInteger quarter);
/**
* Get the performance rating of the given company in the given economy-quarter.
@@ -329,7 +341,7 @@ public:
* @return The performance rating of the given company in the given economy-quarter.
* @see \ref ScriptEconomyTime
*/
static SQInteger GetQuarterlyPerformanceRating(CompanyID company, SQInteger quarter);
static SQInteger GetQuarterlyPerformanceRating(ScriptCompany::CompanyID company, SQInteger quarter);
/**
* Get the value of the company in the given economy-quarter.
@@ -340,7 +352,7 @@ public:
* @return The value of the company in the given economy-quarter.
* @see \ref ScriptEconomyTime
*/
static Money GetQuarterlyCompanyValue(CompanyID company, SQInteger quarter);
static Money GetQuarterlyCompanyValue(ScriptCompany::CompanyID company, SQInteger quarter);
/**
* Build your company's HQ on the given tile.
@@ -362,7 +374,7 @@ public:
* @return The tile of the company's HQ, this tile is the most northern tile
* of that HQ, or ScriptMap::TILE_INVALID if there is no HQ yet.
*/
static TileIndex GetCompanyHQ(CompanyID company);
static TileIndex GetCompanyHQ(ScriptCompany::CompanyID company);
/**
* Set whether autorenew is enabled for your company.
@@ -378,7 +390,7 @@ public:
* @pre ResolveCompanyID(company) != COMPANY_INVALID.
* @return True if autorenew is enabled.
*/
static bool GetAutoRenewStatus(CompanyID company);
static bool GetAutoRenewStatus(ScriptCompany::CompanyID company);
/**
* Set the number of months before/after max age to autorenew an engine for your company.
@@ -397,7 +409,7 @@ public:
* @return The number of calendar-months before/after max age of engine.
* @see \ref ScriptCalendarTime
*/
static SQInteger GetAutoRenewMonths(CompanyID company);
static SQInteger GetAutoRenewMonths(ScriptCompany::CompanyID company);
/**
* Set the minimum money needed to autorenew an engine for your company.
@@ -415,7 +427,7 @@ public:
* @pre ResolveCompanyID(company) != COMPANY_INVALID.
* @return The minimum required money for autorenew to work.
*/
static Money GetAutoRenewMoney(CompanyID company);
static Money GetAutoRenewMoney(ScriptCompany::CompanyID company);
/**
* Set primary colour for your company.
@@ -450,6 +462,6 @@ public:
static ScriptCompany::Colours GetSecondaryLiveryColour(LiveryScheme scheme);
};
DECLARE_POSTFIX_INCREMENT(ScriptCompany::CompanyID)
DECLARE_INCREMENT_DECREMENT_OPERATORS(ScriptCompany::CompanyID)
#endif /* SCRIPT_COMPANY_HPP */

View File

@@ -13,13 +13,12 @@
#include "../../safeguards.h"
ScriptCompanyMode::ScriptCompanyMode(SQInteger company)
ScriptCompanyMode::ScriptCompanyMode(ScriptCompany::CompanyID company)
{
if (company < OWNER_BEGIN || company >= MAX_COMPANIES) company = INVALID_COMPANY;
if (!::Company::IsValidID(company)) company = INVALID_COMPANY;
company = ScriptCompany::ResolveCompanyID(company);
this->last_company = ScriptObject::GetCompany();
ScriptObject::SetCompany((::CompanyID)company);
ScriptObject::SetCompany(ScriptCompany::FromScriptCompanyID(company));
}
ScriptCompanyMode::~ScriptCompanyMode()

View File

@@ -11,6 +11,7 @@
#define SCRIPT_COMPANYMODE_HPP
#include "script_object.hpp"
#include "script_company.hpp"
/**
* Class to switch the current company.
@@ -30,7 +31,7 @@
*/
class ScriptCompanyMode : public ScriptObject {
private:
CompanyID last_company; ///< The previous company we were in.
::CompanyID last_company; ///< The previous company we were in.
public:
/**
@@ -40,7 +41,7 @@ public:
* @note When the instance is destroyed, it restores the company that was
* current when the instance was created!
*/
ScriptCompanyMode(SQInteger company);
ScriptCompanyMode(ScriptCompany::CompanyID company);
/**
* Destroying this instance reset the company to that what it was

View File

@@ -57,8 +57,8 @@
* needs manual action to continue. */
ShowScriptDebugWindow(ScriptObject::GetRootCompany());
if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) {
ScriptObject::Command<CMD_PAUSE>::Do(PM_PAUSED_NORMAL, true);
if (!_pause_mode.Test(PauseMode::Normal)) {
ScriptObject::Command<CMD_PAUSE>::Do(PauseMode::Normal, true);
}
}
@@ -67,7 +67,7 @@
ScriptLog::Log(error_msg ? ScriptLogTypes::LOG_SQ_ERROR : ScriptLogTypes::LOG_SQ_INFO, message);
}
ScriptController::ScriptController(CompanyID company) :
ScriptController::ScriptController(::CompanyID company) :
ticks(0),
loaded_library_count(0)
{

View File

@@ -11,6 +11,7 @@
#define SCRIPT_CONTROLLER_HPP
#include "script_types.hpp"
#include "../../company_type.h"
/**
* The Controller, the class each Script should extend. It creates the Script,
@@ -51,7 +52,7 @@ public:
* Initializer of the ScriptController.
* @param company The company this Script is normally serving.
*/
ScriptController(CompanyID company);
ScriptController(::CompanyID company);
#else
/**
@@ -76,9 +77,8 @@ public:
* - booleans, and
* - nulls.
*
* In particular, instances of classes can't be saved including
* ScriptList. Such a list should be converted to an array or table on
* save and converted back on load.
* In particular, instances of classes can't be saved with the exception of
* ScriptList.
*
* The function is called as soon as the user saves the game,
* independently of other activities of the script. The script is not
@@ -208,11 +208,6 @@ private:
uint ticks; ///< The amount of ticks we're sleeping.
LoadedLibraryList loaded_library; ///< The libraries we loaded.
int loaded_library_count; ///< The amount of libraries.
/**
* Register all classes that are known inside the script API.
*/
void RegisterClasses();
};
#endif /* SCRIPT_CONTROLLER_HPP */

View File

@@ -29,7 +29,7 @@
{
if (date < 0) return DATE_INVALID;
::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(date);
::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(::TimerGameEconomy::Date{date});
return ymd.year.base();
}
@@ -37,7 +37,7 @@
{
if (date < 0) return DATE_INVALID;
::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(date);
::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(::TimerGameEconomy::Date{date});
return ymd.month + 1;
}
@@ -45,7 +45,7 @@
{
if (date < 0) return DATE_INVALID;
::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(date);
::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(::TimerGameEconomy::Date{date});
return ymd.day;
}
@@ -53,9 +53,11 @@
{
if (month < 1 || month > 12) return DATE_INVALID;
if (day_of_month < 1 || day_of_month > 31) return DATE_INVALID;
if (year < 0 || year > EconomyTime::MAX_YEAR) return DATE_INVALID;
return (ScriptDate::Date)::TimerGameEconomy::ConvertYMDToDate(year, month - 1, day_of_month).base();
::TimerGameEconomy::Year timer_year{ClampTo<int32_t>(year)};
if (timer_year < EconomyTime::MIN_YEAR || timer_year > EconomyTime::MAX_YEAR) return DATE_INVALID;
return static_cast<ScriptDate::Date>(::TimerGameEconomy::ConvertYMDToDate(timer_year, month - 1, day_of_month).base());
}
/* static */ SQInteger ScriptDate::GetSystemTime()

View File

@@ -28,7 +28,7 @@ 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();
::CompanyID owner = ScriptObject::GetCompany();
for (const Station *st : Station::Iterate()) {
if (is_deity || st->owner == owner) {
for (uint i = 0; i < st->airport.GetNumHangars(); i++) {
@@ -42,7 +42,7 @@ ScriptDepotList::ScriptDepotList(ScriptTile::TransportType transport_type)
/* Handle 'standard' depots. */
bool is_deity = ScriptCompanyMode::IsDeity();
CompanyID owner = ScriptObject::GetCompany();
::CompanyID owner = ScriptObject::GetCompany();
for (const Depot *depot : Depot::Iterate()) {
if ((is_deity || ::GetTileOwner(depot->xy) == owner) && ::IsTileType(depot->xy, tile_type)) this->AddItem(depot->xy.base());
}

View File

@@ -19,6 +19,7 @@
#include "../../articulated_vehicles.h"
#include "../../engine_cmd.h"
#include "../../timer/timer_game_calendar.h"
#include "table/strings.h"
#include "../../safeguards.h"
@@ -31,7 +32,7 @@
/* 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();
::CompanyID company = ScriptObject::GetCompany();
return ScriptCompanyMode::IsDeity() || ::IsEngineBuildable(engine_id, e->type, company) || ::Company::Get(company)->group_all[e->type].GetNumEngines(engine_id) > 0;
}
@@ -46,11 +47,10 @@
{
if (!IsValidEngine(engine_id)) return std::nullopt;
::SetDParam(0, engine_id);
return GetString(STR_ENGINE_NAME);
return ::StrMakeValid(::GetString(STR_ENGINE_NAME, engine_id));
}
/* static */ CargoID ScriptEngine::GetCargoType(EngineID engine_id)
/* static */ CargoType ScriptEngine::GetCargoType(EngineID engine_id)
{
if (!IsValidEngine(engine_id)) return INVALID_CARGO;
@@ -59,24 +59,24 @@
auto it = std::max_element(std::cbegin(cap), std::cend(cap));
if (*it == 0) return INVALID_CARGO;
return CargoID(std::distance(std::cbegin(cap), it));
return CargoType(std::distance(std::cbegin(cap), it));
}
/* static */ bool ScriptEngine::CanRefitCargo(EngineID engine_id, CargoID cargo_id)
/* static */ bool ScriptEngine::CanRefitCargo(EngineID engine_id, CargoType cargo_type)
{
if (!IsValidEngine(engine_id)) return false;
if (!ScriptCargo::IsValidCargo(cargo_id)) return false;
if (!ScriptCargo::IsValidCargo(cargo_type)) return false;
return HasBit(::GetUnionOfArticulatedRefitMasks(engine_id, true), cargo_id);
return HasBit(::GetUnionOfArticulatedRefitMasks(engine_id, true), cargo_type);
}
/* static */ bool ScriptEngine::CanPullCargo(EngineID engine_id, CargoID cargo_id)
/* static */ bool ScriptEngine::CanPullCargo(EngineID engine_id, CargoType cargo_type)
{
if (!IsValidEngine(engine_id)) return false;
if (GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL) return false;
if (!ScriptCargo::IsValidCargo(cargo_id)) return false;
if (!ScriptCargo::IsValidCargo(cargo_type)) return false;
return (::RailVehInfo(engine_id)->ai_passenger_only != 1) || ScriptCargo::HasCargoClass(cargo_id, ScriptCargo::CC_PASSENGERS);
return (::RailVehInfo(engine_id)->ai_passenger_only != 1) || ScriptCargo::HasCargoClass(cargo_type, ScriptCargo::CC_PASSENGERS);
}
@@ -277,7 +277,7 @@
EnforcePrecondition(false, IsValidEngine(engine_id));
EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID);
return ScriptObject::Command<CMD_ENGINE_CTRL>::Do(engine_id, (::CompanyID)company, true);
return ScriptObject::Command<CMD_ENGINE_CTRL>::Do(engine_id, ScriptCompany::FromScriptCompanyID(company), true);
}
/* static */ bool ScriptEngine::DisableForCompany(EngineID engine_id, ScriptCompany::CompanyID company)
@@ -288,5 +288,5 @@
EnforcePrecondition(false, IsValidEngine(engine_id));
EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID);
return ScriptObject::Command<CMD_ENGINE_CTRL>::Do(engine_id, (::CompanyID)company, false);
return ScriptObject::Command<CMD_ENGINE_CTRL>::Do(engine_id, ScriptCompany::FromScriptCompanyID(company), false);
}

View File

@@ -53,7 +53,7 @@ public:
* @pre IsValidEngine(engine_id).
* @return The cargo-type of the engine.
*/
static CargoID GetCargoType(EngineID engine_id);
static CargoType GetCargoType(EngineID engine_id);
/**
* Check if the cargo of an engine can be refitted to your requested. If
@@ -61,26 +61,26 @@ public:
* In case of articulated vehicles the function decides whether at least one
* part can carry the cargo.
* @param engine_id The engine to check for refitting.
* @param cargo_id The cargo to check for refitting.
* @param cargo_type The cargo to check for refitting.
* @pre IsValidEngine(engine_id).
* @pre ScriptCargo::IsValidCargo(cargo_id).
* @pre ScriptCargo::IsValidCargo(cargo_type).
* @return True if the engine can carry this cargo, either via refit, or
* by default.
*/
static bool CanRefitCargo(EngineID engine_id, CargoID cargo_id);
static bool CanRefitCargo(EngineID engine_id, CargoType cargo_type);
/**
* Check if the engine can pull a wagon with the given cargo.
* @param engine_id The engine to check.
* @param cargo_id The cargo to check.
* @param cargo_type The cargo to check.
* @pre IsValidEngine(engine_id).
* @pre GetVehicleType(engine_id) == ScriptVehicle::VT_RAIL.
* @pre ScriptCargo::IsValidCargo(cargo_id).
* @pre ScriptCargo::IsValidCargo(cargo_type).
* @return True if the engine can pull wagons carrying this cargo.
* @note This function is not exhaustive; a true here does not mean
* that the vehicle can pull the wagons, a false does mean it can't.
*/
static bool CanPullCargo(EngineID engine_id, CargoID cargo_id);
static bool CanPullCargo(EngineID engine_id, CargoType cargo_type);
/**
* Get the capacity of an engine. In case it can transport multiple cargoes, it

View File

@@ -17,8 +17,8 @@ ScriptEngineList::ScriptEngineList(ScriptVehicle::VehicleType vehicle_type)
{
EnforceDeityOrCompanyModeValid_Void();
bool is_deity = ScriptCompanyMode::IsDeity();
CompanyID owner = ScriptObject::GetCompany();
::CompanyID owner = ScriptObject::GetCompany();
for (const Engine *e : Engine::IterateType((::VehicleType)vehicle_type)) {
if (is_deity || HasBit(e->company_avail, owner)) this->AddItem(e->index);
if (is_deity || e->company_avail.Test(owner)) this->AddItem(e->index.base());
}
}

View File

@@ -25,12 +25,14 @@ ScriptError::ScriptErrorMapString ScriptError::error_map_string = ScriptError::S
/* static */ std::optional<std::string> ScriptError::GetLastErrorString()
{
return (*error_map_string.find(ScriptError::GetLastError())).second;
auto it = ScriptError::error_map_string.find(ScriptError::GetLastError());
assert(it != ScriptError::error_map_string.end());
return it->second;
}
/* static */ ScriptErrorType ScriptError::StringToError(StringID internal_string_id)
{
uint index = GetStringIndex(internal_string_id);
StringIndexInTab index = GetStringIndex(internal_string_id);
switch (GetStringTab(internal_string_id)) {
case TEXT_TAB_NEWGRF_START:
case TEXT_TAB_GAMESCRIPT_START:

View File

@@ -57,6 +57,8 @@ public:
ET_STORYPAGE_BUTTON_CLICK,
ET_STORYPAGE_TILE_SELECT,
ET_STORYPAGE_VEHICLE_SELECT,
ET_COMPANY_RENAMED,
ET_PRESIDENT_RENAMED,
};
/**

View File

@@ -19,6 +19,7 @@
#include "../../economy_cmd.h"
#include "../../engine_cmd.h"
#include "../../3rdparty/nlohmann/json.hpp"
#include "table/strings.h"
#include "../../safeguards.h"
@@ -33,11 +34,10 @@ std::optional<std::string> ScriptEventEnginePreview::GetName()
{
if (!this->IsEngineValid()) return std::nullopt;
::SetDParam(0, this->engine);
return GetString(STR_ENGINE_NAME);
return ::StrMakeValid(::GetString(STR_ENGINE_NAME, this->engine));
}
CargoID ScriptEventEnginePreview::GetCargoType()
CargoType ScriptEventEnginePreview::GetCargoType()
{
if (!this->IsEngineValid()) return INVALID_CARGO;
CargoArray cap = ::GetCapacityOfArticulatedParts(this->engine);
@@ -45,7 +45,7 @@ CargoID ScriptEventEnginePreview::GetCargoType()
auto it = std::max_element(std::cbegin(cap), std::cend(cap));
if (*it == 0) return INVALID_CARGO;
return CargoID(std::distance(std::cbegin(cap), it));
return CargoType(std::distance(std::cbegin(cap), it));
}
int32_t ScriptEventEnginePreview::GetCapacity()
@@ -113,7 +113,7 @@ bool ScriptEventEnginePreview::AcceptPreview()
bool ScriptEventCompanyAskMerger::AcceptMerger()
{
EnforceCompanyModeValid(false);
return ScriptObject::Command<CMD_BUY_COMPANY>::Do((::CompanyID)this->owner, false);
return ScriptObject::Command<CMD_BUY_COMPANY>::Do(ScriptCompany::FromScriptCompanyID(this->owner), false);
}
ScriptEventAdminPort::ScriptEventAdminPort(const std::string &json) :
@@ -122,7 +122,7 @@ ScriptEventAdminPort::ScriptEventAdminPort(const std::string &json) :
{
}
/**
* Convert a JSON part fo Squirrel.
* Convert a JSON part for Squirrel.
* @param vm The VM used.
* @param json The JSON part to convert to Squirrel.
*/

View File

@@ -13,6 +13,12 @@
#include "script_event.hpp"
#include "script_goal.hpp"
#include "script_window.hpp"
#include "../../engine_type.h"
#include "../../industry_type.h"
#include "../../station_type.h"
#include "../../story_type.h"
#include "../../subsidy_type.h"
#include "../../vehicle_type.h"
/**
* Event Vehicle Crash, indicating a vehicle of yours is crashed.
@@ -39,13 +45,15 @@ public:
* @param crash_site Where the vehicle crashed.
* @param crash_reason The reason why the vehicle crashed.
* @param victims The number of victims caused by the crash.
* @param the ID of the company owning the crashed vehicle.
*/
ScriptEventVehicleCrashed(VehicleID vehicle, TileIndex crash_site, CrashReason crash_reason, uint victims) :
ScriptEventVehicleCrashed(VehicleID vehicle, TileIndex crash_site, CrashReason crash_reason, uint victims, ::CompanyID company) :
ScriptEvent(ET_VEHICLE_CRASHED),
crash_site(crash_site),
vehicle(vehicle),
crash_reason(crash_reason),
victims(victims)
victims(victims),
company(ScriptCompany::ToScriptCompanyID(company))
{}
#endif /* DOXYGEN_API */
@@ -80,11 +88,18 @@ public:
*/
SQInteger GetVictims() { return this->victims; }
/**
* Get the CompanyID of the company owning the vehicle
* @return The company owning the vehicle
*/
ScriptCompany::CompanyID GetVehicleOwner() { return this->company; }
private:
TileIndex crash_site; ///< The location of the crash.
VehicleID vehicle; ///< The crashed vehicle.
CrashReason crash_reason; ///< The reason for crashing.
uint victims; ///< The number of victims.
uint victims; ///< The number of victims.
ScriptCompany::CompanyID company; ///< The company owning the vehicle.
};
/**
@@ -255,7 +270,7 @@ public:
* returns the first/main.
* @return The cargo-type of the engine.
*/
CargoID GetCargoType();
CargoType GetCargoType();
/**
* Get the capacity of the offered engine. In case it can transport multiple cargoes, it
@@ -325,7 +340,7 @@ public:
*/
ScriptEventCompanyNew(Owner owner) :
ScriptEvent(ET_COMPANY_NEW),
owner((ScriptCompany::CompanyID)owner)
owner(ScriptCompany::ToScriptCompanyID(owner))
{}
#endif /* DOXYGEN_API */
@@ -346,6 +361,48 @@ private:
ScriptCompany::CompanyID owner; ///< The new company.
};
/**
* Event Company Renamed, indicating a company has changed name.
* @api ai game
*/
class ScriptEventCompanyRenamed : public ScriptEvent {
public:
#ifndef DOXYGEN_API
/**
* @param owner The company that is renamed.
*/
ScriptEventCompanyRenamed(::CompanyID company, const std::string &new_name) :
ScriptEvent(ET_COMPANY_RENAMED),
company(ScriptCompany::ToScriptCompanyID(company)),
new_name(new_name)
{}
#endif /* DOXYGEN_API */
/**
* Convert an ScriptEvent to the real instance.
* @param instance The instance to convert.
* @return The converted instance.
*/
static ScriptEventCompanyRenamed *Convert(ScriptEvent *instance) { return static_cast<ScriptEventCompanyRenamed *>(instance); }
/**
* Get the CompanyID of the company that has been renamed.
* @return The CompanyID of the company.
*/
ScriptCompany::CompanyID GetCompanyID() { return this->company; }
/**
* Get the new name of the company.
* @return The new name of the company.
*/
std::optional<std::string> GetNewName() { return this->new_name; }
private:
ScriptCompany::CompanyID company; ///< The company that was renamed.
std::string new_name; ///< The new name of the company.
};
/**
* Event Company In Trouble, indicating a company is in trouble and might go
* bankrupt soon.
@@ -359,7 +416,7 @@ public:
*/
ScriptEventCompanyInTrouble(Owner owner) :
ScriptEvent(ET_COMPANY_IN_TROUBLE),
owner((ScriptCompany::CompanyID)owner)
owner(ScriptCompany::ToScriptCompanyID(owner))
{}
#endif /* DOXYGEN_API */
@@ -393,7 +450,7 @@ public:
*/
ScriptEventCompanyAskMerger(Owner owner, Money value) :
ScriptEvent(ET_COMPANY_ASK_MERGER),
owner((ScriptCompany::CompanyID)owner),
owner(ScriptCompany::ToScriptCompanyID(owner)),
value(value)
{}
#endif /* DOXYGEN_API */
@@ -444,8 +501,8 @@ public:
*/
ScriptEventCompanyMerger(Owner old_owner, Owner new_owner) :
ScriptEvent(ET_COMPANY_MERGER),
old_owner((ScriptCompany::CompanyID)old_owner),
new_owner((ScriptCompany::CompanyID)new_owner)
old_owner(ScriptCompany::ToScriptCompanyID(old_owner)),
new_owner(ScriptCompany::ToScriptCompanyID(new_owner))
{}
#endif /* DOXYGEN_API */
@@ -488,7 +545,7 @@ public:
*/
ScriptEventCompanyBankrupt(Owner owner) :
ScriptEvent(ET_COMPANY_BANKRUPT),
owner((ScriptCompany::CompanyID)owner)
owner(ScriptCompany::ToScriptCompanyID(owner))
{}
#endif /* DOXYGEN_API */
@@ -986,10 +1043,10 @@ public:
* @param company The company that is replying.
* @param button The button the company pressed.
*/
ScriptEventGoalQuestionAnswer(uint16_t uniqueid, ScriptCompany::CompanyID company, ScriptGoal::QuestionButton button) :
ScriptEventGoalQuestionAnswer(uint16_t uniqueid, ::CompanyID company, ScriptGoal::QuestionButton button) :
ScriptEvent(ET_GOAL_QUESTION_ANSWER),
uniqueid(uniqueid),
company(company),
company(ScriptCompany::ToScriptCompanyID(company)),
button(button)
{}
#endif /* DOXYGEN_API */
@@ -1037,9 +1094,9 @@ public:
* @param company The company.
* @param town The town.
*/
ScriptEventCompanyTown(ScriptEventType event, ScriptCompany::CompanyID company, TownID town) :
ScriptEventCompanyTown(ScriptEventType event, ::CompanyID company, TownID town) :
ScriptEvent(event),
company(company),
company(ScriptCompany::ToScriptCompanyID(company)),
town(town)
{}
#endif /* DOXYGEN_API */
@@ -1080,7 +1137,7 @@ public:
* @param company The company.
* @param town The town.
*/
ScriptEventExclusiveTransportRights(ScriptCompany::CompanyID company, TownID town) :
ScriptEventExclusiveTransportRights(::CompanyID company, TownID town) :
ScriptEventCompanyTown(ET_EXCLUSIVE_TRANSPORT_RIGHTS, company, town)
{}
#endif /* DOXYGEN_API */
@@ -1105,7 +1162,7 @@ public:
* @param company The company.
* @param town The town.
*/
ScriptEventRoadReconstruction(ScriptCompany::CompanyID company, TownID town) :
ScriptEventRoadReconstruction(::CompanyID company, TownID town) :
ScriptEventCompanyTown(ET_ROAD_RECONSTRUCTION, company, town)
{}
#endif /* DOXYGEN_API */
@@ -1172,9 +1229,9 @@ public:
* @param page_id Which page was the clicked button on.
* @param element_id Which button element was clicked.
*/
ScriptEventStoryPageButtonClick(CompanyID company_id, StoryPageID page_id, StoryPageElementID element_id) :
ScriptEventStoryPageButtonClick(::CompanyID company_id, StoryPageID page_id, StoryPageElementID element_id) :
ScriptEvent(ET_STORYPAGE_BUTTON_CLICK),
company_id((ScriptCompany::CompanyID)company_id),
company_id(ScriptCompany::ToScriptCompanyID(company_id)),
page_id(page_id),
element_id(element_id)
{}
@@ -1224,9 +1281,9 @@ public:
* @param element_id Which button element was used to select the tile.
* @param tile_index Which tile was selected by the player.
*/
ScriptEventStoryPageTileSelect(CompanyID company_id, StoryPageID page_id, StoryPageElementID element_id, TileIndex tile_index) :
ScriptEventStoryPageTileSelect(::CompanyID company_id, StoryPageID page_id, StoryPageElementID element_id, TileIndex tile_index) :
ScriptEvent(ET_STORYPAGE_TILE_SELECT),
company_id((ScriptCompany::CompanyID)company_id),
company_id(ScriptCompany::ToScriptCompanyID(company_id)),
page_id(page_id),
element_id(element_id),
tile_index(tile_index)
@@ -1284,9 +1341,9 @@ public:
* @param element_id Which button element was used to select the tile.
* @param vehicle_id Which vehicle was selected by the player.
*/
ScriptEventStoryPageVehicleSelect(CompanyID company_id, StoryPageID page_id, StoryPageElementID element_id, VehicleID vehicle_id) :
ScriptEventStoryPageVehicleSelect(::CompanyID company_id, StoryPageID page_id, StoryPageElementID element_id, VehicleID vehicle_id) :
ScriptEvent(ET_STORYPAGE_VEHICLE_SELECT),
company_id((ScriptCompany::CompanyID)company_id),
company_id(ScriptCompany::ToScriptCompanyID(company_id)),
page_id(page_id),
element_id(element_id),
vehicle_id(vehicle_id)
@@ -1331,4 +1388,48 @@ private:
VehicleID vehicle_id;
};
/**
* Event President Renamed, indicating a company's president's name has changed.
* This event is not sent to the company for who the president's name changed.
* @api ai game
*/
class ScriptEventPresidentRenamed : public ScriptEvent {
public:
#ifndef DOXYGEN_API
/**
* @param company The company of the president.
* @param new_name The new name of the president.
*/
ScriptEventPresidentRenamed(::CompanyID company, const std::string &new_name) :
ScriptEvent(ET_PRESIDENT_RENAMED),
company(ScriptCompany::ToScriptCompanyID(company)),
new_name(new_name)
{}
#endif /* DOXYGEN_API */
/**
* Convert an ScriptEvent to the real instance.
* @param instance The instance to convert.
* @return The converted instance.
*/
static ScriptEventPresidentRenamed *Convert(ScriptEvent *instance) { return static_cast<ScriptEventPresidentRenamed *>(instance); }
/**
* Get the CompanyID of the company that got its president renamed.
* @return The CompanyID of the company.
*/
ScriptCompany::CompanyID GetCompanyID() { return this->company; }
/**
* Get the new name of the president.
* @return The new name of the president.
*/
std::optional<std::string> GetNewName() { return this->new_name; }
private:
ScriptCompany::CompanyID company; ///< The company of the renamed president.
std::string new_name; ///< The new name of the president.
};
#endif /* SCRIPT_EVENT_TYPES_HPP */

View File

@@ -19,17 +19,17 @@
/* static */ bool ScriptGame::Pause()
{
return ScriptObject::Command<CMD_PAUSE>::Do(PM_PAUSED_GAME_SCRIPT, true);
return ScriptObject::Command<CMD_PAUSE>::Do(PauseMode::GameScript, true);
}
/* static */ bool ScriptGame::Unpause()
{
return ScriptObject::Command<CMD_PAUSE>::Do(PM_PAUSED_GAME_SCRIPT, false);
return ScriptObject::Command<CMD_PAUSE>::Do(PauseMode::GameScript, false);
}
/* static */ bool ScriptGame::IsPaused()
{
return !!_pause_mode;
return _pause_mode.Any();
}
/* static */ ScriptGame::LandscapeType ScriptGame::GetLandscape()

View File

@@ -24,10 +24,10 @@ public:
*/
enum LandscapeType {
/* Note: these values represent part of the in-game LandscapeType enum */
LT_TEMPERATE = ::LT_TEMPERATE, ///< Temperate climate.
LT_ARCTIC = ::LT_ARCTIC, ///< Arctic climate.
LT_TROPIC = ::LT_TROPIC, ///< Tropic climate.
LT_TOYLAND = ::LT_TOYLAND, ///< Toyland climate.
LT_TEMPERATE = to_underlying(::LandscapeType::Temperate), ///< Temperate climate.
LT_ARCTIC = to_underlying(::LandscapeType::Arctic), ///< Arctic climate.
LT_TROPIC = to_underlying(::LandscapeType::Tropic), ///< Tropic climate.
LT_TOYLAND = to_underlying(::LandscapeType::Toyland), ///< Toyland climate.
};
/**

View File

@@ -39,7 +39,7 @@
const SettingDesc *sd = GetSettingFromName(setting);
assert(sd != nullptr);
if ((sd->flags & SF_NO_NETWORK_SYNC) != 0) return false;
if ((sd->flags.Test(SettingFlag::NoNetworkSync))) return false;
value = Clamp<SQInteger>(value, INT32_MIN, INT32_MAX);

View File

@@ -30,33 +30,41 @@
/* static */ bool ScriptGoal::IsValidGoalDestination(ScriptCompany::CompanyID company, GoalType type, SQInteger destination)
{
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);
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));
switch (type) {
case GT_NONE: return destination == 0;
case GT_TILE: return ScriptMap::IsValidTile(::TileIndex(destination));
case GT_INDUSTRY: return ScriptIndustry::IsValidIndustry(static_cast<IndustryID>(destination));
case GT_TOWN: return ScriptTown::IsValidTown(static_cast<TownID>(destination));
case GT_COMPANY: return ScriptCompany::ResolveCompanyID(ScriptCompany::ToScriptCompanyID(static_cast<::CompanyID>(destination))) != ScriptCompany::COMPANY_INVALID;
case GT_STORY_PAGE: {
if (!ScriptStoryPage::IsValidStoryPage(static_cast<StoryPageID>(destination))) return false;
StoryPage *story_page = ::StoryPage::Get(static_cast<StoryPageID>(destination));
if (story_page->company == CompanyID::Invalid()) return true;
::CompanyID c = ScriptCompany::FromScriptCompanyID(company);
return c != CompanyID::Invalid() && story_page->company == c;
}
default: return false;
}
}
/* static */ ScriptGoal::GoalID ScriptGoal::New(ScriptCompany::CompanyID company, Text *goal, GoalType type, SQInteger destination)
/* static */ GoalID ScriptGoal::New(ScriptCompany::CompanyID company, Text *goal, GoalType type, SQInteger destination)
{
ScriptObjectRef counter(goal);
EnforceDeityMode(GOAL_INVALID);
EnforcePrecondition(GOAL_INVALID, goal != nullptr);
std::string text = goal->GetEncodedText();
EncodedString 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;
if (!ScriptObject::Command<CMD_CREATE_GOAL>::Do(&ScriptInstance::DoCommandReturnGoalID, ScriptCompany::FromScriptCompanyID(company), (::GoalType)type, destination, text)) return GOAL_INVALID;
/* In case of test-mode, we return GoalID 0 */
return (ScriptGoal::GoalID)0;
return GoalID::Begin();
}
/* static */ bool ScriptGoal::Remove(GoalID goal_id)
@@ -72,7 +80,7 @@
EnforceDeityMode(false);
EnforcePrecondition(false, IsValidGoal(goal_id));
const Goal *g = Goal::Get(goal_id);
EnforcePrecondition(false, IsValidGoalDestination((ScriptCompany::CompanyID)g->company, type, destination));
EnforcePrecondition(false, IsValidGoalDestination(ScriptCompany::ToScriptCompanyID(g->company), type, destination));
return ScriptObject::Command<CMD_SET_GOAL_DESTINATION>::Do(goal_id, (::GoalType)type, destination);
}
@@ -84,7 +92,7 @@
EnforcePrecondition(false, IsValidGoal(goal_id));
EnforceDeityMode(false);
EnforcePrecondition(false, goal != nullptr);
std::string text = goal->GetEncodedText();
EncodedString text = goal->GetEncodedText();
EnforcePreconditionEncodedText(false, text);
return ScriptObject::Command<CMD_SET_GOAL_TEXT>::Do(goal_id, text);
@@ -97,7 +105,7 @@
EnforcePrecondition(false, IsValidGoal(goal_id));
EnforceDeityMode(false);
return ScriptObject::Command<CMD_SET_GOAL_PROGRESS>::Do(goal_id, progress != nullptr ? progress->GetEncodedText() : std::string{});
return ScriptObject::Command<CMD_SET_GOAL_PROGRESS>::Do(goal_id, progress != nullptr ? progress->GetEncodedText() : EncodedString{});
}
/* static */ bool ScriptGoal::SetCompleted(GoalID goal_id, bool completed)
@@ -123,7 +131,7 @@
EnforceDeityMode(false);
EnforcePrecondition(false, question != nullptr);
std::string text = question->GetEncodedText();
EncodedString text = question->GetEncodedText();
EnforcePreconditionEncodedText(false, text);
uint min_buttons = (type == QT_QUESTION ? 1 : 0);
EnforcePrecondition(false, CountBits<uint64_t>(buttons) >= min_buttons && CountBits<uint64_t>(buttons) <= 3);
@@ -137,10 +145,7 @@
/* 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_t c = company;
if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY;
return DoQuestion(uniqueid, c, false, question, type, buttons);
return DoQuestion(uniqueid, ScriptCompany::FromScriptCompanyID(company).base(), false, question, type, buttons);
}
/* static */ bool ScriptGoal::QuestionClient(SQInteger uniqueid, ScriptClient::ClientID client, Text *question, QuestionType type, SQInteger buttons)

View File

@@ -25,13 +25,7 @@
*/
class ScriptGoal : public ScriptObject {
public:
/**
* The goal IDs.
*/
enum GoalID : uint16_t {
/* Note: these values represent part of the in-game GoalID enum */
GOAL_INVALID = ::INVALID_GOAL, ///< An invalid goal id.
};
static constexpr GoalID GOAL_INVALID = ::GoalID::Invalid(); ///< An invalid goal id.
/**
* Goal types that can be given to a goal.

View File

@@ -19,6 +19,7 @@
#include "../../autoreplace_cmd.h"
#include "../../group_cmd.h"
#include "../../settings_cmd.h"
#include "table/strings.h"
#include "../../safeguards.h"
@@ -30,13 +31,13 @@
return g != nullptr && g->owner == ScriptObject::GetCompany();
}
/* static */ ScriptGroup::GroupID ScriptGroup::CreateGroup(ScriptVehicle::VehicleType vehicle_type, GroupID parent_group_id)
/* static */ 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 */
return (ScriptGroup::GroupID)0;
return GroupID::Begin();
}
/* static */ bool ScriptGroup::DeleteGroup(GroupID group_id)
@@ -65,15 +66,14 @@
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);
return ScriptObject::Command<CMD_ALTER_GROUP>::Do(AlterGroupMode::Rename, group_id, ::GroupID::Invalid(), text);
}
/* static */ std::optional<std::string> ScriptGroup::GetName(GroupID group_id)
{
if (!IsValidGroup(group_id)) return std::nullopt;
::SetDParam(0, group_id);
return GetString(STR_GROUP_NAME);
return ::StrMakeValid(::GetString(STR_GROUP_NAME, group_id));
}
/* static */ bool ScriptGroup::SetParent(GroupID group_id, GroupID parent_group_id)
@@ -85,12 +85,12 @@
return ScriptObject::Command<CMD_ALTER_GROUP>::Do(AlterGroupMode::SetParent, group_id, parent_group_id, {});
}
/* static */ ScriptGroup::GroupID ScriptGroup::GetParent(GroupID group_id)
/* static */ GroupID ScriptGroup::GetParent(GroupID group_id)
{
EnforcePrecondition((ScriptGroup::GroupID)INVALID_GROUP, IsValidGroup(group_id));
EnforcePrecondition(::GroupID::Invalid(), IsValidGroup(group_id));
const Group *g = ::Group::GetIfValid(group_id);
return (ScriptGroup::GroupID)g->parent;
const Group *g = ::Group::Get(group_id);
return g->parent;
}
/* static */ bool ScriptGroup::EnableAutoReplaceProtection(GroupID group_id, bool enable)
@@ -98,14 +98,14 @@
EnforceCompanyModeValid(false);
EnforcePrecondition(false, IsValidGroup(group_id));
return ScriptObject::Command<CMD_SET_GROUP_FLAG>::Do(group_id, GroupFlags::GF_REPLACE_PROTECTION, enable, false);
return ScriptObject::Command<CMD_SET_GROUP_FLAG>::Do(group_id, GroupFlag::ReplaceProtection, enable, false);
}
/* static */ bool ScriptGroup::GetAutoReplaceProtection(GroupID group_id)
{
if (!IsValidGroup(group_id)) return false;
return HasBit(::Group::Get(group_id)->flags, GroupFlags::GF_REPLACE_PROTECTION);
return ::Group::Get(group_id)->flags.Test(GroupFlag::ReplaceProtection);
}
/* static */ SQInteger ScriptGroup::GetNumEngines(GroupID group_id, EngineID engine_id)
@@ -163,8 +163,8 @@
/* 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;
EnforceCompanyModeValid(::EngineID::Invalid());
if (!IsValidGroup(group_id) && group_id != GROUP_DEFAULT && group_id != GROUP_ALL) return ::EngineID::Invalid();
return ::EngineReplacementForCompany(Company::Get(ScriptObject::GetCompany()), engine_id, group_id);
}
@@ -174,7 +174,7 @@
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);
return ScriptObject::Command<CMD_SET_AUTOREPLACE>::Do(group_id, engine_id, ::EngineID::Invalid(), false);
}
/* static */ Money ScriptGroup::GetProfitThisYear(GroupID group_id)
@@ -240,7 +240,7 @@
{
EnforcePrecondition(ScriptCompany::Colours::COLOUR_INVALID, IsValidGroup(group_id));
const Group *g = ::Group::GetIfValid(group_id);
const Group *g = ::Group::Get(group_id);
if (!HasBit(g->livery.in_use, 0)) return ScriptCompany::Colours::COLOUR_INVALID;
return (ScriptCompany::Colours)g->livery.colour1;
}
@@ -249,7 +249,7 @@
{
EnforcePrecondition(ScriptCompany::Colours::COLOUR_INVALID, IsValidGroup(group_id));
const Group *g = ::Group::GetIfValid(group_id);
const Group *g = ::Group::Get(group_id);
if (!HasBit(g->livery.in_use, 1)) return ScriptCompany::Colours::COLOUR_INVALID;
return (ScriptCompany::Colours)g->livery.colour2;
}

View File

@@ -19,15 +19,9 @@
*/
class ScriptGroup : public ScriptObject {
public:
/**
* The group IDs of some special groups.
*/
enum GroupID {
/* Note: these values represent part of the in-game static values */
GROUP_ALL = ::ALL_GROUP, ///< All vehicles are in this group.
GROUP_DEFAULT = ::DEFAULT_GROUP, ///< Vehicles not put in any other group are in this one.
GROUP_INVALID = ::INVALID_GROUP, ///< An invalid group id.
};
static constexpr GroupID GROUP_ALL = ::ALL_GROUP; ///< All vehicles are in this group.
static constexpr GroupID GROUP_DEFAULT = ::DEFAULT_GROUP; ///< Vehicles not put in any other group are in this one.
static constexpr GroupID GROUP_INVALID = ::GroupID::Invalid(); ///< An invalid group id.
/**
* Checks whether the given group is valid.

View File

@@ -17,7 +17,7 @@
ScriptGroupList::ScriptGroupList(HSQUIRRELVM vm)
{
EnforceCompanyModeValid_Void();
CompanyID owner = ScriptObject::GetCompany();
::CompanyID owner = ScriptObject::GetCompany();
ScriptList::FillList<Group>(vm, this,
[owner](const Group *g) { return g->owner == owner; }
);

View File

@@ -7,9 +7,27 @@
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
#include "../script_fatalerror.hpp"
${SQUIRREL_INCLUDES}
static SQInteger ${APIUC}ObjectConstructor(HSQUIRRELVM vm)
{
return sq_throwerror(vm, "${APIUC}Object is not instantiable");
}
static SQInteger ${APIUC}ObjectCloned(HSQUIRRELVM)
{
throw Script_FatalError("This instance is not cloneable");
}
void SQ${APIUC}_RegisterAll(Squirrel *engine)
{
DefSQClass<ScriptObject, ScriptType::${APIUC}> SQ${APIUC}Object("${APIUC}Object");
SQ${APIUC}Object.PreRegister(engine);
SQ${APIUC}Object.DefSQAdvancedStaticMethod(engine, &${APIUC}ObjectConstructor, "constructor");
SQ${APIUC}Object.DefSQAdvancedStaticMethod(engine, &${APIUC}ObjectCloned, "_cloned");
SQ${APIUC}Object.PostRegister(engine);
${SQUIRREL_REGISTER}
}

View File

@@ -21,6 +21,7 @@
#include "../../newgrf_industries.h"
#include "../../industry_cmd.h"
#include "../../timer/timer_game_calendar.h"
#include "table/strings.h"
#include "../../safeguards.h"
@@ -37,7 +38,7 @@
/* static */ IndustryID ScriptIndustry::GetIndustryID(TileIndex tile)
{
if (!::IsValidTile(tile) || !::IsTileType(tile, MP_INDUSTRY)) return INVALID_INDUSTRY;
if (!::IsValidTile(tile) || !::IsTileType(tile, MP_INDUSTRY)) return IndustryID::Invalid();
return ::GetIndustryIndex(tile);
}
@@ -45,8 +46,7 @@
{
if (!IsValidIndustry(industry_id)) return std::nullopt;
::SetDParam(0, industry_id);
return GetString(STR_INDUSTRY_NAME);
return ::StrMakeValid(::GetString(STR_INDUSTRY_NAME, industry_id));
}
/* static */ ScriptDate::Date ScriptIndustry::GetConstructionDate(IndustryID industry_id)
@@ -63,70 +63,70 @@
EnforceDeityMode(false);
EnforcePrecondition(false, IsValidIndustry(industry_id));
return ScriptObject::Command<CMD_INDUSTRY_SET_TEXT>::Do(industry_id, text != nullptr ? text->GetEncodedText() : std::string{});
return ScriptObject::Command<CMD_INDUSTRY_SET_TEXT>::Do(industry_id, text != nullptr ? text->GetEncodedText() : EncodedString{});
}
/* static */ ScriptIndustry::CargoAcceptState ScriptIndustry::IsCargoAccepted(IndustryID industry_id, CargoID cargo_id)
/* static */ ScriptIndustry::CargoAcceptState ScriptIndustry::IsCargoAccepted(IndustryID industry_id, CargoType cargo_type)
{
if (!IsValidIndustry(industry_id)) return CAS_NOT_ACCEPTED;
if (!ScriptCargo::IsValidCargo(cargo_id)) return CAS_NOT_ACCEPTED;
if (!ScriptCargo::IsValidCargo(cargo_type)) return CAS_NOT_ACCEPTED;
/* Not const because IndustryTemporarilyRefusesCargo tests a callback which needs a non-const object. */
Industry *i = ::Industry::Get(industry_id);
if (!i->IsCargoAccepted(cargo_id)) return CAS_NOT_ACCEPTED;
if (IndustryTemporarilyRefusesCargo(i, cargo_id)) return CAS_TEMP_REFUSED;
if (!i->IsCargoAccepted(cargo_type)) return CAS_NOT_ACCEPTED;
if (IndustryTemporarilyRefusesCargo(i, cargo_type)) return CAS_TEMP_REFUSED;
return CAS_ACCEPTED;
}
/* static */ SQInteger ScriptIndustry::GetStockpiledCargo(IndustryID industry_id, CargoID cargo_id)
/* static */ SQInteger ScriptIndustry::GetStockpiledCargo(IndustryID industry_id, CargoType cargo_type)
{
if (!IsValidIndustry(industry_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo_type)) return -1;
const Industry *i = ::Industry::Get(industry_id);
auto it = i->GetCargoAccepted(cargo_id);
auto it = i->GetCargoAccepted(cargo_type);
if (it == std::end(i->accepted)) return -1;
return it->waiting;
}
/* static */ SQInteger ScriptIndustry::GetLastMonthProduction(IndustryID industry_id, CargoID cargo_id)
/* static */ SQInteger ScriptIndustry::GetLastMonthProduction(IndustryID industry_id, CargoType cargo_type)
{
if (!IsValidIndustry(industry_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo_type)) return -1;
const Industry *i = ::Industry::Get(industry_id);
auto it = i->GetCargoProduced(cargo_id);
auto it = i->GetCargoProduced(cargo_type);
if (it == std::end(i->produced)) return -1;
return it->history[LAST_MONTH].production;
}
/* static */ SQInteger ScriptIndustry::GetLastMonthTransported(IndustryID industry_id, CargoID cargo_id)
/* static */ SQInteger ScriptIndustry::GetLastMonthTransported(IndustryID industry_id, CargoType cargo_type)
{
if (!IsValidIndustry(industry_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo_type)) return -1;
const Industry *i = ::Industry::Get(industry_id);
auto it = i->GetCargoProduced(cargo_id);
auto it = i->GetCargoProduced(cargo_type);
if (it == std::end(i->produced)) return -1;
return it->history[LAST_MONTH].transported;
}
/* static */ SQInteger ScriptIndustry::GetLastMonthTransportedPercentage(IndustryID industry_id, CargoID cargo_id)
/* static */ SQInteger ScriptIndustry::GetLastMonthTransportedPercentage(IndustryID industry_id, CargoType cargo_type)
{
if (!IsValidIndustry(industry_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo_type)) return -1;
const Industry *i = ::Industry::Get(industry_id);
auto it = i->GetCargoProduced(cargo_id);
auto it = i->GetCargoProduced(cargo_type);
if (it == std::end(i->produced)) return -1;
return ::ToPercent8(it->history[LAST_MONTH].PctTransported());
@@ -165,14 +165,14 @@
{
if (!IsValidIndustry(industry_id)) return false;
return (::GetIndustrySpec(::Industry::Get(industry_id)->type)->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0;
return ::GetIndustrySpec(::Industry::Get(industry_id)->type)->behaviour.Test(IndustryBehaviour::BuiltOnWater);
}
/* static */ bool ScriptIndustry::HasHeliport(IndustryID industry_id)
{
if (!IsValidIndustry(industry_id)) return false;
return (::GetIndustrySpec(::Industry::Get(industry_id)->type)->behaviour & INDUSTRYBEH_AI_AIRSHIP_ROUTES) != 0;
return ::GetIndustrySpec(::Industry::Get(industry_id)->type)->behaviour.Test(IndustryBehaviour::AIAirShipRoutes);
}
/* static */ TileIndex ScriptIndustry::GetHeliportLocation(IndustryID industry_id)
@@ -194,7 +194,7 @@
{
if (!IsValidIndustry(industry_id)) return false;
return (::GetIndustrySpec(::Industry::Get(industry_id)->type)->behaviour & INDUSTRYBEH_AI_AIRSHIP_ROUTES) != 0;
return ::GetIndustrySpec(::Industry::Get(industry_id)->type)->behaviour.Test(IndustryBehaviour::AIAirShipRoutes);
}
/* static */ TileIndex ScriptIndustry::GetDockLocation(IndustryID industry_id)
@@ -214,7 +214,7 @@
/* static */ IndustryType ScriptIndustry::GetIndustryType(IndustryID industry_id)
{
if (!IsValidIndustry(industry_id)) return INVALID_INDUSTRYTYPE;
if (!IsValidIndustry(industry_id)) return IT_INVALID;
return ::Industry::Get(industry_id)->type;
}
@@ -226,12 +226,12 @@
return i->last_prod_year.base();
}
/* static */ ScriptDate::Date ScriptIndustry::GetCargoLastAcceptedDate(IndustryID industry_id, CargoID cargo_type)
/* static */ ScriptDate::Date ScriptIndustry::GetCargoLastAcceptedDate(IndustryID industry_id, CargoType cargo_type)
{
const Industry *i = Industry::GetIfValid(industry_id);
if (i == nullptr) return ScriptDate::DATE_INVALID;
if (!::IsValidCargoID(cargo_type)) {
if (!::IsValidCargoType(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 {
@@ -245,7 +245,7 @@
{
const Industry *i = Industry::GetIfValid(industry_id);
if (i == nullptr) return 0;
return i->ctlflags;
return i->ctlflags.base();
}
/* static */ bool ScriptIndustry::SetControlFlags(IndustryID industry_id, SQInteger control_flags)
@@ -253,7 +253,7 @@
EnforceDeityMode(false);
if (!IsValidIndustry(industry_id)) return false;
return ScriptObject::Command<CMD_INDUSTRY_SET_FLAGS>::Do(industry_id, (::IndustryControlFlags)control_flags & ::INDCTL_MASK);
return ScriptObject::Command<CMD_INDUSTRY_SET_FLAGS>::Do(industry_id, ::IndustryControlFlags(control_flags));
}
/* static */ ScriptCompany::CompanyID ScriptIndustry::GetExclusiveSupplier(IndustryID industry_id)
@@ -263,7 +263,7 @@
auto company_id = ::Industry::Get(industry_id)->exclusive_supplier;
if (!::Company::IsValidID(company_id)) return ScriptCompany::COMPANY_INVALID;
return (ScriptCompany::CompanyID)((uint8_t)company_id);
return ScriptCompany::ToScriptCompanyID(company_id);
}
/* static */ bool ScriptIndustry::SetExclusiveSupplier(IndustryID industry_id, ScriptCompany::CompanyID company_id)
@@ -283,7 +283,7 @@
auto company_id = ::Industry::Get(industry_id)->exclusive_consumer;
if (!::Company::IsValidID(company_id)) return ScriptCompany::COMPANY_INVALID;
return (ScriptCompany::CompanyID)((uint8_t)company_id);
return ScriptCompany::ToScriptCompanyID(company_id);
}
/* static */ bool ScriptIndustry::SetExclusiveConsumer(IndustryID industry_id, ScriptCompany::CompanyID company_id)
@@ -311,5 +311,5 @@
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{});
return ScriptObject::Command<CMD_INDUSTRY_SET_PRODUCTION>::Do(industry_id, prod_level, show_news, custom_news != nullptr ? custom_news->GetEncodedText() : EncodedString{});
}

View File

@@ -23,9 +23,9 @@ class ScriptIndustry : public ScriptObject {
public:
/** Ways for an industry to accept a cargo. */
enum CargoAcceptState {
CAS_NOT_ACCEPTED, ///< The CargoID is not accepted by this industry.
CAS_ACCEPTED, ///< The industry currently accepts this CargoID.
CAS_TEMP_REFUSED, ///< The industry temporarily refuses to accept this CargoID but may do so again in the future.
CAS_NOT_ACCEPTED, ///< The CargoType is not accepted by this industry.
CAS_ACCEPTED, ///< The industry currently accepts this CargoType.
CAS_TEMP_REFUSED, ///< The industry temporarily refuses to accept this CargoType but may do so again in the future.
};
/**
@@ -37,20 +37,20 @@ public:
* When industry production change is evaluated, rolls to decrease are ignored.
* This also prevents industry closure due to production dropping to the lowest level.
*/
INDCTL_NO_PRODUCTION_DECREASE = ::INDCTL_NO_PRODUCTION_DECREASE,
INDCTL_NO_PRODUCTION_DECREASE = ::IndustryControlFlags{::IndustryControlFlag::NoProductionDecrease}.base(),
/**
* When industry production change is evaluated, rolls to increase are ignored.
*/
INDCTL_NO_PRODUCTION_INCREASE = ::INDCTL_NO_PRODUCTION_INCREASE,
INDCTL_NO_PRODUCTION_INCREASE = ::IndustryControlFlags{::IndustryControlFlag::NoProductionIncrease}.base(),
/**
* Industry can not close regardless of production level or time since last delivery.
* This does not prevent a closure already announced.
*/
INDCTL_NO_CLOSURE = ::INDCTL_NO_CLOSURE,
INDCTL_NO_CLOSURE = ::IndustryControlFlags{::IndustryControlFlag::NoClosure}.base(),
/**
* Indicates that the production level of the industry is controlled by a game script.
*/
INDCTL_EXTERNAL_PROD_LEVEL = ::INDCTL_EXTERNAL_PROD_LEVEL,
INDCTL_EXTERNAL_PROD_LEVEL = ::IndustryControlFlags{::IndustryControlFlag::ExternalProdLevel}.base(),
};
/**
@@ -109,55 +109,55 @@ public:
/**
* See whether an industry currently accepts a certain cargo.
* @param industry_id The index of the industry.
* @param cargo_id The index of the cargo.
* @param cargo_type The index of the cargo.
* @pre IsValidIndustry(industry_id).
* @pre ScriptCargo::IsValidCargo(cargo_id).
* @pre ScriptCargo::IsValidCargo(cargo_type).
* @return Whether the industry accepts, temporarily refuses or never accepts this cargo.
*/
static CargoAcceptState IsCargoAccepted(IndustryID industry_id, CargoID cargo_id);
static CargoAcceptState IsCargoAccepted(IndustryID industry_id, CargoType cargo_type);
/**
* Get the amount of cargo stockpiled for processing.
* @param industry_id The index of the industry.
* @param cargo_id The index of the cargo.
* @param cargo_type The index of the cargo.
* @pre IsValidIndustry(industry_id).
* @pre ScriptCargo::IsValidCargo(cargo_id).
* @pre ScriptCargo::IsValidCargo(cargo_type).
* @return The amount of cargo that is waiting for processing.
*/
static SQInteger GetStockpiledCargo(IndustryID industry_id, CargoID cargo_id);
static SQInteger GetStockpiledCargo(IndustryID industry_id, CargoType cargo_type);
/**
* Get the total last economy-month's production of the given cargo at an industry.
* @param industry_id The index of the industry.
* @param cargo_id The index of the cargo.
* @param cargo_type The index of the cargo.
* @pre IsValidIndustry(industry_id).
* @pre ScriptCargo::IsValidCargo(cargo_id).
* @pre ScriptCargo::IsValidCargo(cargo_type).
* @return The last economy-month's production of the given cargo for this industry.
* @see \ref ScriptEconomyTime
*/
static SQInteger GetLastMonthProduction(IndustryID industry_id, CargoID cargo_id);
static SQInteger GetLastMonthProduction(IndustryID industry_id, CargoType cargo_type);
/**
* Get the total amount of cargo transported from an industry last economy-month.
* @param industry_id The index of the industry.
* @param cargo_id The index of the cargo.
* @param cargo_type The index of the cargo.
* @pre IsValidIndustry(industry_id).
* @pre ScriptCargo::IsValidCargo(cargo_id).
* @pre ScriptCargo::IsValidCargo(cargo_type).
* @return The amount of given cargo transported from this industry last economy-month.
* @see \ref ScriptEconomyTime
*/
static SQInteger GetLastMonthTransported(IndustryID industry_id, CargoID cargo_id);
static SQInteger GetLastMonthTransported(IndustryID industry_id, CargoType cargo_type);
/**
* Get the percentage of cargo transported from an industry last economy-month.
* @param industry_id The index of the industry.
* @param cargo_id The index of the cargo.
* @param cargo_type The index of the cargo.
* @pre IsValidIndustry(industry_id).
* @pre ScriptCargo::IsValidCargo(cargo_id).
* @pre ScriptCargo::IsValidCargo(cargo_type).
* @return The percentage of given cargo transported from this industry last economy-month.
* @see \ref ScriptEconomyTime
*/
static SQInteger GetLastMonthTransportedPercentage(IndustryID industry_id, CargoID cargo_id);
static SQInteger GetLastMonthTransportedPercentage(IndustryID industry_id, CargoType cargo_type);
/**
* Gets the location of the industry.
@@ -269,7 +269,7 @@ public:
* @see \ref ScriptEconomyTime
* @api -ai
*/
static ScriptDate::Date GetCargoLastAcceptedDate(IndustryID industry_id, CargoID cargo_type);
static ScriptDate::Date GetCargoLastAcceptedDate(IndustryID industry_id, CargoType cargo_type);
/**
* Get the current control flags for an industry.

View File

@@ -18,16 +18,16 @@ ScriptIndustryList::ScriptIndustryList(HSQUIRRELVM vm)
ScriptList::FillList<Industry>(vm, this);
}
ScriptIndustryList_CargoAccepting::ScriptIndustryList_CargoAccepting(CargoID cargo_id)
ScriptIndustryList_CargoAccepting::ScriptIndustryList_CargoAccepting(CargoType cargo_type)
{
ScriptList::FillList<Industry>(this,
[cargo_id](const Industry *i) { return i->IsCargoAccepted(cargo_id); }
[cargo_type](const Industry *i) { return i->IsCargoAccepted(cargo_type); }
);
}
ScriptIndustryList_CargoProducing::ScriptIndustryList_CargoProducing(CargoID cargo_id)
ScriptIndustryList_CargoProducing::ScriptIndustryList_CargoProducing(CargoType cargo_type)
{
ScriptList::FillList<Industry>(this,
[cargo_id](const Industry *i) { return i->IsCargoProduced(cargo_id); }
[cargo_type](const Industry *i) { return i->IsCargoProduced(cargo_type); }
);
}

View File

@@ -58,9 +58,9 @@ public:
class ScriptIndustryList_CargoAccepting : public ScriptList {
public:
/**
* @param cargo_id The cargo this industry should accept.
* @param cargo_type The cargo this industry should accept.
*/
ScriptIndustryList_CargoAccepting(CargoID cargo_id);
ScriptIndustryList_CargoAccepting(CargoType cargo_type);
};
/**
@@ -72,9 +72,9 @@ public:
class ScriptIndustryList_CargoProducing : public ScriptList {
public:
/**
* @param cargo_id The cargo this industry should produce.
* @param cargo_type The cargo this industry should produce.
*/
ScriptIndustryList_CargoProducing(CargoID cargo_id);
ScriptIndustryList_CargoProducing(CargoType cargo_type);
};
#endif /* SCRIPT_INDUSTRYLIST_HPP */

View File

@@ -45,8 +45,8 @@
{
if (!IsValidIndustryType(industry_type)) return false;
if (_settings_game.game_creation.landscape != LT_TEMPERATE) return true;
return (::GetIndustrySpec(industry_type)->behaviour & INDUSTRYBEH_DONT_INCR_PROD) == 0;
if (_settings_game.game_creation.landscape != LandscapeType::Temperate) return true;
return !::GetIndustrySpec(industry_type)->behaviour.Test(IndustryBehaviour::DontIncrProd);
}
/* static */ Money ScriptIndustryType::GetConstructionCost(IndustryType industry_type)
@@ -61,7 +61,7 @@
{
if (!IsValidIndustryType(industry_type)) return std::nullopt;
return GetString(::GetIndustrySpec(industry_type)->name);
return ::StrMakeValid(::GetString(::GetIndustrySpec(industry_type)->name));
}
/* static */ ScriptList *ScriptIndustryType::GetProducedCargo(IndustryType industry_type)
@@ -71,8 +71,8 @@
const IndustrySpec *ins = ::GetIndustrySpec(industry_type);
ScriptList *list = new ScriptList();
for (const CargoID &c : ins->produced_cargo) {
if (::IsValidCargoID(c)) list->AddItem(c);
for (const CargoType &cargo : ins->produced_cargo) {
if (::IsValidCargoType(cargo)) list->AddItem(cargo);
}
return list;
@@ -85,8 +85,8 @@
const IndustrySpec *ins = ::GetIndustrySpec(industry_type);
ScriptList *list = new ScriptList();
for (const CargoID &c : ins->accepts_cargo) {
if (::IsValidCargoID(c)) list->AddItem(c);
for (const CargoType &cargo : ins->accepts_cargo) {
if (::IsValidCargoType(cargo)) list->AddItem(cargo);
}
return list;
@@ -134,34 +134,34 @@
EnforcePrecondition(false, CanProspectIndustry(industry_type));
uint32_t seed = ScriptBase::Rand();
return ScriptObject::Command<CMD_BUILD_INDUSTRY>::Do(0, industry_type, 0, false, seed);
return ScriptObject::Command<CMD_BUILD_INDUSTRY>::Do(TileIndex{}, industry_type, 0, false, seed);
}
/* static */ bool ScriptIndustryType::IsBuiltOnWater(IndustryType industry_type)
{
if (!IsValidIndustryType(industry_type)) return false;
return (::GetIndustrySpec(industry_type)->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0;
return ::GetIndustrySpec(industry_type)->behaviour.Test(IndustryBehaviour::BuiltOnWater);
}
/* static */ bool ScriptIndustryType::HasHeliport(IndustryType industry_type)
{
if (!IsValidIndustryType(industry_type)) return false;
return (::GetIndustrySpec(industry_type)->behaviour & INDUSTRYBEH_AI_AIRSHIP_ROUTES) != 0;
return ::GetIndustrySpec(industry_type)->behaviour.Test(IndustryBehaviour::AIAirShipRoutes);
}
/* static */ bool ScriptIndustryType::HasDock(IndustryType industry_type)
{
if (!IsValidIndustryType(industry_type)) return false;
return (::GetIndustrySpec(industry_type)->behaviour & INDUSTRYBEH_AI_AIRSHIP_ROUTES) != 0;
return ::GetIndustrySpec(industry_type)->behaviour.Test(IndustryBehaviour::AIAirShipRoutes);
}
/* static */ IndustryType ScriptIndustryType::ResolveNewGRFID(SQInteger grfid, SQInteger grf_local_id)
{
EnforcePrecondition(INVALID_INDUSTRYTYPE, IsInsideBS(grf_local_id, 0x00, NUM_INDUSTRYTYPES_PER_GRF));
EnforcePrecondition(IT_INVALID, IsInsideBS(grf_local_id, 0x00, NUM_INDUSTRYTYPES_PER_GRF));
grfid = BSWAP32(GB(grfid, 0, 32)); // Match people's expectations.
grfid = std::byteswap(GB(grfid, 0, 32)); // Match people's expectations.
return _industry_mngr.GetID(grf_local_id, grfid);
}

View File

@@ -11,6 +11,7 @@
#define SCRIPT_INDUSTRYTYPE_HPP
#include "script_list.hpp"
#include "../../industry_type.h"
/**
* Class that handles all industry-type related functions.
@@ -42,22 +43,22 @@ public:
static std::optional<std::string> GetName(IndustryType industry_type);
/**
* Get a list of CargoID possible produced by this industry-type.
* Get a list of CargoType possible produced by this industry-type.
* @warning This function only returns the default cargoes of the industry type.
* Industries can specify new cargotypes on construction.
* @param industry_type The type to get the CargoIDs for.
* @param industry_type The type to get the CargoTypes for.
* @pre IsValidIndustryType(industry_type).
* @return The CargoIDs of all cargotypes this industry could produce.
* @return The CargoTypes of all cargotypes this industry could produce.
*/
static ScriptList *GetProducedCargo(IndustryType industry_type);
/**
* Get a list of CargoID accepted by this industry-type.
* Get a list of CargoType accepted by this industry-type.
* @warning This function only returns the default cargoes of the industry type.
* Industries can specify new cargotypes on construction.
* @param industry_type The type to get the CargoIDs for.
* @param industry_type The type to get the CargoTypes for.
* @pre IsValidIndustryType(industry_type).
* @return The CargoIDs of all cargotypes this industry accepts.
* @return The CargoTypes of all cargotypes this industry accepts.
*/
static ScriptList *GetAcceptedCargo(IndustryType industry_type);

View File

@@ -23,7 +23,7 @@
company = ScriptCompany::ResolveCompanyID(company);
if (company == ScriptCompany::COMPANY_INVALID || (::RailType)railtype >= RAILTYPE_END) return 0;
return ::Company::Get((::CompanyID)company)->infrastructure.rail[railtype];
return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->infrastructure.rail[railtype];
}
/* static */ SQInteger ScriptInfrastructure::GetRoadPieceCount(ScriptCompany::CompanyID company, ScriptRoad::RoadType roadtype)
@@ -31,7 +31,7 @@
company = ScriptCompany::ResolveCompanyID(company);
if (company == ScriptCompany::COMPANY_INVALID || (::RoadType)roadtype >= ROADTYPE_END) return 0;
return ::Company::Get((::CompanyID)company)->infrastructure.road[roadtype];
return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->infrastructure.road[roadtype];
}
/* static */ SQInteger ScriptInfrastructure::GetInfrastructurePieceCount(ScriptCompany::CompanyID company, Infrastructure infra_type)
@@ -39,7 +39,7 @@
company = ScriptCompany::ResolveCompanyID(company);
if (company == ScriptCompany::COMPANY_INVALID) return 0;
const ::Company *c = ::Company::Get((::CompanyID)company);
const ::Company *c = ::Company::Get(ScriptCompany::FromScriptCompanyID(company));
switch (infra_type) {
case INFRASTRUCTURE_RAIL:
return c->infrastructure.GetRailTotal();
@@ -69,7 +69,7 @@
company = ScriptCompany::ResolveCompanyID(company);
if (company == ScriptCompany::COMPANY_INVALID || (::RailType)railtype >= RAILTYPE_END || !_settings_game.economy.infrastructure_maintenance) return 0;
const ::Company *c = ::Company::Get((::CompanyID)company);
const ::Company *c = ::Company::Get(ScriptCompany::FromScriptCompanyID(company));
return ::RailMaintenanceCost((::RailType)railtype, c->infrastructure.rail[railtype], c->infrastructure.GetRailTotal());
}
@@ -78,7 +78,7 @@
company = ScriptCompany::ResolveCompanyID(company);
if (company == ScriptCompany::COMPANY_INVALID || (::RoadType)roadtype >= ROADTYPE_END || !_settings_game.economy.infrastructure_maintenance) return 0;
const ::Company *c = ::Company::Get((::CompanyID)company);
const ::Company *c = ::Company::Get(ScriptCompany::FromScriptCompanyID(company));
return ::RoadMaintenanceCost((::RoadType)roadtype, c->infrastructure.road[roadtype], RoadTypeIsRoad((::RoadType)roadtype) ? c->infrastructure.GetRoadTotal() : c->infrastructure.GetTramTotal());
}
@@ -87,7 +87,7 @@
company = ScriptCompany::ResolveCompanyID(company);
if (company == ScriptCompany::COMPANY_INVALID || !_settings_game.economy.infrastructure_maintenance) return 0;
const ::Company *c = ::Company::Get((::CompanyID)company);
const ::Company *c = ::Company::Get(ScriptCompany::FromScriptCompanyID(company));
switch (infra_type) {
case INFRASTRUCTURE_RAIL: {
Money cost;

View File

@@ -24,7 +24,7 @@
return ::LeagueTable::IsValidID(table_id);
}
/* static */ ScriptLeagueTable::LeagueTableID ScriptLeagueTable::New(Text *title, Text *header, Text *footer)
/* static */ LeagueTableID ScriptLeagueTable::New(Text *title, Text *header, Text *footer)
{
ScriptObjectRef title_counter(title);
ScriptObjectRef header_counter(header);
@@ -32,16 +32,16 @@
EnforceDeityMode(LEAGUE_TABLE_INVALID);
EnforcePrecondition(LEAGUE_TABLE_INVALID, title != nullptr);
std::string encoded_title = title->GetEncodedText();
EncodedString encoded_title = title->GetEncodedText();
EnforcePreconditionEncodedText(LEAGUE_TABLE_INVALID, encoded_title);
std::string encoded_header = (header != nullptr ? header->GetEncodedText() : std::string{});
std::string encoded_footer = (footer != nullptr ? footer->GetEncodedText() : std::string{});
EncodedString encoded_header = (header != nullptr ? header->GetEncodedText() : EncodedString{});
EncodedString encoded_footer = (footer != nullptr ? footer->GetEncodedText() : EncodedString{});
if (!ScriptObject::Command<CMD_CREATE_LEAGUE_TABLE>::Do(&ScriptInstance::DoCommandReturnLeagueTableID, encoded_title, encoded_header, encoded_footer)) return LEAGUE_TABLE_INVALID;
/* In case of test-mode, we return LeagueTableID 0 */
return (ScriptLeagueTable::LeagueTableID)0;
return LeagueTableID::Begin();
}
/* static */ bool ScriptLeagueTable::IsValidLeagueTableElement(LeagueTableElementID element_id)
@@ -49,7 +49,7 @@
return ::LeagueTableElement::IsValidID(element_id);
}
/* static */ ScriptLeagueTable::LeagueTableElementID ScriptLeagueTable::NewElement(ScriptLeagueTable::LeagueTableID table, SQInteger rating, ScriptCompany::CompanyID company, Text *text, Text *score, LinkType link_type, SQInteger link_target)
/* static */ LeagueTableElementID ScriptLeagueTable::NewElement(LeagueTableID table, SQInteger rating, ScriptCompany::CompanyID company, Text *text, Text *score, LinkType link_type, SQInteger link_target)
{
ScriptObjectRef text_counter(text);
ScriptObjectRef score_counter(score);
@@ -59,15 +59,14 @@
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, IsValidLeagueTable(table));
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID);
CompanyID c = (::CompanyID)company;
if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY;
::CompanyID c = ScriptCompany::FromScriptCompanyID(company);
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, text != nullptr);
std::string encoded_text = text->GetEncodedText();
EncodedString encoded_text = text->GetEncodedText();
EnforcePreconditionEncodedText(LEAGUE_TABLE_ELEMENT_INVALID, encoded_text);
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, score != nullptr);
std::string encoded_score = score->GetEncodedText();
EncodedString encoded_score = score->GetEncodedText();
EnforcePreconditionEncodedText(LEAGUE_TABLE_ELEMENT_INVALID, encoded_score);
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, IsValidLink(Link((::LinkType)link_type, link_target)));
@@ -75,7 +74,7 @@
if (!ScriptObject::Command<CMD_CREATE_LEAGUE_TABLE_ELEMENT>::Do(&ScriptInstance::DoCommandReturnLeagueTableElementID, table, rating, c, encoded_text, encoded_score, (::LinkType)link_type, (::LinkTargetID)link_target)) return LEAGUE_TABLE_ELEMENT_INVALID;
/* In case of test-mode, we return LeagueTableElementID 0 */
return (ScriptLeagueTable::LeagueTableElementID)0;
return LeagueTableElementID::Begin();
}
/* static */ bool ScriptLeagueTable::UpdateElementData(LeagueTableElementID element, ScriptCompany::CompanyID company, Text *text, LinkType link_type, SQInteger link_target)
@@ -86,11 +85,10 @@
EnforcePrecondition(false, IsValidLeagueTableElement(element));
EnforcePrecondition(false, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID);
CompanyID c = (::CompanyID)company;
if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY;
::CompanyID c = ScriptCompany::FromScriptCompanyID(company);
EnforcePrecondition(false, text != nullptr);
std::string encoded_text = text->GetEncodedText();
EncodedString encoded_text = text->GetEncodedText();
EnforcePreconditionEncodedText(false, encoded_text);
EnforcePrecondition(false, IsValidLink(Link((::LinkType)link_type, link_target)));
@@ -106,7 +104,7 @@
EnforcePrecondition(false, IsValidLeagueTableElement(element));
EnforcePrecondition(false, score != nullptr);
std::string encoded_score = score->GetEncodedText();
EncodedString encoded_score = score->GetEncodedText();
EnforcePreconditionEncodedText(false, encoded_score);
return ScriptObject::Command<CMD_UPDATE_LEAGUE_TABLE_ELEMENT_SCORE>::Do(element, rating, encoded_score);

View File

@@ -25,19 +25,9 @@
*/
class ScriptLeagueTable : public ScriptObject {
public:
/**
* The league table IDs.
*/
enum LeagueTableID {
LEAGUE_TABLE_INVALID = ::INVALID_LEAGUE_TABLE, ///< An invalid league table id.
};
static constexpr LeagueTableID LEAGUE_TABLE_INVALID = ::LeagueTableID::Invalid(); ///< An invalid league table id.
/**
* The league table element IDs.
*/
enum LeagueTableElementID {
LEAGUE_TABLE_ELEMENT_INVALID = ::INVALID_LEAGUE_TABLE_ELEMENT, ///< An invalid league table element id.
};
static constexpr LeagueTableElementID LEAGUE_TABLE_ELEMENT_INVALID = ::LeagueTableElementID::Invalid(); ///< An invalid league table element id.
/**
* The type of a link.
@@ -80,7 +70,7 @@ public:
* Create a new league table element.
* @param table Id of the league table this element belongs to.
* @param rating Value that elements are ordered by.
* @param company Company to show the color blob for or INVALID_COMPANY.
* @param company Company to show the color blob for or COMPANY_INVALID.
* @param text Text of the element (can be either a raw string, or ScriptText object).
* @param score String representation of the score associated with the element (can be either a raw string, or ScriptText object).
* @param link_type Type of the referenced object.
@@ -97,7 +87,7 @@ public:
/**
* Update the attributes of a league table element.
* @param element Id of the element to update
* @param company Company to show the color blob for or INVALID_COMPANY.
* @param company Company to show the color blob for or COMPANY_INVALID.
* @param text Text of the element (can be either a raw string, or ScriptText object).
* @param link_type Type of the referenced object.
* @param link_target Id of the referenced object.

View File

@@ -403,10 +403,60 @@ public:
bool ScriptList::SaveObject(HSQUIRRELVM vm)
{
sq_pushstring(vm, "List");
sq_newarray(vm, 0);
sq_pushinteger(vm, this->sorter_type);
sq_arrayappend(vm, -2);
sq_pushbool(vm, this->sort_ascending ? SQTrue : SQFalse);
sq_arrayappend(vm, -2);
sq_newtable(vm);
for (ScriptListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
sq_pushinteger(vm, iter->first);
sq_pushinteger(vm, iter->second);
sq_rawset(vm, -3);
}
sq_arrayappend(vm, -2);
return true;
}
bool ScriptList::LoadObject(HSQUIRRELVM vm)
{
if (sq_gettype(vm, -1) != OT_ARRAY) return false;
sq_pushnull(vm);
if (SQ_FAILED(sq_next(vm, -2))) return false;
if (sq_gettype(vm, -1) != OT_INTEGER) return false;
SQInteger type;
sq_getinteger(vm, -1, &type);
sq_pop(vm, 2);
if (SQ_FAILED(sq_next(vm, -2))) return false;
if (sq_gettype(vm, -1) != OT_BOOL) return false;
SQBool order;
sq_getbool(vm, -1, &order);
sq_pop(vm, 2);
if (SQ_FAILED(sq_next(vm, -2))) return false;
if (sq_gettype(vm, -1) != OT_TABLE) return false;
sq_pushnull(vm);
while (SQ_SUCCEEDED(sq_next(vm, -2))) {
if (sq_gettype(vm, -2) != OT_INTEGER && sq_gettype(vm, -1) != OT_INTEGER) return false;
SQInteger key, value;
sq_getinteger(vm, -2, &key);
sq_getinteger(vm, -1, &value);
this->AddItem(key, value);
sq_pop(vm, 2);
}
sq_pop(vm, 3);
if (SQ_SUCCEEDED(sq_next(vm, -2))) return false;
sq_pop(vm, 1);
this->Sort(static_cast<SorterType>(type), order == SQTrue);
return true;
}
ScriptList::ScriptList()
{
/* Default sorter */
this->sorter = new ScriptListSorterValueDescending(this);
this->sorter = std::make_unique<ScriptListSorterValueDescending>(this);
this->sorter_type = SORT_BY_VALUE;
this->sort_ascending = false;
this->initialized = false;
@@ -415,7 +465,6 @@ ScriptList::ScriptList()
ScriptList::~ScriptList()
{
delete this->sorter;
}
bool ScriptList::HasItem(SQInteger item)
@@ -527,21 +576,20 @@ void ScriptList::Sort(SorterType sorter, bool ascending)
if (sorter != SORT_BY_VALUE && sorter != SORT_BY_ITEM) return;
if (sorter == this->sorter_type && ascending == this->sort_ascending) return;
delete this->sorter;
switch (sorter) {
case SORT_BY_ITEM:
if (ascending) {
this->sorter = new ScriptListSorterItemAscending(this);
this->sorter = std::make_unique<ScriptListSorterItemAscending>(this);
} else {
this->sorter = new ScriptListSorterItemDescending(this);
this->sorter = std::make_unique<ScriptListSorterItemDescending>(this);
}
break;
case SORT_BY_VALUE:
if (ascending) {
this->sorter = new ScriptListSorterValueAscending(this);
this->sorter = std::make_unique<ScriptListSorterValueAscending>(this);
} else {
this->sorter = new ScriptListSorterValueDescending(this);
this->sorter = std::make_unique<ScriptListSorterValueDescending>(this);
}
break;
@@ -576,11 +624,11 @@ void ScriptList::SwapList(ScriptList *list)
this->items.swap(list->items);
this->buckets.swap(list->buckets);
Swap(this->sorter, list->sorter);
Swap(this->sorter_type, list->sorter_type);
Swap(this->sort_ascending, list->sort_ascending);
Swap(this->initialized, list->initialized);
Swap(this->modifications, list->modifications);
std::swap(this->sorter, list->sorter);
std::swap(this->sorter_type, list->sorter_type);
std::swap(this->sort_ascending, list->sort_ascending);
std::swap(this->initialized, list->initialized);
std::swap(this->modifications, list->modifications);
this->sorter->Retarget(this);
list->sorter->Retarget(list);
}

View File

@@ -36,36 +36,42 @@ public:
static const bool SORT_DESCENDING = false;
private:
ScriptListSorter *sorter; ///< Sorting algorithm
std::unique_ptr<ScriptListSorter> sorter; ///< Sorting algorithm
SorterType sorter_type; ///< Sorting type
bool sort_ascending; ///< Whether to sort ascending or descending
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>
/* Temporary helper functions to get the raw index from either strongly and non-strongly typed pool items. */
template <typename T>
static auto GetRawIndex(const T &index) { return index; }
template <ConvertibleThroughBase T>
static auto GetRawIndex(const T &index) { return index.base(); }
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);
list->AddItem(GetRawIndex(item->index));
}
}
template<typename T, class ItemValid>
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>
template <typename T>
static void FillList(ScriptList *list)
{
ScriptList::FillList<T>(list, [](const T *) { return true; });
}
template<typename T, class ItemValid>
template <typename T, class ItemValid>
static void FillList(HSQUIRRELVM vm, ScriptList *list, ItemValid item_valid)
{
int nparam = sq_gettop(vm) - 1;
@@ -99,7 +105,7 @@ protected:
/* 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);
sq_pushinteger(vm, GetRawIndex(item->index));
for (int i = 0; i < nparam - 1; i++) {
sq_push(vm, i + 3);
}
@@ -137,12 +143,15 @@ protected:
ScriptObject::SetAllowDoCommand(backup_allow);
}
template<typename T>
template <typename T>
static void FillList(HSQUIRRELVM vm, ScriptList *list)
{
ScriptList::FillList<T>(vm, list, [](const T *) { return true; });
}
virtual bool SaveObject(HSQUIRRELVM vm) override;
virtual bool LoadObject(HSQUIRRELVM vm) override;
public:
typedef std::set<SQInteger> ScriptItemList; ///< The list of items inside the bucket
typedef std::map<SQInteger, ScriptItemList> ScriptListBucket; ///< The bucket list per value

View File

@@ -10,7 +10,6 @@
#include "../../stdafx.h"
#include "script_log_types.hpp"
#include "script_log.hpp"
#include "../../core/alloc_func.hpp"
#include "../../debug.h"
#include "../../window_func.h"
#include "../../string_func.h"
@@ -57,6 +56,6 @@
}
/* Also still print to debug window */
Debug(script, level, "[{}] [{}] {}", (uint)ScriptObject::GetRootCompany(), logc, line.text);
Debug(script, level, "[{}] [{}] {}", ScriptObject::GetRootCompany(), logc, line.text);
InvalidateWindowClassesData(WC_SCRIPT_DEBUG, ScriptObject::GetRootCompany());
}

View File

@@ -92,7 +92,7 @@
EnforcePrecondition(false, ::IsValidTile(tile));
EnforcePrecondition(false, station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id));
return ScriptObject::Command<CMD_BUILD_DOCK>::Do(tile, ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION, station_id != ScriptStation::STATION_JOIN_ADJACENT);
return ScriptObject::Command<CMD_BUILD_DOCK>::Do(tile, ScriptStation::IsValidStation(station_id) ? station_id : StationID::Invalid(), station_id != ScriptStation::STATION_JOIN_ADJACENT);
}
/* static */ bool ScriptMarine::BuildBuoy(TileIndex tile)

View File

@@ -11,6 +11,7 @@
#define SCRIPT_MARINE_HPP
#include "script_error.hpp"
#include "../../station_type.h"
/**
* Class that handles all marine related functions.

View File

@@ -17,48 +17,36 @@
ScriptNewGRFList::ScriptNewGRFList()
{
for (auto c = _grfconfig; c != nullptr; c = c->next) {
if (!HasBit(c->flags, GCF_STATIC)) {
this->AddItem(BSWAP32(c->ident.grfid));
for (const auto &c : _grfconfig) {
if (!c->flags.Test(GRFConfigFlag::Static)) {
this->AddItem(std::byteswap(c->ident.grfid));
}
}
}
/* static */ bool ScriptNewGRF::IsLoaded(SQInteger grfid)
{
grfid = BSWAP32(GB(grfid, 0, 32)); // Match people's expectations.
grfid = std::byteswap(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 true;
}
}
return false;
return std::ranges::any_of(_grfconfig, [grfid](const auto &c) { return !c->flags.Test(GRFConfigFlag::Static) && c->ident.grfid == grfid; });
}
/* static */ SQInteger ScriptNewGRF::GetVersion(SQInteger grfid)
{
grfid = BSWAP32(GB(grfid, 0, 32)); // Match people's expectations.
grfid = std::byteswap(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 c->version;
}
}
auto it = std::ranges::find_if(_grfconfig, [grfid](const auto &c) { return !c->flags.Test(GRFConfigFlag::Static) && c->ident.grfid == grfid; });
if (it != std::end(_grfconfig)) return (*it)->version;
return 0;
}
/* static */ std::optional<std::string> ScriptNewGRF::GetName(SQInteger grfid)
{
grfid = BSWAP32(GB(grfid, 0, 32)); // Match people's expectations.
grfid = std::byteswap(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 c->GetName();
}
}
auto it = std::ranges::find_if(_grfconfig, [grfid](const auto &c) { return !c->flags.Test(GRFConfigFlag::Static) && c->ident.grfid == grfid; });
if (it != std::end(_grfconfig)) return (*it)->GetName();
return std::nullopt;
}

View File

@@ -20,25 +20,35 @@
#include "../../safeguards.h"
static NewsReference CreateReference(ScriptNews::NewsReferenceType ref_type, SQInteger reference)
{
switch (ref_type) {
case ScriptNews::NR_NONE: return {};
case ScriptNews::NR_TILE: return ::TileIndex(reference);
case ScriptNews::NR_STATION: return static_cast<StationID>(reference);
case ScriptNews::NR_INDUSTRY: return static_cast<IndustryID>(reference);
case ScriptNews::NR_TOWN: return static_cast<TownID>(reference);
default: NOT_REACHED();
}
}
/* static */ bool ScriptNews::Create(NewsType type, Text *text, ScriptCompany::CompanyID company, NewsReferenceType ref_type, SQInteger reference)
{
ScriptObjectRef counter(text);
EnforceDeityMode(false);
EnforcePrecondition(false, text != nullptr);
std::string encoded = text->GetEncodedText();
EncodedString 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);
EnforcePrecondition(false, (ref_type == NR_NONE) ||
(ref_type == NR_TILE && ScriptMap::IsValidTile(reference)) ||
(ref_type == NR_STATION && ScriptStation::IsValidStation(reference)) ||
(ref_type == NR_INDUSTRY && ScriptIndustry::IsValidIndustry(reference)) ||
(ref_type == NR_TOWN && ScriptTown::IsValidTown(reference)));
(ref_type == NR_TILE && ScriptMap::IsValidTile(::TileIndex(reference))) ||
(ref_type == NR_STATION && ScriptStation::IsValidStation(static_cast<StationID>(reference))) ||
(ref_type == NR_INDUSTRY && ScriptIndustry::IsValidIndustry(static_cast<IndustryID>(reference))) ||
(ref_type == NR_TOWN && ScriptTown::IsValidTown(static_cast<TownID>(reference))));
uint8_t c = company;
if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY;
::CompanyID c = ScriptCompany::FromScriptCompanyID(company);
if (ref_type == NR_NONE) reference = 0;
return ScriptObject::Command<CMD_CUSTOM_NEWS_ITEM>::Do((::NewsType)type, (::NewsReferenceType)ref_type, (::CompanyID)c, reference, encoded);
return ScriptObject::Command<CMD_CUSTOM_NEWS_ITEM>::Do((::NewsType)type, c, CreateReference(ref_type, reference), encoded);
}

View File

@@ -24,13 +24,13 @@ public:
*/
enum NewsType {
/* Arbitrary selection of NewsTypes which might make sense for scripts */
NT_ACCIDENT = ::NT_ACCIDENT, ///< Category accidents.
NT_COMPANY_INFO = ::NT_COMPANY_INFO, ///< Category company info.
NT_ECONOMY = ::NT_ECONOMY, ///< Category economy.
NT_ADVICE = ::NT_ADVICE, ///< Category vehicle advice.
NT_ACCEPTANCE = ::NT_ACCEPTANCE, ///< Category acceptance changes.
NT_SUBSIDIES = ::NT_SUBSIDIES, ///< Category subsidies.
NT_GENERAL = ::NT_GENERAL, ///< Category general.
NT_ACCIDENT = to_underlying(::NewsType::Accident), ///< Category accidents.
NT_COMPANY_INFO = to_underlying(::NewsType::CompanyInfo), ///< Category company info.
NT_ECONOMY = to_underlying(::NewsType::Economy), ///< Category economy.
NT_ADVICE = to_underlying(::NewsType::Advice), ///< Category vehicle advice.
NT_ACCEPTANCE = to_underlying(::NewsType::Acceptance), ///< Category acceptance changes.
NT_SUBSIDIES = to_underlying(::NewsType::Subsidies), ///< Category subsidies.
NT_GENERAL = to_underlying(::NewsType::General), ///< Category general.
};
/**
@@ -38,11 +38,11 @@ public:
*/
enum NewsReferenceType {
/* Selection of useful game elements to refer to. */
NR_NONE = ::NR_NONE, ///< No reference supplied.
NR_TILE = ::NR_TILE, ///< Reference location, scroll to the location when clicking on the news.
NR_STATION = ::NR_STATION, ///< Reference station, scroll to the station when clicking on the news. Delete news when the station is deleted.
NR_INDUSTRY = ::NR_INDUSTRY, ///< Reference industry, scrolls to the industry when clicking on the news. Delete news when the industry is deleted.
NR_TOWN = ::NR_TOWN, ///< Reference town, scroll to the town when clicking on the news.
NR_NONE, ///< No reference supplied.
NR_TILE, ///< Reference location, scroll to the location when clicking on the news.
NR_STATION, ///< Reference station, scroll to the station when clicking on the news. Delete news when the station is deleted.
NR_INDUSTRY, ///< Reference industry, scrolls to the industry when clicking on the news. Delete news when the industry is deleted.
NR_TOWN, ///< Reference town, scroll to the town when clicking on the news.
};
/**
@@ -58,7 +58,7 @@ public:
* - For #NR_INDUSTRY this parameter should be a valid industryID (ScriptIndustry::IsValidIndustry).
* - For #NR_TOWN this parameter should be a valid townID (ScriptTown::IsValidTown).
* @return True if the action succeeded.
* @pre type must be #NT_ECONOMY, #NT_SUBSIDIES, or #NT_GENERAL.
* @pre type must be #NewsType::Economy, #NewsType::Subsidies, or #NewsType::General.
* @pre text != null.
* @pre company == COMPANY_INVALID || ResolveCompanyID(company) != COMPANY_INVALID.
* @pre The \a reference condition must be fulfilled.

View File

@@ -215,7 +215,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
return GetStorage()->allow_do_command;
}
/* static */ void ScriptObject::SetCompany(CompanyID company)
/* static */ void ScriptObject::SetCompany(::CompanyID company)
{
if (GetStorage()->root_company == INVALID_OWNER) GetStorage()->root_company = company;
GetStorage()->company = company;
@@ -223,12 +223,12 @@ ScriptObject::ActiveInstance::~ActiveInstance()
_current_company = company;
}
/* static */ CompanyID ScriptObject::GetCompany()
/* static */ ::CompanyID ScriptObject::GetCompany()
{
return GetStorage()->company;
}
/* static */ CompanyID ScriptObject::GetRootCompany()
/* static */ ::CompanyID ScriptObject::GetRootCompany()
{
return GetStorage()->root_company;
}
@@ -249,11 +249,6 @@ ScriptObject::ActiveInstance::~ActiveInstance()
return GetStorage()->log_data;
}
/* static */ std::string ScriptObject::GetString(StringID string)
{
return ::StrMakeValid(::GetString(string));
}
/* static */ void ScriptObject::SetCallbackVariable(int index, int value)
{
if (static_cast<size_t>(index) >= GetStorage()->callback_value.size()) GetStorage()->callback_value.resize(index + 1);
@@ -347,7 +342,7 @@ bool ScriptObject::DoCommandProcessResult(const CommandCost &res, Script_Suspend
}
/* static */ Randomizer ScriptObject::random_states[OWNER_END];
/* static */ ScriptObject::RandomizerArray ScriptObject::random_states;
Randomizer &ScriptObject::GetRandomizer(Owner owner)
{
@@ -357,7 +352,7 @@ Randomizer &ScriptObject::GetRandomizer(Owner owner)
void ScriptObject::InitializeRandomizers()
{
Randomizer random = _random;
for (Owner owner = OWNER_BEGIN; owner < OWNER_END; owner++) {
for (Owner owner = OWNER_BEGIN; owner < OWNER_END; ++owner) {
ScriptObject::GetRandomizer(owner).SetSeed(random.Next());
}
}

View File

@@ -84,6 +84,22 @@ protected:
static ScriptInstance *active; ///< The global current active instance.
};
/**
* Save this object.
* Must push 2 elements on the stack:
* - the name (classname without "Script") of the object (OT_STRING)
* - the data for the object (any supported types)
* @return True iff saving this type is supported.
*/
virtual bool SaveObject(HSQUIRRELVM) { return false; }
/**
* Load this object.
* The data for the object must be pushed on the stack before the call.
* @return True iff loading this type is supported.
*/
virtual bool LoadObject(HSQUIRRELVM) { return false; }
public:
/**
* Store the latest result of a DoCommand per company.
@@ -116,7 +132,7 @@ public:
static void InitializeRandomizers();
protected:
template<Commands TCmd, typename T> struct ScriptDoCommandHelper;
template <Commands TCmd, typename T> struct ScriptDoCommandHelper;
/**
* Templated wrapper that exposes the command parameter arguments
@@ -126,7 +142,7 @@ protected:
* @tparam Targs The command parameter types.
*/
template <Commands Tcmd, typename Tret, typename... Targs>
struct ScriptDoCommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...)> {
struct ScriptDoCommandHelper<Tcmd, Tret(*)(DoCommandFlags, Targs...)> {
static bool Do(Script_SuspendCallbackProc *callback, Targs... args)
{
return Execute(callback, std::forward_as_tuple(args...));
@@ -269,21 +285,21 @@ protected:
* information about.
* @param company The new company.
*/
static void SetCompany(CompanyID company);
static void SetCompany(::CompanyID company);
/**
* Get the current company we are executing commands for or
* requesting information about.
* @return The current company.
*/
static CompanyID GetCompany();
static ::CompanyID GetCompany();
/**
* Get the root company, the company that the script really
* runs under / for.
* @return The root company.
*/
static CompanyID GetRootCompany();
static ::CompanyID GetRootCompany();
/**
* Set the cost of the last command.
@@ -320,17 +336,13 @@ protected:
*/
static ScriptLogTypes::LogData &GetLogData();
/**
* Get an allocated string with all control codes stripped off.
*/
static std::string GetString(StringID string);
private:
/* Helper functions for DoCommand. */
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)
using RandomizerArray = ReferenceThroughBaseContainer<std::array<Randomizer, OWNER_END.base()>>;
static RandomizerArray random_states; ///< Random states for each of the scripts (game script uses OWNER_DEITY)
};
namespace ScriptObjectInternal {
@@ -341,12 +353,12 @@ namespace ScriptObjectInternal {
if constexpr (std::is_same_v<std::string, T>) {
/* The string must be valid, i.e. not contain special codes. Since some
* can be made with GSText, make sure the control codes are removed. */
data = ::StrMakeValid(data, SVS_NONE);
::StrMakeValidInPlace(data, {});
}
}
/** Helper function to perform validation on command data strings. */
template<class Ttuple, size_t... Tindices>
template <class Ttuple, size_t... Tindices>
static inline void SanitizeStringsHelper(Ttuple &values, std::index_sequence<Tindices...>)
{
((SanitizeSingleStringHelper(std::get<Tindices>(values))), ...);
@@ -362,7 +374,7 @@ namespace ScriptObjectInternal {
}
/** Set all invalid ClientID's to the proper value. */
template<class Ttuple, size_t... Tindices>
template <class Ttuple, size_t... Tindices>
static inline void SetClientIds(Ttuple &values, std::index_sequence<Tindices...>)
{
((SetClientIdHelper(std::get<Tindices>(values))), ...);
@@ -377,12 +389,12 @@ namespace ScriptObjectInternal {
}
template <Commands Tcmd, typename Tret, typename... Targs>
bool ScriptObject::ScriptDoCommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...)>::Execute(Script_SuspendCallbackProc *callback, std::tuple<Targs...> args)
bool ScriptObject::ScriptDoCommandHelper<Tcmd, Tret(*)(DoCommandFlags, Targs...)>::Execute(Script_SuspendCallbackProc *callback, std::tuple<Targs...> args)
{
auto [err, estimate_only, asynchronous, networking] = ScriptObject::DoCommandPrep();
if (err) return false;
if ((::GetCommandFlags<Tcmd>() & CMD_STR_CTRL) == 0) {
if (!::GetCommandFlags<Tcmd>().Test(CommandFlag::StrCtrl)) {
ScriptObjectInternal::SanitizeStringsHelper(args, std::index_sequence_for<Targs...>{});
}
@@ -392,16 +404,16 @@ bool ScriptObject::ScriptDoCommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...)>
}
/* Do not even think about executing out-of-bounds tile-commands. */
if (tile != 0 && (tile >= Map::Size() || (!IsValidTile(tile) && (GetCommandFlags<Tcmd>() & CMD_ALL_TILES) == 0))) return false;
if (tile != 0 && (tile >= Map::Size() || (!IsValidTile(tile) && !GetCommandFlags<Tcmd>().Test(CommandFlag::AllTiles)))) 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...>{});
if constexpr (::GetCommandFlags<Tcmd>().Test(CommandFlag::ClientID)) ScriptObjectInternal::SetClientIds(args, std::index_sequence_for<Targs...>{});
/* Store the command for command callback validation. */
if (!estimate_only && networking) ScriptObject::SetLastCommand(EndianBufferWriter<CommandDataBuffer>::FromValue(args), Tcmd);
/* Try to perform the command. */
Tret res = ::Command<Tcmd>::Unsafe((StringID)0, networking ? ScriptObject::GetDoCommandCallback() : nullptr, false, estimate_only, tile, args);
Tret res = ::Command<Tcmd>::Unsafe((StringID)0, (!asynchronous && networking) ? ScriptObject::GetDoCommandCallback() : nullptr, false, estimate_only, tile, args);
if constexpr (std::is_same_v<Tret, CommandCost>) {
return ScriptObject::DoCommandProcessResult(res, callback, estimate_only, asynchronous);

View File

@@ -14,6 +14,7 @@
#include "script_error.hpp"
#include "script_map.hpp"
#include "../../object_cmd.h"
#include "../../strings_func.h"
#include "../../safeguards.h"
@@ -27,7 +28,7 @@
{
EnforcePrecondition(std::nullopt, IsValidObjectType(object_type));
return GetString(ObjectSpec::Get(object_type)->name);
return ::StrMakeValid(::GetString(ObjectSpec::Get(object_type)->name));
}
/* static */ SQInteger ScriptObjectType::GetViews(ObjectType object_type)
@@ -51,6 +52,6 @@
{
EnforcePrecondition(INVALID_OBJECT_TYPE, IsInsideBS(grf_local_id, 0x00, NUM_OBJECTS_PER_GRF));
grfid = BSWAP32(GB(grfid, 0, 32)); // Match people's expectations.
grfid = std::byteswap(GB(grfid, 0, 32)); // Match people's expectations.
return _object_mngr.GetID(grf_local_id, grfid);
}

View File

@@ -46,7 +46,7 @@ public:
/**
* Build an object of the specified type.
* @param object_type The type of the object to build.
* @param view The view for teh object.
* @param view The view for the object.
* @param tile The tile to build the object on.
* @pre IsValidObjectType(object_type).
* @return True if the object was successfully build.

View File

@@ -104,6 +104,23 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
return res;
}
/**
* Convert an order index from OpenTTD to a ScriptOrder::OrderPosition (which is the manual order index)
* @param order_position The OpenTTD-internal index to convert.
* @return An OrderPosition for the same order.
*/
static ScriptOrder::OrderPosition RealOrderPositionToScriptOrderPosition(VehicleID vehicle_id, int order_position)
{
const Order *order = ::Vehicle::Get(vehicle_id)->GetFirstOrder();
assert(order != nullptr);
int num_implicit_orders = 0;
for (int i = 0; i < order_position; i++) {
if (order->GetType() == OT_IMPLICIT) num_implicit_orders++;
order = order->next;
}
return static_cast<ScriptOrder::OrderPosition>(order_position - num_implicit_orders);
}
/* static */ bool ScriptOrder::IsGotoStationOrder(VehicleID vehicle_id, OrderPosition order_position)
{
if (!IsValidVehicleOrder(vehicle_id, order_position)) return false;
@@ -175,16 +192,9 @@ 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++;
order = order->next;
}
int real_order_pos = cur_order_pos - num_implicit_orders;
assert(real_order_pos < num_manual_orders);
return (ScriptOrder::OrderPosition)real_order_pos;
OrderPosition order_pos = ::RealOrderPositionToScriptOrderPosition(vehicle_id, cur_order_pos);
assert(order_pos < num_manual_orders);
return order_pos;
}
return (order_position >= 0 && order_position < num_manual_orders) ? order_position : ORDER_INVALID;
}
@@ -197,12 +207,11 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
case OT_GOTO_STATION:
return (order_flags & ~(OF_NON_STOP_FLAGS | OF_UNLOAD_FLAGS | OF_LOAD_FLAGS)) == 0 &&
/* Test the different mutual exclusive flags. */
((order_flags & OF_TRANSFER) == 0 || (order_flags & OF_UNLOAD) == 0) &&
((order_flags & OF_TRANSFER) == 0 || (order_flags & OF_NO_UNLOAD) == 0) &&
((order_flags & OF_UNLOAD) == 0 || (order_flags & OF_NO_UNLOAD) == 0) &&
((order_flags & OF_UNLOAD) == 0 || (order_flags & OF_NO_UNLOAD) == 0) &&
((order_flags & OF_NO_UNLOAD) == 0 || (order_flags & OF_NO_LOAD) == 0) &&
((order_flags & OF_FULL_LOAD_ANY) == 0 || (order_flags & OF_NO_LOAD) == 0);
HasAtMostOneBit(order_flags & (OF_TRANSFER | OF_UNLOAD | OF_NO_UNLOAD)) &&
HasAtMostOneBit(order_flags & (OF_NO_UNLOAD | OF_NO_LOAD)) &&
HasAtMostOneBit(order_flags & (OF_FULL_LOAD | OF_NO_LOAD)) &&
/* "Full load any" is "Full load" plus a bit. On its own that bit is invalid. */
((order_flags & OF_FULL_LOAD_ANY) != (OF_FULL_LOAD_ANY & ~OF_FULL_LOAD));
case OT_GOTO_DEPOT:
return (order_flags & ~(OF_NON_STOP_FLAGS | OF_DEPOT_FLAGS)) == 0 &&
@@ -252,15 +261,15 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
/* We don't know where the nearest depot is... (yet) */
if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) return INVALID_TILE;
if (v->type != VEH_AIRCRAFT) return ::Depot::Get(order->GetDestination())->xy;
if (v->type != VEH_AIRCRAFT) return ::Depot::Get(order->GetDestination().ToDepotID())->xy;
/* Aircraft's hangars are referenced by StationID, not DepotID */
const Station *st = ::Station::Get(order->GetDestination());
const Station *st = ::Station::Get(order->GetDestination().ToStationID());
if (!st->airport.HasHangar()) return INVALID_TILE;
return st->airport.GetHangarTile(0);
}
case OT_GOTO_STATION: {
const Station *st = ::Station::Get(order->GetDestination());
const Station *st = ::Station::Get(order->GetDestination().ToStationID());
if (st->train_station.tile != INVALID_TILE) {
for (TileIndex t : st->train_station) {
if (st->TileBelongsToRailStation(t)) return t;
@@ -282,7 +291,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
}
case OT_GOTO_WAYPOINT: {
const Waypoint *wp = ::Waypoint::Get(order->GetDestination());
const Waypoint *wp = ::Waypoint::Get(order->GetDestination().ToStationID());
if (wp->train_station.tile != INVALID_TILE) {
for (TileIndex t : wp->train_station) {
if (wp->TileBelongsToRailStation(t)) return t;
@@ -328,7 +337,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
if (order_position == ORDER_CURRENT || !IsConditionalOrder(vehicle_id, order_position)) return ORDER_INVALID;
const Order *order = ::ResolveOrder(vehicle_id, order_position);
return (OrderPosition)order->GetConditionSkipToOrder();
return ::RealOrderPositionToScriptOrderPosition(vehicle_id, order->GetConditionSkipToOrder());
}
/* static */ ScriptOrder::OrderCondition ScriptOrder::GetOrderCondition(VehicleID vehicle_id, OrderPosition order_position)
@@ -370,7 +379,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
return (ScriptOrder::StopLocation)order->GetStopLocation();
}
/* static */ CargoID ScriptOrder::GetOrderRefit(VehicleID vehicle_id, OrderPosition order_position)
/* static */ CargoType ScriptOrder::GetOrderRefit(VehicleID vehicle_id, OrderPosition order_position)
{
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;
@@ -386,7 +395,9 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
EnforcePrecondition(false, order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position));
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, jump_to) && jump_to != ORDER_CURRENT);
return ScriptObject::Command<CMD_MODIFY_ORDER>::Do(0, vehicle_id, order_position, MOF_COND_DESTINATION, jump_to);
int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position);
int jump_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, jump_to);
return ScriptObject::Command<CMD_MODIFY_ORDER>::Do(0, vehicle_id, order_pos, MOF_COND_DESTINATION, jump_pos);
}
/* static */ bool ScriptOrder::SetOrderCondition(VehicleID vehicle_id, OrderPosition order_position, OrderCondition condition)
@@ -437,7 +448,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
return ScriptObject::Command<CMD_MODIFY_ORDER>::Do(0, vehicle_id, order_pos, MOF_STOP_LOCATION, stop_location);
}
/* static */ bool ScriptOrder::SetOrderRefit(VehicleID vehicle_id, OrderPosition order_position, CargoID refit_cargo)
/* static */ bool ScriptOrder::SetOrderRefit(VehicleID vehicle_id, OrderPosition order_position, CargoType refit_cargo)
{
EnforceCompanyModeValid(false);
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
@@ -484,7 +495,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
if (order_flags & OF_GOTO_NEAREST_DEPOT) odaf |= ODATFB_NEAREST_DEPOT;
OrderNonStopFlags onsf = (OrderNonStopFlags)((order_flags & OF_NON_STOP_INTERMEDIATE) ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE);
if (order_flags & OF_GOTO_NEAREST_DEPOT) {
order.MakeGoToDepot(INVALID_DEPOT, odtf, onsf, odaf);
order.MakeGoToDepot(DepotID::Invalid(), odtf, onsf, odaf);
} else {
/* Check explicitly if the order is to a station (for aircraft) or
* to a depot (other vehicle types). */
@@ -531,7 +542,8 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, jump_to) && jump_to != ORDER_CURRENT);
Order order;
order.MakeConditional(jump_to);
int jump_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, jump_to);
order.MakeConditional(jump_pos);
int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position);
return ScriptObject::Command<CMD_INSERT_ORDER>::Do(0, vehicle_id, order_pos, order);
@@ -633,7 +645,7 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance)
/* static */ bool ScriptOrder::SetOrderFlags(VehicleID vehicle_id, OrderPosition order_position, ScriptOrder::ScriptOrderFlags order_flags)
{
ScriptObject::SetCallbackVariable(0, vehicle_id);
ScriptObject::SetCallbackVariable(0, vehicle_id.base());
ScriptObject::SetCallbackVariable(1, order_position);
ScriptObject::SetCallbackVariable(2, order_flags);
/* In case another client(s) change orders at the same time we could
@@ -680,7 +692,7 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance)
EnforceCompanyModeValid(false);
EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id));
return ScriptObject::Command<CMD_CLONE_ORDER>::Do(0, CO_UNSHARE, vehicle_id, 0);
return ScriptObject::Command<CMD_CLONE_ORDER>::Do(0, CO_UNSHARE, vehicle_id, VehicleID::Invalid());
}
/* static */ SQInteger ScriptOrder::GetOrderDistance(ScriptVehicle::VehicleType vehicle_type, TileIndex origin_tile, TileIndex dest_tile)

View File

@@ -57,9 +57,9 @@ public:
/** Never unload the vehicle; only for stations. Cannot be set when OF_UNLOAD, OF_TRANSFER or OF_NO_LOAD is set. */
OF_NO_UNLOAD = 1 << 4,
/** Wt till the vehicle is fully loaded; only for stations. Cannot be set when OF_NO_LOAD is set. */
/** Wait till the vehicle is fully loaded; only for stations. Cannot be set when OF_NO_LOAD is set. */
OF_FULL_LOAD = 2 << 5,
/** Wt till at least one cargo of the vehicle is fully loaded; only for stations. Cannot be set when OF_NO_LOAD is set. */
/** Wait till at least one cargo of the vehicle is fully loaded; only for stations. Cannot be set when OF_NO_LOAD is set. */
OF_FULL_LOAD_ANY = 3 << 5,
/** Do not load any cargo; only for stations. Cannot be set when OF_NO_UNLOAD, OF_FULL_LOAD or OF_FULL_LOAD_ANY is set. */
OF_NO_LOAD = 1 << 7,
@@ -348,7 +348,7 @@ public:
* in the orderlist, but they can be the current order of a vehicle.
* @return The refit cargo of the order or CT_NO_REFIT if no refit is set.
*/
static CargoID GetOrderRefit(VehicleID vehicle_id, OrderPosition order_position);
static CargoType GetOrderRefit(VehicleID vehicle_id, OrderPosition order_position);
/**
* Sets the OrderPosition to jump to if the check succeeds of the given order for the given vehicle.
@@ -427,7 +427,7 @@ public:
* @game @pre ScriptCompanyMode::IsValid().
* @return Whether the order has been/can be changed.
*/
static bool SetOrderRefit(VehicleID vehicle_id, OrderPosition order_position, CargoID refit_cargo);
static bool SetOrderRefit(VehicleID vehicle_id, OrderPosition order_position, CargoType refit_cargo);
/**
* Appends an order to the end of the vehicle's order list.

View File

@@ -28,7 +28,7 @@
{
if (!IsRailTypeAvailable(rail_type)) return std::nullopt;
return GetString(GetRailTypeInfo((::RailType)rail_type)->strings.menu_text);
return ::StrMakeValid(::GetString(GetRailTypeInfo((::RailType)rail_type)->strings.menu_text));
}
/* static */ bool ScriptRail::IsRailTile(TileIndex tile)
@@ -159,10 +159,10 @@
EnforcePrecondition(false, station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id));
bool adjacent = station_id != ScriptStation::STATION_JOIN_ADJACENT;
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);
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 : StationID::Invalid(), adjacent);
}
/* 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)
/* static */ bool ScriptRail::BuildNewGRFRailStation(TileIndex tile, RailTrack direction, SQInteger num_platforms, SQInteger platform_length, StationID station_id, CargoType cargo_type, IndustryType source_industry, IndustryType goal_industry, SQInteger distance, bool source_station)
{
EnforceCompanyModeValid(false);
EnforcePrecondition(false, ::IsValidTile(tile));
@@ -171,14 +171,14 @@
EnforcePrecondition(false, platform_length > 0 && platform_length <= 0xFF);
EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType()));
EnforcePrecondition(false, station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id));
EnforcePrecondition(false, ScriptCargo::IsValidCargo(cargo_id));
EnforcePrecondition(false, ScriptCargo::IsValidCargo(cargo_type));
EnforcePrecondition(false, source_industry == ScriptIndustryType::INDUSTRYTYPE_UNKNOWN || source_industry == ScriptIndustryType::INDUSTRYTYPE_TOWN || ScriptIndustryType::IsValidIndustryType(source_industry));
EnforcePrecondition(false, goal_industry == ScriptIndustryType::INDUSTRYTYPE_UNKNOWN || goal_industry == ScriptIndustryType::INDUSTRYTYPE_TOWN || ScriptIndustryType::IsValidIndustryType(goal_industry));
const GRFFile *file;
uint16_t res = GetAiPurchaseCallbackResult(
GSF_STATIONS,
cargo_id,
cargo_type,
0,
source_industry,
goal_industry,
@@ -191,7 +191,7 @@
Axis axis = direction == RAILTRACK_NW_SE ? AXIS_Y : AXIS_X;
bool adjacent = station_id != ScriptStation::STATION_JOIN_ADJACENT;
StationID to_join = ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION;
StationID to_join = ScriptStation::IsValidStation(station_id) ? station_id : StationID::Invalid();
if (res != CALLBACK_FAILED) {
const StationSpec *spec = StationClass::GetByGrf(file->grfid, res);
if (spec == nullptr) {
@@ -213,7 +213,7 @@
EnforcePrecondition(false, GetRailTracks(tile) == RAILTRACK_NE_SW || GetRailTracks(tile) == RAILTRACK_NW_SE);
EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType()));
return ScriptObject::Command<CMD_BUILD_RAIL_WAYPOINT>::Do(tile, GetRailTracks(tile) == RAILTRACK_NE_SW ? AXIS_X : AXIS_Y, 1, 1, STAT_CLASS_WAYP, 0, INVALID_STATION, false);
return ScriptObject::Command<CMD_BUILD_RAIL_WAYPOINT>::Do(tile, GetRailTracks(tile) == RAILTRACK_NE_SW ? AXIS_X : AXIS_Y, 1, 1, STAT_CLASS_WAYP, 0, StationID::Invalid(), false);
}
/* static */ bool ScriptRail::RemoveRailWaypointTileRectangle(TileIndex tile, TileIndex tile2, bool keep_rail)
@@ -272,7 +272,7 @@
if (!IsRailTile(tile)) return false;
if (from == to || ScriptMap::DistanceManhattan(from, tile) != 1 || ScriptMap::DistanceManhattan(tile, to) != 1) return false;
if (to < from) ::Swap(from, to);
if (to < from) std::swap(from, to);
if (tile - from == 1) {
if (to - tile == 1) return (GetRailTracks(tile) & RAILTRACK_NE_SW) != 0;

View File

@@ -11,7 +11,9 @@
#define SCRIPT_RAIL_HPP
#include "script_tile.hpp"
#include "../../industry_type.h"
#include "../../signal_type.h"
#include "../../station_type.h"
#include "../../track_type.h"
/**
@@ -58,7 +60,7 @@ public:
RAILTRACK_SW_SE = ::TRACK_BIT_LOWER, ///< Track in the lower corner of the tile (south).
RAILTRACK_NW_SW = ::TRACK_BIT_LEFT, ///< Track in the left corner of the tile (west).
RAILTRACK_NE_SE = ::TRACK_BIT_RIGHT, ///< Track in the right corner of the tile (east).
RAILTRACK_INVALID = ::INVALID_TRACK_BIT, ///< Flag for an invalid track.
RAILTRACK_INVALID = 0xFF, ///< Flag for an invalid track.
};
/**
@@ -276,7 +278,7 @@ public:
* @param num_platforms The number of platforms to build.
* @param platform_length The length of each platform.
* @param station_id The station to join, ScriptStation::STATION_NEW or ScriptStation::STATION_JOIN_ADJACENT.
* @param cargo_id The CargoID of the cargo that will be transported from / to this station.
* @param cargo_type The CargoType of the cargo that will be transported from / to this station.
* @param source_industry The IndustryType of the industry you'll transport goods from, ScriptIndustryType::INDUSTRYTYPE_UNKNOWN or ScriptIndustryType::INDUSTRYTYPE_TOWN.
* @param goal_industry The IndustryType of the industry you'll transport goods to, ScriptIndustryType::INDUSTRYTYPE_UNKNOWN or ScriptIndustryType::INDUSTRYTYPE_TOWN.
* @param distance The manhattan distance you'll transport the cargo over.
@@ -299,7 +301,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, SQInteger num_platforms, SQInteger platform_length, StationID station_id, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, SQInteger distance, bool source_station);
static bool BuildNewGRFRailStation(TileIndex tile, RailTrack direction, SQInteger num_platforms, SQInteger platform_length, StationID station_id, CargoType cargo_type, IndustryType source_industry, IndustryType goal_industry, SQInteger distance, bool source_station);
/**
* Build a rail waypoint.

View File

@@ -18,7 +18,7 @@ ScriptRailTypeList::ScriptRailTypeList()
{
EnforceDeityOrCompanyModeValid_Void();
bool is_deity = ScriptCompanyMode::IsDeity();
CompanyID owner = ScriptObject::GetCompany();
::CompanyID owner = ScriptObject::GetCompany();
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
if (is_deity || ::HasRailTypeAvail(owner, rt)) this->AddItem(rt);
}

View File

@@ -15,12 +15,13 @@
#include "../../landscape_cmd.h"
#include "../../road_cmd.h"
#include "../../station_cmd.h"
#include "../../strings_func.h"
#include "../../newgrf_roadstop.h"
#include "../../script/squirrel_helper_type.hpp"
#include "../../safeguards.h"
/* static */ ScriptRoad::RoadVehicleType ScriptRoad::GetRoadVehicleTypeForCargo(CargoID cargo_type)
/* static */ ScriptRoad::RoadVehicleType ScriptRoad::GetRoadVehicleTypeForCargo(CargoType cargo_type)
{
return ScriptCargo::HasCargoClass(cargo_type, ScriptCargo::CC_PASSENGERS) ? ROADVEHTYPE_BUS : ROADVEHTYPE_TRUCK;
}
@@ -29,7 +30,7 @@
{
if (!IsRoadTypeAvailable(road_type)) return std::nullopt;
return GetString(GetRoadTypeInfo((::RoadType)road_type)->strings.name);
return ::StrMakeValid(::GetString(GetRoadTypeInfo((::RoadType)road_type)->strings.name));
}
/* static */ bool ScriptRoad::IsRoadTile(TileIndex tile)
@@ -46,7 +47,7 @@
if (!IsRoadTypeAvailable(GetCurrentRoadType())) return false;
return ::IsTileType(tile, MP_ROAD) && ::GetRoadTileType(tile) == ROAD_TILE_DEPOT &&
HasBit(::GetPresentRoadTypes(tile), (::RoadType)GetCurrentRoadType());
::GetPresentRoadTypes(tile).Test(::RoadType(GetCurrentRoadType()));
}
/* static */ bool ScriptRoad::IsRoadStationTile(TileIndex tile)
@@ -54,7 +55,7 @@
if (!::IsValidTile(tile)) return false;
if (!IsRoadTypeAvailable(GetCurrentRoadType())) return false;
return ::IsStationRoadStopTile(tile) && HasBit(::GetPresentRoadTypes(tile), (::RoadType)GetCurrentRoadType());
return ::IsStationRoadStopTile(tile) && ::GetPresentRoadTypes(tile).Test(::RoadType(GetCurrentRoadType()));
}
/* static */ bool ScriptRoad::IsDriveThroughRoadStationTile(TileIndex tile)
@@ -62,7 +63,7 @@
if (!::IsValidTile(tile)) return false;
if (!IsRoadTypeAvailable(GetCurrentRoadType())) return false;
return ::IsDriveThroughStopTile(tile) && HasBit(::GetPresentRoadTypes(tile), (::RoadType)GetCurrentRoadType());
return ::IsDriveThroughStopTile(tile) && ::GetPresentRoadTypes(tile).Test(::RoadType(GetCurrentRoadType()));
}
/* static */ bool ScriptRoad::IsRoadTypeAvailable(RoadType road_type)
@@ -100,7 +101,7 @@
{
if (!ScriptMap::IsValidTile(tile)) return false;
if (!IsRoadTypeAvailable(road_type)) return false;
return ::MayHaveRoad(tile) && HasBit(::GetPresentRoadTypes(tile), (::RoadType)road_type);
return ::MayHaveRoad(tile) && ::GetPresentRoadTypes(tile).Test(::RoadType(road_type));
}
/* static */ bool ScriptRoad::AreRoadTilesConnected(TileIndex t1, TileIndex t2)
@@ -110,7 +111,7 @@
if (!IsRoadTypeAvailable(GetCurrentRoadType())) return false;
/* Tiles not neighbouring */
if ((abs((int)::TileX(t1) - (int)::TileX(t2)) + abs((int)::TileY(t1) - (int)::TileY(t2))) != 1) return false;
if (::DistanceManhattan(t1, t2) != 1) return false;
RoadTramType rtt = ::GetRoadTramType(ScriptObject::GetRoadType());
RoadBits r1 = ::GetAnyRoadBits(t1, rtt); // TODO
@@ -131,7 +132,7 @@
EnforcePrecondition(false, ::IsValidTile(end_tile));
EnforcePrecondition(false, IsRoadTypeAvailable(road_type));
return ScriptObject::Command<CMD_CONVERT_ROAD>::Do(start_tile, end_tile, (::RoadType)road_type);
return ScriptObject::Command<CMD_CONVERT_ROAD>::Do(start_tile, end_tile, (::RoadType)road_type, false);
}
/* Helper functions for ScriptRoad::CanBuildConnectedRoadParts(). */
@@ -460,7 +461,7 @@ static std::optional<RoadPartOrientation> ToRoadPartOrientation(const TileIndex
static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagDirection neighbour)
{
TileIndex neighbour_tile = ::TileAddByDiagDir(start_tile, neighbour);
if (!HasBit(::GetPresentRoadTypes(neighbour_tile), rt)) return false;
if (!::GetPresentRoadTypes(neighbour_tile).Test(rt)) return false;
switch (::GetTileType(neighbour_tile)) {
case MP_ROAD:
@@ -578,8 +579,8 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD
EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType()));
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;
RoadStopType stop_type = road_veh_type == ROADVEHTYPE_TRUCK ? RoadStopType::Truck : RoadStopType::Bus;
StationID to_join = ScriptStation::IsValidStation(station_id) ? station_id : StationID::Invalid();
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);
}

View File

@@ -12,7 +12,8 @@
#include "script_tile.hpp"
#include "../squirrel_helper_type.hpp"
#include "../../../road.h"
#include "../../station_type.h"
#include "../../road.h"
/**
* Class that handles all road related functions.
@@ -72,8 +73,8 @@ public:
* Type of road station.
*/
enum RoadVehicleType {
ROADVEHTYPE_BUS, ///< Build objects useable for busses and passenger trams
ROADVEHTYPE_TRUCK, ///< Build objects useable for trucks and cargo trams
ROADVEHTYPE_BUS, ///< Build objects usable for busses and passenger trams
ROADVEHTYPE_TRUCK, ///< Build objects usable for trucks and cargo trams
};
/**
@@ -100,7 +101,7 @@ public:
* @pre ScriptCargo::IsValidCargo(cargo_type).
* @return The road vehicle type needed to transport the cargo.
*/
static RoadVehicleType GetRoadVehicleTypeForCargo(CargoID cargo_type);
static RoadVehicleType GetRoadVehicleTypeForCargo(CargoType cargo_type);
/**
* Checks whether the given tile is actually a tile with road that can be

View File

@@ -16,7 +16,7 @@
ScriptRoadTypeList::ScriptRoadTypeList(ScriptRoad::RoadTramTypes rtts)
{
EnforceDeityOrCompanyModeValid_Void();
CompanyID owner = ScriptObject::GetCompany();
::CompanyID owner = ScriptObject::GetCompany();
for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
if (!HasBit(rtts, GetRoadTramType(rt))) continue;
if (::HasRoadTypeAvail(owner, rt)) this->AddItem(rt);

View File

@@ -9,7 +9,6 @@
#include "../../stdafx.h"
#include "script_sign.hpp"
#include "table/strings.h"
#include "../script_instance.hpp"
#include "../../signs_base.h"
#include "../../string_func.h"
@@ -17,6 +16,8 @@
#include "../../tile_map.h"
#include "../../signs_cmd.h"
#include "table/strings.h"
#include "../../safeguards.h"
/* static */ bool ScriptSign::IsValidSign(SignID sign_id)
@@ -30,7 +31,7 @@
{
if (!IsValidSign(sign_id)) return ScriptCompany::COMPANY_INVALID;
return static_cast<ScriptCompany::CompanyID>((int)::Sign::Get(sign_id)->owner);
return ScriptCompany::ToScriptCompanyID(::Sign::Get(sign_id)->owner);
}
/* static */ bool ScriptSign::SetName(SignID sign_id, Text *name)
@@ -51,8 +52,7 @@
{
if (!IsValidSign(sign_id)) return std::nullopt;
::SetDParam(0, sign_id);
return GetString(STR_SIGN_NAME);
return ::StrMakeValid(::GetString(STR_SIGN_NAME, sign_id));
}
/* static */ TileIndex ScriptSign::GetLocation(SignID sign_id)
@@ -74,15 +74,15 @@
{
ScriptObjectRef counter(name);
EnforceDeityOrCompanyModeValid(INVALID_SIGN);
EnforcePrecondition(INVALID_SIGN, ::IsValidTile(location));
EnforcePrecondition(INVALID_SIGN, name != nullptr);
EnforceDeityOrCompanyModeValid(SignID::Invalid());
EnforcePrecondition(SignID::Invalid(), ::IsValidTile(location));
EnforcePrecondition(SignID::Invalid(), name != nullptr);
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);
EnforcePreconditionEncodedText(SignID::Invalid(), text);
EnforcePreconditionCustomError(SignID::Invalid(), ::Utf8StringLength(text) < MAX_LENGTH_SIGN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG);
if (!ScriptObject::Command<CMD_PLACE_SIGN>::Do(&ScriptInstance::DoCommandReturnSignID, location, text)) return INVALID_SIGN;
if (!ScriptObject::Command<CMD_PLACE_SIGN>::Do(&ScriptInstance::DoCommandReturnSignID, location, text)) return SignID::Invalid();
/* In case of test-mode, we return SignID 0 */
return 0;
return SignID::Begin();
}

View File

@@ -12,6 +12,7 @@
#include "script_company.hpp"
#include "script_error.hpp"
#include "../../signs_type.h"
/**
* Class that handles all sign related functions.

View File

@@ -30,36 +30,39 @@
{
if (!IsValidStation(station_id)) return ScriptCompany::COMPANY_INVALID;
return static_cast<ScriptCompany::CompanyID>((int)::Station::Get(station_id)->owner);
return ScriptCompany::ToScriptCompanyID(::Station::Get(station_id)->owner);
}
/* static */ StationID ScriptStation::GetStationID(TileIndex tile)
{
if (!::IsValidTile(tile) || !::IsTileType(tile, MP_STATION)) return INVALID_STATION;
if (!::IsValidTile(tile) || !::IsTileType(tile, MP_STATION)) return StationID::Invalid();
return ::GetStationIndex(tile);
}
template<bool Tfrom, bool Tvia>
template <bool Tfrom, bool Tvia>
/* static */ bool ScriptStation::IsCargoRequestValid(StationID station_id,
StationID from_station_id, StationID via_station_id, CargoID cargo_id)
StationID from_station_id, StationID via_station_id, CargoType cargo_type)
{
if (!IsValidStation(station_id)) return false;
if (Tfrom && !IsValidStation(from_station_id) && from_station_id != STATION_INVALID) return false;
if (Tvia && !IsValidStation(via_station_id) && via_station_id != STATION_INVALID) return false;
if (!ScriptCargo::IsValidCargo(cargo_id)) return false;
if (!ScriptCargo::IsValidCargo(cargo_type)) return false;
return true;
}
template<bool Tfrom, bool Tvia>
template <bool Tfrom, bool Tvia>
/* static */ SQInteger ScriptStation::CountCargoWaiting(StationID station_id,
StationID from_station_id, StationID via_station_id, CargoID cargo_id)
StationID from_station_id, StationID via_station_id, CargoType cargo_type)
{
if (!ScriptStation::IsCargoRequestValid<Tfrom, Tvia>(station_id, from_station_id,
via_station_id, cargo_id)) {
via_station_id, cargo_type)) {
return -1;
}
const StationCargoList &cargo_list = ::Station::Get(station_id)->goods[cargo_id].cargo;
const ::GoodsEntry &goods = ::Station::Get(station_id)->goods[cargo_type];
if (!goods.HasData()) return 0;
const StationCargoList &cargo_list = goods.GetData().cargo;
if (!Tfrom && !Tvia) return cargo_list.TotalCount();
uint16_t cargo_count = 0;
@@ -75,39 +78,42 @@ template<bool Tfrom, bool Tvia>
return cargo_count;
}
/* static */ SQInteger ScriptStation::GetCargoWaiting(StationID station_id, CargoID cargo_id)
/* static */ SQInteger ScriptStation::GetCargoWaiting(StationID station_id, CargoType cargo_type)
{
return CountCargoWaiting<false, false>(station_id, STATION_INVALID, STATION_INVALID, cargo_id);
return CountCargoWaiting<false, false>(station_id, STATION_INVALID, STATION_INVALID, cargo_type);
}
/* static */ SQInteger ScriptStation::GetCargoWaitingFrom(StationID station_id,
StationID from_station_id, CargoID cargo_id)
StationID from_station_id, CargoType cargo_type)
{
return CountCargoWaiting<true, false>(station_id, from_station_id, STATION_INVALID, cargo_id);
return CountCargoWaiting<true, false>(station_id, from_station_id, STATION_INVALID, cargo_type);
}
/* static */ SQInteger ScriptStation::GetCargoWaitingVia(StationID station_id,
StationID via_station_id, CargoID cargo_id)
StationID via_station_id, CargoType cargo_type)
{
return CountCargoWaiting<false, true>(station_id, STATION_INVALID, via_station_id, cargo_id);
return CountCargoWaiting<false, true>(station_id, STATION_INVALID, via_station_id, cargo_type);
}
/* static */ SQInteger ScriptStation::GetCargoWaitingFromVia(StationID station_id,
StationID from_station_id, StationID via_station_id, CargoID cargo_id)
StationID from_station_id, StationID via_station_id, CargoType cargo_type)
{
return CountCargoWaiting<true, true>(station_id, from_station_id, via_station_id, cargo_id);
return CountCargoWaiting<true, true>(station_id, from_station_id, via_station_id, cargo_type);
}
template<bool Tfrom, bool Tvia>
template <bool Tfrom, bool Tvia>
/* static */ SQInteger ScriptStation::CountCargoPlanned(StationID station_id,
StationID from_station_id, StationID via_station_id, CargoID cargo_id)
StationID from_station_id, StationID via_station_id, CargoType cargo_type)
{
if (!ScriptStation::IsCargoRequestValid<Tfrom, Tvia>(station_id, from_station_id,
via_station_id, cargo_id)) {
via_station_id, cargo_type)) {
return -1;
}
const FlowStatMap &flows = ::Station::Get(station_id)->goods[cargo_id].flows;
const ::GoodsEntry &goods = ::Station::Get(station_id)->goods[cargo_type];
if (!goods.HasData()) return 0;
const FlowStatMap &flows = goods.GetData().flows;
if (Tfrom) {
return Tvia ? flows.GetFlowFromVia(from_station_id, via_station_id) :
flows.GetFlowFrom(from_station_id);
@@ -116,42 +122,42 @@ template<bool Tfrom, bool Tvia>
}
}
/* static */ SQInteger ScriptStation::GetCargoPlanned(StationID station_id, CargoID cargo_id)
/* static */ SQInteger ScriptStation::GetCargoPlanned(StationID station_id, CargoType cargo_type)
{
return CountCargoPlanned<false, false>(station_id, STATION_INVALID, STATION_INVALID, cargo_id);
return CountCargoPlanned<false, false>(station_id, STATION_INVALID, STATION_INVALID, cargo_type);
}
/* static */ SQInteger ScriptStation::GetCargoPlannedFrom(StationID station_id,
StationID from_station_id, CargoID cargo_id)
StationID from_station_id, CargoType cargo_type)
{
return CountCargoPlanned<true, false>(station_id, from_station_id, STATION_INVALID, cargo_id);
return CountCargoPlanned<true, false>(station_id, from_station_id, STATION_INVALID, cargo_type);
}
/* static */ SQInteger ScriptStation::GetCargoPlannedVia(StationID station_id,
StationID via_station_id, CargoID cargo_id)
StationID via_station_id, CargoType cargo_type)
{
return CountCargoPlanned<false, true>(station_id, STATION_INVALID, via_station_id, cargo_id);
return CountCargoPlanned<false, true>(station_id, STATION_INVALID, via_station_id, cargo_type);
}
/* static */ SQInteger ScriptStation::GetCargoPlannedFromVia(StationID station_id,
StationID from_station_id, StationID via_station_id, CargoID cargo_id)
StationID from_station_id, StationID via_station_id, CargoType cargo_type)
{
return CountCargoPlanned<true, true>(station_id, from_station_id, via_station_id, cargo_id);
return CountCargoPlanned<true, true>(station_id, from_station_id, via_station_id, cargo_type);
}
/* static */ bool ScriptStation::HasCargoRating(StationID station_id, CargoID cargo_id)
/* static */ bool ScriptStation::HasCargoRating(StationID station_id, CargoType cargo_type)
{
if (!IsValidStation(station_id)) return false;
if (!ScriptCargo::IsValidCargo(cargo_id)) return false;
if (!ScriptCargo::IsValidCargo(cargo_type)) return false;
return ::Station::Get(station_id)->goods[cargo_id].HasRating();
return ::Station::Get(station_id)->goods[cargo_type].HasRating();
}
/* static */ SQInteger ScriptStation::GetCargoRating(StationID station_id, CargoID cargo_id)
/* static */ SQInteger ScriptStation::GetCargoRating(StationID station_id, CargoType cargo_type)
{
if (!ScriptStation::HasCargoRating(station_id, cargo_id)) return -1;
if (!ScriptStation::HasCargoRating(station_id, cargo_type)) return -1;
return ::ToPercent8(::Station::Get(station_id)->goods[cargo_id].rating);
return ::ToPercent8(::Station::Get(station_id)->goods[cargo_type].rating);
}
/* static */ SQInteger ScriptStation::GetCoverageRadius(ScriptStation::StationType station_type)
@@ -203,7 +209,7 @@ template<bool Tfrom, bool Tvia>
if (!IsValidStation(station_id)) return false;
if (!HasExactlyOneBit(station_type)) return false;
return (::Station::Get(station_id)->facilities & static_cast<StationFacility>(station_type)) != 0;
return ::Station::Get(station_id)->facilities.Any(static_cast<StationFacilities>(station_type));
}
/* static */ bool ScriptStation::HasRoadType(StationID station_id, ScriptRoad::RoadType road_type)
@@ -211,11 +217,11 @@ template<bool Tfrom, bool Tvia>
if (!IsValidStation(station_id)) return false;
if (!ScriptRoad::IsRoadTypeAvailable(road_type)) return false;
for (const RoadStop *rs = ::Station::Get(station_id)->GetPrimaryRoadStop(ROADSTOP_BUS); rs != nullptr; rs = rs->next) {
if (HasBit(::GetPresentRoadTypes(rs->xy), (::RoadType)road_type)) return true;
for (const RoadStop *rs = ::Station::Get(station_id)->GetPrimaryRoadStop(RoadStopType::Bus); rs != nullptr; rs = rs->next) {
if (::GetPresentRoadTypes(rs->xy).Test(::RoadType(road_type))) return true;
}
for (const RoadStop *rs = ::Station::Get(station_id)->GetPrimaryRoadStop(ROADSTOP_TRUCK); rs != nullptr; rs = rs->next) {
if (HasBit(::GetPresentRoadTypes(rs->xy), (::RoadType)road_type)) return true;
for (const RoadStop *rs = ::Station::Get(station_id)->GetPrimaryRoadStop(RoadStopType::Truck); rs != nullptr; rs = rs->next) {
if (::GetPresentRoadTypes(rs->xy).Test(::RoadType(road_type))) return true;
}
return false;
@@ -223,7 +229,7 @@ template<bool Tfrom, bool Tvia>
/* static */ TownID ScriptStation::GetNearestTown(StationID station_id)
{
if (!IsValidStation(station_id)) return INVALID_TOWN;
if (!IsValidStation(station_id)) return TownID::Invalid();
return ::Station::Get(station_id)->town->index;
}
@@ -233,7 +239,7 @@ template<bool Tfrom, bool Tvia>
EnforcePrecondition(false, IsValidStation(station_id));
EnforcePrecondition(false, HasStationType(station_id, STATION_AIRPORT));
return (::Station::Get(station_id)->airport.flags & AIRPORT_CLOSED_block) != 0;
return ::Station::Get(station_id)->airport.blocks.Test(AirportBlock::AirportClosed);
}
/* static */ bool ScriptStation::OpenCloseAirport(StationID station_id)

View File

@@ -43,12 +43,12 @@ public:
* Type of stations known in the game.
*/
enum StationType {
/* Note: these values represent part of the in-game StationFacility enum */
STATION_TRAIN = (int)::FACIL_TRAIN, ///< Train station
STATION_TRUCK_STOP = (int)::FACIL_TRUCK_STOP, ///< Truck station
STATION_BUS_STOP = (int)::FACIL_BUS_STOP, ///< Bus station
STATION_AIRPORT = (int)::FACIL_AIRPORT, ///< Airport
STATION_DOCK = (int)::FACIL_DOCK, ///< Dock
/* Note: these values represent part of the in-game StationFacilities enum */
STATION_TRAIN = ::StationFacilities{::StationFacility::Train}.base(), ///< Train station
STATION_TRUCK_STOP = ::StationFacilities{::StationFacility::TruckStop}.base(), ///< Truck station
STATION_BUS_STOP = ::StationFacilities{::StationFacility::BusStop}.base(), ///< Bus station
STATION_AIRPORT = ::StationFacilities{::StationFacility::Airport}.base(), ///< Airport
STATION_DOCK = ::StationFacilities{::StationFacility::Dock}.base(), ///< Dock
STATION_ANY = STATION_TRAIN | STATION_TRUCK_STOP | STATION_BUS_STOP | STATION_AIRPORT | STATION_DOCK, ///< All station types
};
@@ -79,88 +79,88 @@ public:
/**
* See how much cargo there is waiting on a station.
* @param station_id The station to get the cargo-waiting of.
* @param cargo_id The cargo to get the cargo-waiting of.
* @param cargo_type The cargo to get the cargo-waiting of.
* @pre IsValidStation(station_id).
* @pre IsValidCargo(cargo_id).
* @pre IsValidCargo(cargo_type).
* @return The amount of units waiting at the station.
*/
static SQInteger GetCargoWaiting(StationID station_id, CargoID cargo_id);
static SQInteger GetCargoWaiting(StationID station_id, CargoType cargo_type);
/**
* See how much cargo with a specific source station there is waiting on a station.
* @param station_id The station to get the cargo-waiting of.
* @param from_station_id The source station of the cargo. Pass STATION_INVALID to get cargo of which the source has been deleted.
* @param cargo_id The cargo to get the cargo-waiting of.
* @param cargo_type The cargo to get the cargo-waiting of.
* @pre IsValidStation(station_id).
* @pre IsValidStation(from_station_id) || from_station_id == STATION_INVALID.
* @pre IsValidCargo(cargo_id).
* @pre IsValidCargo(cargo_type).
* @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 SQInteger GetCargoWaitingFrom(StationID station_id, StationID from_station_id, CargoID cargo_id);
static SQInteger GetCargoWaitingFrom(StationID station_id, StationID from_station_id, CargoType cargo_type);
/**
* See how much cargo with a specific via-station there is waiting on a station.
* @param station_id The station to get the cargo-waiting of.
* @param via_station_id The next station the cargo is going to. Pass STATION_INVALID to get waiting cargo for "via any station".
* @param cargo_id The cargo to get the cargo-waiting of.
* @param cargo_type The cargo to get the cargo-waiting of.
* @pre IsValidStation(station_id).
* @pre IsValidStation(via_station_id) || via_station_id == STATION_INVALID.
* @pre IsValidCargo(cargo_id).
* @pre IsValidCargo(cargo_type).
* @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.
* @note if ScriptCargo.GetCargoDistributionType(cargo_type) == ScriptCargo.DT_MANUAL, then all waiting cargo will have STATION_INVALID as next hop.
*/
static SQInteger GetCargoWaitingVia(StationID station_id, StationID via_station_id, CargoID cargo_id);
static SQInteger GetCargoWaitingVia(StationID station_id, StationID via_station_id, CargoType cargo_type);
/**
* See how much cargo with a specific via-station and source station there is waiting on a station.
* @param station_id The station to get the cargo-waiting of.
* @param from_station_id The source station of the cargo. Pass STATION_INVALID to get cargo of which the source has been deleted.
* @param via_station_id The next station the cargo is going to. Pass STATION_INVALID to get waiting cargo for "via any station".
* @param cargo_id The cargo to get the cargo-waiting of.
* @param cargo_type The cargo to get the cargo-waiting of.
* @pre IsValidStation(station_id).
* @pre IsValidStation(from_station_id) || from_station_id == STATION_INVALID.
* @pre IsValidStation(via_station_id) || via_station_id == STATION_INVALID.
* @pre IsValidCargo(cargo_id).
* @pre IsValidCargo(cargo_type).
* @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.
* @note if ScriptCargo.GetCargoDistributionType(cargo_type) == ScriptCargo.DT_MANUAL, then all waiting cargo will have STATION_INVALID as next hop.
*/
static SQInteger 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, CargoType cargo_type);
/**
* See how much cargo was planned to pass (including production and consumption) this station per month.
* @param station_id The station to get the planned flow for.
* @param cargo_id The cargo type to get the planned flow for.
* @param cargo_type The cargo type to get the planned flow for.
* @pre IsValidStation(station_id).
* @pre IsValidCargo(cargo_id).
* @pre IsValidCargo(cargo_type).
* @return The amount of cargo units planned to pass the station per month.
*/
static SQInteger GetCargoPlanned(StationID station_id, CargoID cargo_id);
static SQInteger GetCargoPlanned(StationID station_id, CargoType cargo_type);
/**
* See how much cargo from the specified origin was planned to pass (including production and consumption) this station per month.
* @param station_id The station to get the planned flow for.
* @param from_station_id The station the cargo originates at.
* @param cargo_id The cargo type to get the planned flow for.
* @param cargo_type The cargo type to get the planned flow for.
* @pre IsValidStation(station_id).
* @pre IsValidStation(from_station_id) || from_station_id == STATION_INVALID.
* @pre IsValidCargo(cargo_id).
* @pre IsValidCargo(cargo_type).
* @return The amount of cargo units from the specified origin planned to pass the station per month.
*/
static SQInteger GetCargoPlannedFrom(StationID station_id, StationID from_station_id, CargoID cargo_id);
static SQInteger GetCargoPlannedFrom(StationID station_id, StationID from_station_id, CargoType cargo_type);
/**
* See how much cargo was planned to pass (including production and consumption) this station per month, heading for the specified next hop.
* @param station_id The station to get the planned flow for.
* @param via_station_id The next station the cargo will go on to.
* @param cargo_id The cargo type to get the planned flow for.
* @param cargo_type The cargo type to get the planned flow for.
* @pre IsValidStation(station_id).
* @pre IsValidStation(via_station_id) || via_station_id == STATION_INVALID.
* @pre IsValidCargo(cargo_id).
* @pre IsValidCargo(cargo_type).
* @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 SQInteger GetCargoPlannedVia(StationID station_id, StationID via_station_id, CargoID cargo_id);
static SQInteger GetCargoPlannedVia(StationID station_id, StationID via_station_id, CargoType cargo_type);
/**
* See how much cargo from the specified origin was planned to pass this station per month,
@@ -168,37 +168,37 @@ public:
* @param station_id The station to get the planned flow for.
* @param from_station_id The station the cargo originates at.
* @param via_station_id The next station the cargo will go on to.
* @param cargo_id The cargo type to get the planned flow for.
* @param cargo_type The cargo type to get the planned flow for.
* @pre IsValidStation(station_id).
* @pre IsValidStation(from_station_id) || from_station_id == STATION_INVALID.
* @pre IsValidStation(via_station_id) || via_station_id == STATION_INVALID.
* @pre IsValidCargo(cargo_id).
* @pre IsValidCargo(cargo_type).
* @return The amount of cargo units from the specified origin 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.
* @note Cargo planned to pass "from" the same station that's being queried is actually produced there.
*/
static SQInteger 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, CargoType cargo_type);
/**
* Check whether the given cargo at the given station a rating.
* @param station_id The station to get the cargo-rating state of.
* @param cargo_id The cargo to get the cargo-rating state of.
* @param cargo_type The cargo to get the cargo-rating state of.
* @pre IsValidStation(station_id).
* @pre IsValidCargo(cargo_id).
* @pre IsValidCargo(cargo_type).
* @return True if the cargo has a rating, otherwise false.
*/
static bool HasCargoRating(StationID station_id, CargoID cargo_id);
static bool HasCargoRating(StationID station_id, CargoType cargo_type);
/**
* See how high the rating is of a cargo on a station.
* @param station_id The station to get the cargo-rating of.
* @param cargo_id The cargo to get the cargo-rating of.
* @param cargo_type The cargo to get the cargo-rating of.
* @pre IsValidStation(station_id).
* @pre IsValidCargo(cargo_id).
* @pre HasCargoRating(station_id, cargo_id).
* @pre IsValidCargo(cargo_type).
* @pre HasCargoRating(station_id, cargo_type).
* @return The rating in percent of the cargo on the station.
*/
static SQInteger GetCargoRating(StationID station_id, CargoID cargo_id);
static SQInteger GetCargoRating(StationID station_id, CargoType cargo_type);
/**
* Get the coverage radius of this type of station.
@@ -297,17 +297,17 @@ public:
static bool OpenCloseAirport(StationID station_id);
private:
template<bool Tfrom, bool Tvia>
template <bool Tfrom, bool Tvia>
static bool IsCargoRequestValid(StationID station_id, StationID from_station_id,
StationID via_station_id, CargoID cargo_id);
StationID via_station_id, CargoType cargo_type);
template<bool Tfrom, bool Tvia>
template <bool Tfrom, bool Tvia>
static SQInteger CountCargoWaiting(StationID station_id, StationID from_station_id,
StationID via_station_id, CargoID cargo_id);
StationID via_station_id, CargoType cargo_type);
template<bool Tfrom, bool Tvia>
template <bool Tfrom, bool Tvia>
static SQInteger CountCargoPlanned(StationID station_id, StationID from_station_id,
StationID via_station_id, CargoID cargo_id);
StationID via_station_id, CargoType cargo_type);
};

View File

@@ -20,10 +20,10 @@ ScriptStationList::ScriptStationList(ScriptStation::StationType station_type)
{
EnforceDeityOrCompanyModeValid_Void();
bool is_deity = ScriptCompanyMode::IsDeity();
CompanyID owner = ScriptObject::GetCompany();
::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;
return (is_deity || st->owner == owner) && st->facilities.Any(static_cast<StationFacilities>(station_type));
}
);
}
@@ -35,12 +35,12 @@ ScriptStationList_Vehicle::ScriptStationList_Vehicle(VehicleID vehicle_id)
const Vehicle *v = ::Vehicle::Get(vehicle_id);
for (Order *o = v->GetFirstOrder(); o != nullptr; o = o->next) {
if (o->IsType(OT_GOTO_STATION)) this->AddItem(o->GetDestination());
if (o->IsType(OT_GOTO_STATION)) this->AddItem(o->GetDestination().ToStationID().base());
}
}
ScriptStationList_Cargo::ScriptStationList_Cargo(ScriptStationList_Cargo::CargoMode mode,
ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoID cargo,
ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoType cargo,
StationID other_station)
{
switch (mode) {
@@ -56,7 +56,7 @@ ScriptStationList_Cargo::ScriptStationList_Cargo(ScriptStationList_Cargo::CargoM
}
ScriptStationList_CargoWaiting::ScriptStationList_CargoWaiting(
ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoID cargo,
ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoType cargo,
StationID other_station)
{
switch (selector) {
@@ -78,7 +78,7 @@ ScriptStationList_CargoWaiting::ScriptStationList_CargoWaiting(
}
ScriptStationList_CargoPlanned::ScriptStationList_CargoPlanned(
ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoID cargo,
ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoType cargo,
StationID other_station)
{
switch (selector) {
@@ -101,11 +101,11 @@ ScriptStationList_CargoPlanned::ScriptStationList_CargoPlanned(
class CargoCollector {
public:
CargoCollector(ScriptStationList_Cargo *parent, StationID station_id, CargoID cargo,
CargoCollector(ScriptStationList_Cargo *parent, StationID station_id, CargoType cargo,
StationID other);
~CargoCollector() ;
template<ScriptStationList_Cargo::CargoSelector Tselector>
template <ScriptStationList_Cargo::CargoSelector Tselector>
void Update(StationID from, StationID via, uint amount);
const GoodsEntry *GE() const { return ge; }
@@ -121,8 +121,8 @@ private:
};
CargoCollector::CargoCollector(ScriptStationList_Cargo *parent,
StationID station_id, CargoID cargo, StationID other) :
list(parent), ge(nullptr), other_station(other), last_key(INVALID_STATION), amount(0)
StationID station_id, CargoType cargo, StationID other) :
list(parent), ge(nullptr), other_station(other), last_key(StationID::Invalid()), amount(0)
{
if (!ScriptStation::IsValidStation(station_id)) return;
if (!ScriptCargo::IsValidCargo(cargo)) return;
@@ -137,19 +137,19 @@ CargoCollector::~CargoCollector()
void CargoCollector::SetValue()
{
if (this->amount > 0) {
if (this->list->HasItem(this->last_key)) {
this->list->SetValue(this->last_key,
this->list->GetValue(this->last_key) + this->amount);
if (this->list->HasItem(this->last_key.base())) {
this->list->SetValue(this->last_key.base(),
this->list->GetValue(this->last_key.base()) + this->amount);
} else {
this->list->AddItem(this->last_key, this->amount);
this->list->AddItem(this->last_key.base(), this->amount);
}
}
}
template<ScriptStationList_Cargo::CargoSelector Tselector>
template <ScriptStationList_Cargo::CargoSelector Tselector>
void CargoCollector::Update(StationID from, StationID via, uint amount)
{
StationID key = INVALID_STATION;
StationID key = StationID::Invalid();
switch (Tselector) {
case ScriptStationList_Cargo::CS_VIA_BY_FROM:
if (via != this->other_station) return;
@@ -174,28 +174,30 @@ void CargoCollector::Update(StationID from, StationID via, uint amount)
}
template<ScriptStationList_Cargo::CargoSelector Tselector>
void ScriptStationList_CargoWaiting::Add(StationID station_id, CargoID cargo, StationID other_station)
template <ScriptStationList_Cargo::CargoSelector Tselector>
void ScriptStationList_CargoWaiting::Add(StationID station_id, CargoType cargo, StationID other_station)
{
CargoCollector collector(this, station_id, cargo, other_station);
if (collector.GE() == nullptr) return;
if (!collector.GE()->HasData()) return;
StationCargoList::ConstIterator iter = collector.GE()->cargo.Packets()->begin();
StationCargoList::ConstIterator end = collector.GE()->cargo.Packets()->end();
StationCargoList::ConstIterator iter = collector.GE()->GetData().cargo.Packets()->begin();
StationCargoList::ConstIterator end = collector.GE()->GetData().cargo.Packets()->end();
for (; iter != end; ++iter) {
collector.Update<Tselector>((*iter)->GetFirstStation(), iter.GetKey(), (*iter)->Count());
}
}
template<ScriptStationList_Cargo::CargoSelector Tselector>
void ScriptStationList_CargoPlanned::Add(StationID station_id, CargoID cargo, StationID other_station)
template <ScriptStationList_Cargo::CargoSelector Tselector>
void ScriptStationList_CargoPlanned::Add(StationID station_id, CargoType cargo, StationID other_station)
{
CargoCollector collector(this, station_id, cargo, other_station);
if (collector.GE() == nullptr) return;
if (!collector.GE()->HasData()) return;
FlowStatMap::const_iterator iter = collector.GE()->flows.begin();
FlowStatMap::const_iterator end = collector.GE()->flows.end();
FlowStatMap::const_iterator iter = collector.GE()->GetData().flows.begin();
FlowStatMap::const_iterator end = collector.GE()->GetData().flows.end();
for (; iter != end; ++iter) {
const FlowStat::SharesMap *shares = iter->second.GetShares();
uint prev = 0;
@@ -208,19 +210,20 @@ void ScriptStationList_CargoPlanned::Add(StationID station_id, CargoID cargo, St
}
ScriptStationList_CargoWaitingByFrom::ScriptStationList_CargoWaitingByFrom(StationID station_id,
CargoID cargo)
CargoType cargo)
{
this->Add<CS_BY_FROM>(station_id, cargo);
}
ScriptStationList_CargoWaitingViaByFrom::ScriptStationList_CargoWaitingViaByFrom(
StationID station_id, CargoID cargo, StationID via)
StationID station_id, CargoType cargo, StationID via)
{
CargoCollector collector(this, station_id, cargo, via);
if (collector.GE() == nullptr) return;
if (!collector.GE()->HasData()) return;
std::pair<StationCargoList::ConstIterator, StationCargoList::ConstIterator> range =
collector.GE()->cargo.Packets()->equal_range(via);
collector.GE()->GetData().cargo.Packets()->equal_range(via);
for (StationCargoList::ConstIterator iter = range.first; iter != range.second; ++iter) {
collector.Update<CS_VIA_BY_FROM>((*iter)->GetFirstStation(), iter.GetKey(), (*iter)->Count());
}
@@ -228,45 +231,46 @@ ScriptStationList_CargoWaitingViaByFrom::ScriptStationList_CargoWaitingViaByFrom
ScriptStationList_CargoWaitingByVia::ScriptStationList_CargoWaitingByVia(StationID station_id,
CargoID cargo)
CargoType cargo)
{
this->Add<CS_BY_VIA>(station_id, cargo);
}
ScriptStationList_CargoWaitingFromByVia::ScriptStationList_CargoWaitingFromByVia(
StationID station_id, CargoID cargo, StationID from)
StationID station_id, CargoType cargo, StationID from)
{
this->Add<CS_FROM_BY_VIA>(station_id, cargo, from);
}
ScriptStationList_CargoPlannedByFrom::ScriptStationList_CargoPlannedByFrom(StationID station_id,
CargoID cargo)
CargoType cargo)
{
this->Add<CS_BY_FROM>(station_id, cargo);
}
ScriptStationList_CargoPlannedViaByFrom::ScriptStationList_CargoPlannedViaByFrom(
StationID station_id, CargoID cargo, StationID via)
StationID station_id, CargoType cargo, StationID via)
{
this->Add<CS_VIA_BY_FROM>(station_id, cargo, via);
}
ScriptStationList_CargoPlannedByVia::ScriptStationList_CargoPlannedByVia(StationID station_id,
CargoID cargo)
CargoType cargo)
{
this->Add<CS_BY_VIA>(station_id, cargo);
}
ScriptStationList_CargoPlannedFromByVia::ScriptStationList_CargoPlannedFromByVia(
StationID station_id, CargoID cargo, StationID from)
StationID station_id, CargoType cargo, StationID from)
{
CargoCollector collector(this, station_id, cargo, from);
if (collector.GE() == nullptr) return;
if (!collector.GE()->HasData()) return;
FlowStatMap::const_iterator iter = collector.GE()->flows.find(from);
if (iter == collector.GE()->flows.end()) return;
FlowStatMap::const_iterator iter = collector.GE()->GetData().flows.find(from);
if (iter == collector.GE()->GetData().flows.end()) return;
const FlowStat::SharesMap *shares = iter->second.GetShares();
uint prev = 0;
for (FlowStat::SharesMap::const_iterator flow_iter = shares->begin();

View File

@@ -61,7 +61,7 @@ public:
* @param cargo Cargo type to query for.
* @param other_station Other station to restrict the query with.
*/
ScriptStationList_Cargo(ScriptStationList_Cargo::CargoMode mode, ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoID cargo, StationID other_station);
ScriptStationList_Cargo(ScriptStationList_Cargo::CargoMode mode, ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoType cargo, StationID other_station);
protected:
@@ -92,8 +92,8 @@ protected:
* @param cargo Cargo type to query for.
* @param other_station Other station to restrict the query with.
*/
template<CargoSelector Tselector>
void Add(StationID station_id, CargoID cargo, StationID other_station = INVALID_STATION);
template <CargoSelector Tselector>
void Add(StationID station_id, CargoType cargo, StationID other_station = StationID::Invalid());
public:
@@ -105,7 +105,7 @@ public:
* @param cargo Cargo type to query for.
* @param other_station Other station to restrict the query with.
*/
ScriptStationList_CargoWaiting(ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoID cargo, StationID other_station);
ScriptStationList_CargoWaiting(ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoType cargo, StationID other_station);
};
/**
@@ -129,8 +129,8 @@ protected:
* @param cargo Cargo type to query for.
* @param other_station Other station to restrict the query with.
*/
template<CargoSelector Tselector>
void Add(StationID station_id, CargoID cargo, StationID other_station = INVALID_STATION);
template <CargoSelector Tselector>
void Add(StationID station_id, CargoType cargo, StationID other_station = StationID::Invalid());
public:
@@ -142,7 +142,7 @@ public:
* @param cargo Cargo type to query for.
* @param other_station Other station to restrict the query with.
*/
ScriptStationList_CargoPlanned(ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoID cargo, StationID other_station);
ScriptStationList_CargoPlanned(ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoType cargo, StationID other_station);
};
/**
@@ -157,7 +157,7 @@ public:
* @param station_id Station to query for waiting cargo.
* @param cargo Cargo type to query for.
*/
ScriptStationList_CargoWaitingByFrom(StationID station_id, CargoID cargo);
ScriptStationList_CargoWaitingByFrom(StationID station_id, CargoType cargo);
};
/**
@@ -173,7 +173,7 @@ public:
* @param cargo Cargo type to query for.
* @param via Next hop to restrict the query with.
*/
ScriptStationList_CargoWaitingViaByFrom(StationID station_id, CargoID cargo, StationID via);
ScriptStationList_CargoWaitingViaByFrom(StationID station_id, CargoType cargo, StationID via);
};
/**
@@ -188,7 +188,7 @@ public:
* @param station_id Station to query for waiting cargo.
* @param cargo Cargo type to query for.
*/
ScriptStationList_CargoWaitingByVia(StationID station_id, CargoID cargo);
ScriptStationList_CargoWaitingByVia(StationID station_id, CargoType cargo);
};
/**
@@ -204,7 +204,7 @@ public:
* @param cargo Cargo type to query for.
* @param from Origin station to restrict the query with.
*/
ScriptStationList_CargoWaitingFromByVia(StationID station_id, CargoID cargo, StationID from);
ScriptStationList_CargoWaitingFromByVia(StationID station_id, CargoType cargo, StationID from);
};
/**
@@ -219,7 +219,7 @@ public:
* @param station_id Station to query for planned flows.
* @param cargo Cargo type to query for.
*/
ScriptStationList_CargoPlannedByFrom(StationID station_id, CargoID cargo);
ScriptStationList_CargoPlannedByFrom(StationID station_id, CargoType cargo);
};
/**
@@ -235,7 +235,7 @@ public:
* @param cargo Cargo type to query for.
* @param via Next hop to restrict the query with.
*/
ScriptStationList_CargoPlannedViaByFrom(StationID station_id, CargoID cargo, StationID via);
ScriptStationList_CargoPlannedViaByFrom(StationID station_id, CargoType cargo, StationID via);
};
/**
@@ -251,7 +251,7 @@ public:
* @param station_id Station to query for planned flows.
* @param cargo Cargo type to query for.
*/
ScriptStationList_CargoPlannedByVia(StationID station_id, CargoID cargo);
ScriptStationList_CargoPlannedByVia(StationID station_id, CargoType cargo);
};
/**
@@ -268,7 +268,7 @@ public:
* @param cargo Cargo type to query for.
* @param from Origin station to restrict the query with.
*/
ScriptStationList_CargoPlannedFromByVia(StationID station_id, CargoID cargo, StationID from);
ScriptStationList_CargoPlannedFromByVia(StationID station_id, CargoType cargo, StationID from);
};
/**

View File

@@ -43,24 +43,23 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
return type == SPET_TEXT || type == SPET_LOCATION || type == SPET_GOAL || type == SPET_BUTTON_PUSH || type == SPET_BUTTON_TILE || type == SPET_BUTTON_VEHICLE;
}
/* static */ ScriptStoryPage::StoryPageID ScriptStoryPage::New(ScriptCompany::CompanyID company, Text *title)
/* static */ StoryPageID ScriptStoryPage::New(ScriptCompany::CompanyID company, Text *title)
{
ScriptObjectRef counter(title);
EnforceDeityMode(STORY_PAGE_INVALID);
EnforcePrecondition(STORY_PAGE_INVALID, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID);
uint8_t c = company;
if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY;
::CompanyID c = ScriptCompany::FromScriptCompanyID(company);
if (!ScriptObject::Command<CMD_CREATE_STORY_PAGE>::Do(&ScriptInstance::DoCommandReturnStoryPageID,
(::CompanyID)c, title != nullptr ? title->GetEncodedText() : std::string{})) return STORY_PAGE_INVALID;
c, title != nullptr ? title->GetEncodedText() : EncodedString{})) return STORY_PAGE_INVALID;
/* In case of test-mode, we return StoryPageID 0 */
return (ScriptStoryPage::StoryPageID)0;
return StoryPageID::Begin();
}
/* static */ ScriptStoryPage::StoryPageElementID ScriptStoryPage::NewElement(StoryPageID story_page_id, StoryPageElementType type, SQInteger reference, Text *text)
/* static */ StoryPageElementID ScriptStoryPage::NewElement(StoryPageID story_page_id, StoryPageElementType type, SQInteger reference, Text *text)
{
ScriptObjectRef counter(text);
@@ -69,21 +68,21 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
EnforceDeityMode(STORY_PAGE_ELEMENT_INVALID);
EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, IsValidStoryPage(story_page_id));
EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, IsValidStoryPageElementType(type));
std::string encoded_text;
EncodedString encoded_text;
if (StoryPageElementTypeRequiresText(btype)) {
EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, text != nullptr);
encoded_text = text->GetEncodedText();
EnforcePreconditionEncodedText(STORY_PAGE_ELEMENT_INVALID, encoded_text);
}
EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, type != SPET_LOCATION || ::IsValidTile((::TileIndex)reference));
EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, type != SPET_GOAL || ScriptGoal::IsValidGoal((ScriptGoal::GoalID)reference));
EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, type != SPET_GOAL || !(StoryPage::Get(story_page_id)->company == INVALID_COMPANY && Goal::Get(reference)->company != INVALID_COMPANY));
EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, type != SPET_GOAL || ScriptGoal::IsValidGoal(static_cast<::GoalID>(reference)));
EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, type != SPET_GOAL || !(StoryPage::Get(story_page_id)->company == CompanyID::Invalid() && Goal::Get(reference)->company != CompanyID::Invalid()));
uint32_t refid = 0;
TileIndex reftile = 0;
TileIndex reftile{};
switch (type) {
case SPET_LOCATION:
reftile = reference;
reftile = TileIndex(reference);
break;
case SPET_GOAL:
case SPET_BUTTON_PUSH:
@@ -104,7 +103,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
encoded_text)) return STORY_PAGE_ELEMENT_INVALID;
/* In case of test-mode, we return StoryPageElementID 0 */
return (ScriptStoryPage::StoryPageElementID)0;
return StoryPageElementID::Begin();
}
/* static */ bool ScriptStoryPage::UpdateElement(StoryPageElementID story_page_element_id, SQInteger reference, Text *text)
@@ -118,21 +117,21 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
const StoryPage *p = StoryPage::Get(pe->page);
::StoryPageElementType type = pe->type;
std::string encoded_text;
EncodedString encoded_text;
if (StoryPageElementTypeRequiresText(type)) {
EnforcePrecondition(false, text != nullptr);
encoded_text = text->GetEncodedText();
EnforcePreconditionEncodedText(false, encoded_text);
}
EnforcePrecondition(false, type != ::SPET_LOCATION || ::IsValidTile((::TileIndex)reference));
EnforcePrecondition(false, type != ::SPET_GOAL || ScriptGoal::IsValidGoal((ScriptGoal::GoalID)reference));
EnforcePrecondition(false, type != ::SPET_GOAL || !(p->company == INVALID_COMPANY && Goal::Get(reference)->company != INVALID_COMPANY));
EnforcePrecondition(false, type != ::SPET_GOAL || ScriptGoal::IsValidGoal(static_cast<::GoalID>(reference)));
EnforcePrecondition(false, type != ::SPET_GOAL || !(p->company == CompanyID::Invalid() && Goal::Get(reference)->company != CompanyID::Invalid()));
uint32_t refid = 0;
TileIndex reftile = 0;
TileIndex reftile{};
switch (type) {
case ::SPET_LOCATION:
reftile = reference;
reftile = TileIndex(reference);
break;
case ::SPET_GOAL:
case ::SPET_BUTTON_PUSH:
@@ -170,17 +169,14 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
EnforcePrecondition(false, IsValidStoryPage(story_page_id));
EnforceDeityMode(false);
return ScriptObject::Command<CMD_SET_STORY_PAGE_TITLE>::Do(story_page_id, title != nullptr ? title->GetEncodedText() : std::string{});
return ScriptObject::Command<CMD_SET_STORY_PAGE_TITLE>::Do(story_page_id, title != nullptr ? title->GetEncodedText() : EncodedString{});
}
/* static */ ScriptCompany::CompanyID ScriptStoryPage::GetCompany(StoryPageID story_page_id)
{
EnforcePrecondition(ScriptCompany::COMPANY_INVALID, IsValidStoryPage(story_page_id));
CompanyID c = StoryPage::Get(story_page_id)->company;
ScriptCompany::CompanyID company = c == INVALID_COMPANY ? ScriptCompany::COMPANY_INVALID : (ScriptCompany::CompanyID)c;
return company;
return ScriptCompany::ToScriptCompanyID(StoryPage::Get(story_page_id)->company);
}
/* static */ ScriptDate::Date ScriptStoryPage::GetDate(StoryPageID story_page_id)
@@ -196,7 +192,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
EnforcePrecondition(false, IsValidStoryPage(story_page_id));
EnforceDeityMode(false);
return ScriptObject::Command<CMD_SET_STORY_PAGE_DATE>::Do(story_page_id, date);
return ScriptObject::Command<CMD_SET_STORY_PAGE_DATE>::Do(story_page_id, ::TimerGameCalendar::Date{date});
}

View File

@@ -38,21 +38,8 @@
*/
class ScriptStoryPage : public ScriptObject {
public:
/**
* The story page IDs.
*/
enum StoryPageID {
/* Note: these values represent part of the in-game StoryPageID enum */
STORY_PAGE_INVALID = ::INVALID_STORY_PAGE, ///< An invalid story page id.
};
/**
* The story page element IDs.
*/
enum StoryPageElementID {
/* Note: these values represent part of the in-game StoryPageElementID enum */
STORY_PAGE_ELEMENT_INVALID = ::INVALID_STORY_PAGE_ELEMENT, ///< An invalid story page element id.
};
static constexpr StoryPageID STORY_PAGE_INVALID = ::StoryPageID::Invalid(); ///< An invalid story page id.
static constexpr StoryPageElementID STORY_PAGE_ELEMENT_INVALID = ::StoryPageElementID::Invalid(); ///< An invalid story page element id.
/**
* Story page element types.
@@ -63,7 +50,7 @@ public:
SPET_GOAL = ::SPET_GOAL, ///< An element that displays a goal.
SPET_BUTTON_PUSH = ::SPET_BUTTON_PUSH, ///< A push button that triggers an immediate event.
SPET_BUTTON_TILE = ::SPET_BUTTON_TILE, ///< A button that allows the player to select a tile, and triggers an event with the tile.
SPET_BUTTON_VEHICLE = ::SPET_BUTTON_VEHICLE, ///< A button that allows the player to select a vehicle, and triggers an event wih the vehicle.
SPET_BUTTON_VEHICLE = ::SPET_BUTTON_VEHICLE, ///< A button that allows the player to select a vehicle, and triggers an event with the vehicle.
};
/**

View File

@@ -13,7 +13,7 @@
#include "../../safeguards.h"
ScriptStoryPageElementList::ScriptStoryPageElementList(ScriptStoryPage::StoryPageID story_page_id)
ScriptStoryPageElementList::ScriptStoryPageElementList(StoryPageID story_page_id)
{
if (!ScriptStoryPage::IsValidStoryPage(story_page_id)) return;

View File

@@ -24,7 +24,7 @@ public:
/**
* @param story_page_id The page id of the story page of which all page elements should be included in the list.
*/
ScriptStoryPageElementList(ScriptStoryPage::StoryPageID story_page_id);
ScriptStoryPageElementList(StoryPageID story_page_id);
};
#endif /* SCRIPT_STORYPAGEELEMENTLIST_HPP */

View File

@@ -16,10 +16,9 @@
ScriptStoryPageList::ScriptStoryPageList(ScriptCompany::CompanyID company)
{
uint8_t c = company;
if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY;
::CompanyID c = ScriptCompany::FromScriptCompanyID(company);
ScriptList::FillList<StoryPage>(this,
[c](const StoryPage *p) {return p->company == c || p->company == INVALID_COMPANY; }
[c](const StoryPage *p) {return p->company == c || p->company == CompanyID::Invalid(); }
);
}

View File

@@ -31,23 +31,26 @@
return ::Subsidy::Get(subsidy_id)->IsAwarded();
}
/* static */ bool ScriptSubsidy::Create(CargoID cargo_type, SubsidyParticipantType from_type, SQInteger from_id, SubsidyParticipantType to_type, SQInteger to_id)
/* static */ bool ScriptSubsidy::Create(CargoType cargo_type, SubsidyParticipantType from_type, SQInteger from_id, SubsidyParticipantType to_type, SQInteger to_id)
{
EnforceDeityMode(false);
EnforcePrecondition(false, ScriptCargo::IsValidCargo(cargo_type));
EnforcePrecondition(false, from_type == SPT_INDUSTRY || from_type == SPT_TOWN);
EnforcePrecondition(false, to_type == SPT_INDUSTRY || to_type == SPT_TOWN);
EnforcePrecondition(false, (from_type == SPT_INDUSTRY && ScriptIndustry::IsValidIndustry(from_id)) || (from_type == SPT_TOWN && ScriptTown::IsValidTown(from_id)));
EnforcePrecondition(false, (to_type == SPT_INDUSTRY && ScriptIndustry::IsValidIndustry(to_id)) || (to_type == SPT_TOWN && ScriptTown::IsValidTown(to_id)));
EnforcePrecondition(false, (from_type == SPT_INDUSTRY && ScriptIndustry::IsValidIndustry(static_cast<IndustryID>(from_id))) || (from_type == SPT_TOWN && ScriptTown::IsValidTown(static_cast<TownID>(from_id))));
EnforcePrecondition(false, (to_type == SPT_INDUSTRY && ScriptIndustry::IsValidIndustry(static_cast<IndustryID>(to_id))) || (to_type == SPT_TOWN && ScriptTown::IsValidTown(static_cast<TownID>(to_id))));
return ScriptObject::Command<CMD_CREATE_SUBSIDY>::Do(cargo_type, (::SourceType)from_type, from_id, (::SourceType)to_type, to_id);
Source from{static_cast<SourceID>(from_id), static_cast<SourceType>(from_type)};
Source to{static_cast<SourceID>(to_id), static_cast<SourceType>(to_type)};
return ScriptObject::Command<CMD_CREATE_SUBSIDY>::Do(cargo_type, from, to);
}
/* static */ ScriptCompany::CompanyID ScriptSubsidy::GetAwardedTo(SubsidyID subsidy_id)
{
if (!IsAwarded(subsidy_id)) return ScriptCompany::COMPANY_INVALID;
return (ScriptCompany::CompanyID)((uint8_t)::Subsidy::Get(subsidy_id)->awarded);
return ScriptCompany::ToScriptCompanyID(::Subsidy::Get(subsidy_id)->awarded);
}
/* static */ ScriptDate::Date ScriptSubsidy::GetExpireDate(SubsidyID subsidy_id)
@@ -57,13 +60,13 @@
TimerGameEconomy::YearMonthDay ymd = TimerGameEconomy::ConvertDateToYMD(TimerGameEconomy::date);
ymd.day = 1;
auto m = ymd.month + ::Subsidy::Get(subsidy_id)->remaining;
ymd.month = (m - 1) % 12 + 1;
ymd.year += (m - 1) / 12;
ymd.month = m % 12;
ymd.year += TimerGameEconomy::Year{m / 12};
return (ScriptDate::Date)TimerGameEconomy::ConvertYMDToDate(ymd.year, ymd.month, ymd.day).base();
}
/* static */ CargoID ScriptSubsidy::GetCargoType(SubsidyID subsidy_id)
/* static */ CargoType ScriptSubsidy::GetCargoType(SubsidyID subsidy_id)
{
if (!IsValidSubsidy(subsidy_id)) return INVALID_CARGO;
@@ -74,26 +77,26 @@
{
if (!IsValidSubsidy(subsidy_id)) return SPT_INVALID;
return (SubsidyParticipantType)(uint)::Subsidy::Get(subsidy_id)->src_type;
return static_cast<SubsidyParticipantType>(::Subsidy::Get(subsidy_id)->src.type);
}
/* static */ SQInteger ScriptSubsidy::GetSourceIndex(SubsidyID subsidy_id)
{
if (!IsValidSubsidy(subsidy_id)) return INVALID_SOURCE;
if (!IsValidSubsidy(subsidy_id)) return Source::Invalid;
return ::Subsidy::Get(subsidy_id)->src;
return ::Subsidy::Get(subsidy_id)->src.id;
}
/* static */ ScriptSubsidy::SubsidyParticipantType ScriptSubsidy::GetDestinationType(SubsidyID subsidy_id)
{
if (!IsValidSubsidy(subsidy_id)) return SPT_INVALID;
return (SubsidyParticipantType)(uint)::Subsidy::Get(subsidy_id)->dst_type;
return static_cast<SubsidyParticipantType>(::Subsidy::Get(subsidy_id)->dst.type);
}
/* static */ SQInteger ScriptSubsidy::GetDestinationIndex(SubsidyID subsidy_id)
{
if (!IsValidSubsidy(subsidy_id)) return INVALID_SOURCE;
if (!IsValidSubsidy(subsidy_id)) return Source::Invalid;
return ::Subsidy::Get(subsidy_id)->dst;
return ::Subsidy::Get(subsidy_id)->dst.id;
}

View File

@@ -12,6 +12,7 @@
#include "script_company.hpp"
#include "script_date.hpp"
#include "../../subsidy_type.h"
/**
* Class that handles all subsidy related functions.
@@ -63,7 +64,7 @@ public:
* @pre (to_type == SPT_INDUSTRY && ScriptIndustry::IsValidIndustry(to_id)) || (to_type == SPT_TOWN && ScriptTown::IsValidTown(to_id))
* @api -ai
*/
static bool Create(CargoID cargo_type, SubsidyParticipantType from_type, SQInteger from_id, SubsidyParticipantType to_type, SQInteger to_id);
static bool Create(CargoType cargo_type, SubsidyParticipantType from_type, SQInteger from_id, SubsidyParticipantType to_type, SQInteger to_id);
/**
* Get the company index of the company this subsidy is awarded to.
@@ -93,7 +94,7 @@ public:
* @pre IsValidSubsidy(subsidy_id).
* @return The cargo type to transport.
*/
static CargoID GetCargoType(SubsidyID subsidy_id);
static CargoType GetCargoType(SubsidyID subsidy_id);
/**
* Returns the type of source of subsidy.

View File

@@ -20,6 +20,10 @@
#include "../../safeguards.h"
EncodedString RawText::GetEncodedText()
{
return ::GetEncodedString(STR_JUST_RAW_STRING, this->text);
}
ScriptText::ScriptText(HSQUIRRELVM vm)
{
@@ -33,7 +37,7 @@ ScriptText::ScriptText(HSQUIRRELVM vm)
if (SQ_FAILED(sq_getinteger(vm, 2, &sqstring))) {
throw sq_throwerror(vm, "First argument must be a valid StringID");
}
this->string = sqstring;
this->string = StringIndexInTab(sqstring);
/* The rest of the parameters must be arguments. */
for (int i = 0; i < nparam - 1; i++) {
@@ -153,17 +157,17 @@ SQInteger ScriptText::_set(HSQUIRRELVM vm)
return this->_SetParam(k, vm);
}
std::string ScriptText::GetEncodedText()
EncodedString ScriptText::GetEncodedText()
{
ScriptTextList seen_texts;
ParamList params;
int param_count = 0;
std::string result;
auto output = std::back_inserter(result);
StringBuilder builder(result);
this->_FillParamList(params, seen_texts);
this->_GetEncodedText(output, param_count, params, true);
this->_GetEncodedText(builder, param_count, params, true);
if (param_count > SCRIPT_TEXT_MAX_PARAMETERS) throw Script_FatalError(fmt::format("{}: Too many parameters", GetGameStringName(this->string)));
return result;
return ::EncodedString{std::move(result)};
}
void ScriptText::_FillParamList(ParamList &params, ScriptTextList &seen_texts)
@@ -185,39 +189,50 @@ void ScriptText::_FillParamList(ParamList &params, ScriptTextList &seen_texts)
static Param dummy = 0;
int nb_extra = SCRIPT_TEXT_MAX_PARAMETERS - (int)params.size();
for (int i = 0; i < nb_extra; i++)
params.emplace_back(-1, i, &dummy);
params.emplace_back(StringIndexInTab(-1), i, &dummy);
}
}
void ScriptText::ParamCheck::Encode(std::back_insert_iterator<std::string> &output, const char *cmd)
void ScriptText::ParamCheck::Encode(StringBuilder &builder, std::string_view cmd)
{
if (this->cmd == nullptr) this->cmd = cmd;
if (this->cmd.empty()) this->cmd = cmd;
if (this->used) return;
struct visitor {
std::back_insert_iterator<std::string> &output;
StringBuilder &builder;
void operator()(std::string value)
{
this->builder.PutUtf8(SCC_ENCODED_STRING);
StrMakeValidInPlace(value, {StringValidationSetting::ReplaceWithQuestionMark, StringValidationSetting::AllowNewline, StringValidationSetting::ReplaceTabCrNlWithSpace});
this->builder.Put(value);
}
void operator()(const SQInteger &value)
{
this->builder.PutUtf8(SCC_ENCODED_NUMERIC);
this->builder.PutIntegerBase(value, 16);
}
void operator()(const std::string &value) { fmt::format_to(this->output, ":\"{}\"", value); }
void operator()(const SQInteger &value) { fmt::format_to(this->output, ":{:X}", value); }
void operator()(const ScriptTextRef &value)
{
fmt::format_to(this->output, ":");
Utf8Encode(this->output, SCC_ENCODED);
fmt::format_to(this->output, "{:X}", value->string);
this->builder.PutUtf8(SCC_ENCODED);
this->builder.PutIntegerBase(value->string.base(), 16);
}
};
std::visit(visitor{output}, *this->param);
builder.PutUtf8(SCC_RECORD_SEPARATOR);
std::visit(visitor{builder}, *this->param);
this->used = true;
}
void ScriptText::_GetEncodedText(std::back_insert_iterator<std::string> &output, int &param_count, ParamSpan args, bool first)
void ScriptText::_GetEncodedText(StringBuilder &builder, int &param_count, ParamSpan args, bool first)
{
const std::string &name = GetGameStringName(this->string);
if (first) {
Utf8Encode(output, SCC_ENCODED);
fmt::format_to(output, "{:X}", this->string);
builder.PutUtf8(SCC_ENCODED);
builder.PutIntegerBase(this->string.base(), 16);
}
const StringParams &params = GetGameStringParams(this->string);
@@ -241,7 +256,7 @@ void ScriptText::_GetEncodedText(std::back_insert_iterator<std::string> &output,
case StringParam::RAW_STRING:
{
ParamCheck &p = *get_next_arg();
p.Encode(output, cur_param.cmd);
p.Encode(builder, cur_param.cmd);
if (p.cmd != cur_param.cmd) throw 1;
if (!std::holds_alternative<std::string>(*p.param)) ScriptLog::Error(fmt::format("{}({}): {{{}}} expects a raw string", name, param_count + 1, cur_param.cmd));
break;
@@ -250,7 +265,7 @@ void ScriptText::_GetEncodedText(std::back_insert_iterator<std::string> &output,
case StringParam::STRING:
{
ParamCheck &p = *get_next_arg();
p.Encode(output, cur_param.cmd);
p.Encode(builder, cur_param.cmd);
if (p.cmd != cur_param.cmd) throw 1;
if (!std::holds_alternative<ScriptTextRef>(*p.param)) {
ScriptLog::Error(fmt::format("{}({}): {{{}}} expects a GSText", name, param_count + 1, cur_param.cmd));
@@ -259,11 +274,13 @@ void ScriptText::_GetEncodedText(std::back_insert_iterator<std::string> &output,
}
int count = 0;
ScriptTextRef &ref = std::get<ScriptTextRef>(*p.param);
ref->_GetEncodedText(output, count, args.subspan(idx), false);
ref->_GetEncodedText(builder, count, args.subspan(idx), false);
if (++count != cur_param.consumes) {
ScriptLog::Warning(fmt::format("{}({}): {{{}}} expects {} to be consumed, but {} consumes {}", name, param_count + 1, cur_param.cmd, cur_param.consumes - 1, GetGameStringName(ref->string), count - 1));
/* Fill missing params if needed. */
for (int i = count; i < cur_param.consumes; i++) fmt::format_to(output, ":0");
for (int i = count; i < cur_param.consumes; i++) {
builder.PutUtf8(SCC_RECORD_SEPARATOR);
}
}
skip_args(cur_param.consumes - 1);
break;
@@ -272,7 +289,7 @@ void ScriptText::_GetEncodedText(std::back_insert_iterator<std::string> &output,
default:
for (int i = 0; i < cur_param.consumes; i++) {
ParamCheck &p = *get_next_arg();
p.Encode(output, i == 0 ? cur_param.cmd : nullptr);
p.Encode(builder, i == 0 ? cur_param.cmd : "");
if (i == 0 && p.cmd != cur_param.cmd) throw 1;
if (!std::holds_alternative<SQInteger>(*p.param)) ScriptLog::Error(fmt::format("{}({}): {{{}}} expects an integer", name, param_count + i + 1, cur_param.cmd));
}
@@ -288,6 +305,5 @@ void ScriptText::_GetEncodedText(std::back_insert_iterator<std::string> &output,
const std::string Text::GetDecodedText()
{
::SetDParamStr(0, this->GetEncodedText());
return ::GetString(STR_JUST_RAW_STRING);
return this->GetEncodedText().GetDecodedString();
}

View File

@@ -11,6 +11,8 @@
#define SCRIPT_TEXT_HPP
#include "script_object.hpp"
#include "../../strings_func.h"
#include "../../core/string_builder.hpp"
#include <variant>
@@ -25,7 +27,7 @@ public:
* @return A string.
* @api -all
*/
virtual std::string GetEncodedText() = 0;
virtual EncodedString GetEncodedText() = 0;
/**
* Convert a #ScriptText into a decoded normal string.
@@ -43,7 +45,7 @@ class RawText : public Text {
public:
RawText(const std::string &text) : text(text) {}
std::string GetEncodedText() override { return this->text; }
EncodedString GetEncodedText() override;
private:
const std::string text;
};
@@ -124,7 +126,7 @@ public:
/**
* @api -all
*/
std::string GetEncodedText() override;
EncodedString GetEncodedText() override;
private:
using ScriptTextRef = ScriptObjectRef<ScriptText>;
@@ -132,21 +134,21 @@ private:
using Param = std::variant<SQInteger, std::string, ScriptTextRef>;
struct ParamCheck {
StringID owner;
StringIndexInTab owner;
int idx;
Param *param;
bool used = false;
const char *cmd = nullptr;
std::string_view cmd;
ParamCheck(StringID owner, int idx, Param *param) : owner(owner), idx(idx), param(param) {}
ParamCheck(StringIndexInTab owner, int idx, Param *param) : owner(owner), idx(idx), param(param) {}
void Encode(std::back_insert_iterator<std::string> &output, const char *cmd);
void Encode(StringBuilder &output, std::string_view cmd);
};
using ParamList = std::vector<ParamCheck>;
using ParamSpan = std::span<ParamCheck>;
StringID string;
StringIndexInTab string;
std::array<Param, SCRIPT_TEXT_MAX_PARAMETERS> param = {};
int paramc = 0;
@@ -167,7 +169,7 @@ private:
* @param args The parameters to be consumed.
* @param first Whether it's the first call in the recursion.
*/
void _GetEncodedText(std::back_insert_iterator<std::string> &output, int &param_count, ParamSpan args, bool first);
void _GetEncodedText(StringBuilder &output, int &param_count, ParamSpan args, bool first);
/**
* Set a parameter, where the value is the first item on the stack.

View File

@@ -130,14 +130,14 @@
{
if (!::IsValidTile(tile)) return false;
return (::IsTileType(tile, MP_CLEAR) && ::GetRawClearGround(tile) == ::CLEAR_ROCKS);
return (::IsTileType(tile, MP_CLEAR) && ::GetClearGround(tile) == ::CLEAR_ROCKS);
}
/* static */ bool ScriptTile::IsRoughTile(TileIndex tile)
{
if (!::IsValidTile(tile)) return false;
return (::IsTileType(tile, MP_CLEAR) && ::GetRawClearGround(tile) == ::CLEAR_ROUGH);
return (::IsTileType(tile, MP_CLEAR) && ::GetClearGround(tile) == ::CLEAR_ROUGH);
}
/* static */ bool ScriptTile::IsSnowTile(TileIndex tile)
@@ -209,7 +209,7 @@
if (::IsTileType(tile, MP_HOUSE)) return ScriptCompany::COMPANY_INVALID;
if (::IsTileType(tile, MP_INDUSTRY)) return ScriptCompany::COMPANY_INVALID;
return ScriptCompany::ResolveCompanyID((ScriptCompany::CompanyID)(uint8_t)::GetTileOwner(tile));
return ScriptCompany::ResolveCompanyID(ScriptCompany::ToScriptCompanyID(::GetTileOwner(tile)));
}
/* static */ bool ScriptTile::HasTransportType(TileIndex tile, TransportType transport_type)
@@ -224,7 +224,7 @@
}
}
/* static */ SQInteger ScriptTile::GetCargoAcceptance(TileIndex tile, CargoID cargo_type, SQInteger width, SQInteger height, SQInteger radius)
/* static */ SQInteger ScriptTile::GetCargoAcceptance(TileIndex tile, CargoType cargo_type, SQInteger width, SQInteger height, SQInteger radius)
{
if (!::IsValidTile(tile) || width <= 0 || height <= 0 || radius < 0 || !ScriptCargo::IsValidCargo(cargo_type)) return -1;
@@ -232,7 +232,7 @@
return acceptance[cargo_type];
}
/* static */ SQInteger ScriptTile::GetCargoProduction(TileIndex tile, CargoID cargo_type, SQInteger width, SQInteger height, SQInteger radius)
/* static */ SQInteger ScriptTile::GetCargoProduction(TileIndex tile, CargoType cargo_type, SQInteger width, SQInteger height, SQInteger radius)
{
if (!::IsValidTile(tile) || width <= 0 || height <= 0 || radius < 0 || !ScriptCargo::IsValidCargo(cargo_type)) return -1;
@@ -310,20 +310,20 @@
/* static */ TownID ScriptTile::GetTownAuthority(TileIndex tile)
{
if (!::IsValidTile(tile)) return INVALID_TOWN;
if (!::IsValidTile(tile)) return TownID::Invalid();
Town *town = ::ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
if (town == nullptr) return INVALID_TOWN;
if (town == nullptr) return TownID::Invalid();
return town->index;
}
/* static */ TownID ScriptTile::GetClosestTown(TileIndex tile)
{
if (!::IsValidTile(tile)) return INVALID_TOWN;
if (!::IsValidTile(tile)) return TownID::Invalid();
Town *town = ::ClosestTownFromTile(tile, UINT_MAX);
if (town == nullptr) return INVALID_TOWN;
if (town == nullptr) return TownID::Invalid();
return town->index;
}

View File

@@ -376,7 +376,7 @@ public:
* @pre radius >= 0.
* @return Values below 8 mean no acceptance; the more the better.
*/
static SQInteger GetCargoAcceptance(TileIndex tile, CargoID cargo_type, SQInteger width, SQInteger height, SQInteger radius);
static SQInteger GetCargoAcceptance(TileIndex tile, CargoType cargo_type, SQInteger width, SQInteger height, SQInteger radius);
/**
* Checks how many producers in the radius produces this cargo.
@@ -393,7 +393,7 @@ public:
* @pre radius >= 0.
* @return The number of producers that produce this cargo within radius of the tile.
*/
static SQInteger GetCargoProduction(TileIndex tile, CargoID cargo_type, SQInteger width, SQInteger height, SQInteger radius);
static SQInteger GetCargoProduction(TileIndex tile, CargoType cargo_type, SQInteger width, SQInteger height, SQInteger radius);
/**
* Get the manhattan distance from the tile to the tile.

View File

@@ -15,6 +15,14 @@
#include "../../safeguards.h"
bool ScriptTileList::SaveObject(HSQUIRRELVM vm)
{
sq_pushstring(vm, "TileList");
if (!ScriptList::SaveObject(vm)) return false;
sq_remove(vm, -2);
return true;
}
void ScriptTileList::AddRectangle(TileIndex t1, TileIndex t2)
{
if (!::IsValidTile(t1)) return;
@@ -95,7 +103,7 @@ ScriptTileList_IndustryAccepting::ScriptTileList_IndustryAccepting(IndustryID in
/* Only add the tile if it accepts the cargo (sometimes just 1 tile of an
* industry triggers the acceptance). */
CargoArray acceptance = ::GetAcceptanceAroundTiles(cur_tile, 1, 1, radius);
if (std::none_of(std::begin(i->accepted), std::end(i->accepted), [&acceptance](const auto &a) { return ::IsValidCargoID(a.cargo) && acceptance[a.cargo] != 0; })) continue;
if (std::none_of(std::begin(i->accepted), std::end(i->accepted), [&acceptance](const auto &a) { return ::IsValidCargoType(a.cargo) && acceptance[a.cargo] != 0; })) continue;
this->AddTile(cur_tile);
}
@@ -130,20 +138,20 @@ ScriptTileList_StationType::ScriptTileList_StationType(StationID station_id, Scr
const StationRect *rect = &::Station::Get(station_id)->rect;
uint station_type_value = 0;
EnumBitSet<StationType, uint8_t> station_types = {};
/* Convert ScriptStation::StationType to ::StationType, but do it in a
* bitmask, so we can scan for multiple entries at the same time. */
if ((station_type & ScriptStation::STATION_TRAIN) != 0) station_type_value |= (1 << ::STATION_RAIL);
if ((station_type & ScriptStation::STATION_TRUCK_STOP) != 0) station_type_value |= (1 << ::STATION_TRUCK);
if ((station_type & ScriptStation::STATION_BUS_STOP) != 0) station_type_value |= (1 << ::STATION_BUS);
if ((station_type & ScriptStation::STATION_AIRPORT) != 0) station_type_value |= (1 << ::STATION_AIRPORT) | (1 << ::STATION_OILRIG);
if ((station_type & ScriptStation::STATION_DOCK) != 0) station_type_value |= (1 << ::STATION_DOCK) | (1 << ::STATION_OILRIG);
if ((station_type & ScriptStation::STATION_TRAIN) != 0) station_types.Set(::StationType::Rail);
if ((station_type & ScriptStation::STATION_TRUCK_STOP) != 0) station_types.Set(::StationType::Truck);
if ((station_type & ScriptStation::STATION_BUS_STOP) != 0) station_types.Set(::StationType::Bus);
if ((station_type & ScriptStation::STATION_AIRPORT) != 0) station_types.Set(::StationType::Airport).Set(::StationType::Oilrig);
if ((station_type & ScriptStation::STATION_DOCK) != 0) station_types.Set(::StationType::Dock).Set(::StationType::Oilrig);
TileArea ta(::TileXY(rect->left, rect->top), rect->Width(), rect->Height());
for (TileIndex cur_tile : ta) {
if (!::IsTileType(cur_tile, MP_STATION)) continue;
if (::GetStationIndex(cur_tile) != station_id) continue;
if (!HasBit(station_type_value, ::GetStationType(cur_tile))) continue;
if (!station_types.Test(::GetStationType(cur_tile))) continue;
this->AddTile(cur_tile);
}
}

View File

@@ -12,6 +12,7 @@
#include "script_station.hpp"
#include "script_list.hpp"
#include "../../industry_type.h"
/**
* Creates an empty list, in which you can add tiles.
@@ -19,6 +20,8 @@
* @ingroup ScriptList
*/
class ScriptTileList : public ScriptList {
protected:
virtual bool SaveObject(HSQUIRRELVM) override;
public:
/**
* Adds the rectangle between tile_from and tile_to to the to-be-evaluated tiles.

View File

@@ -18,6 +18,7 @@
#include "../../station_base.h"
#include "../../landscape.h"
#include "../../town_cmd.h"
#include "table/strings.h"
#include "../../safeguards.h"
@@ -36,8 +37,7 @@
{
if (!IsValidTown(town_id)) return std::nullopt;
::SetDParam(0, town_id);
return GetString(STR_TOWN_NAME);
return ::StrMakeValid(::GetString(STR_TOWN_NAME, town_id));
}
/* static */ bool ScriptTown::SetName(TownID town_id, Text *name)
@@ -62,7 +62,7 @@
EnforceDeityMode(false);
EnforcePrecondition(false, IsValidTown(town_id));
return ScriptObject::Command<CMD_TOWN_SET_TEXT>::Do(town_id, text != nullptr ? text->GetEncodedText() : std::string{});
return ScriptObject::Command<CMD_TOWN_SET_TEXT>::Do(town_id, text != nullptr ? text->GetEncodedText() : EncodedString{});
}
/* static */ SQInteger ScriptTown::GetPopulation(TownID town_id)
@@ -86,33 +86,33 @@
return t->xy;
}
/* static */ SQInteger ScriptTown::GetLastMonthProduction(TownID town_id, CargoID cargo_id)
/* static */ SQInteger ScriptTown::GetLastMonthProduction(TownID town_id, CargoType cargo_type)
{
if (!IsValidTown(town_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo_type)) return -1;
const Town *t = ::Town::Get(town_id);
return t->supplied[cargo_id].old_max;
return t->supplied[cargo_type].old_max;
}
/* static */ SQInteger ScriptTown::GetLastMonthSupplied(TownID town_id, CargoID cargo_id)
/* static */ SQInteger ScriptTown::GetLastMonthSupplied(TownID town_id, CargoType cargo_type)
{
if (!IsValidTown(town_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo_type)) return -1;
const Town *t = ::Town::Get(town_id);
return t->supplied[cargo_id].old_act;
return t->supplied[cargo_type].old_act;
}
/* static */ SQInteger ScriptTown::GetLastMonthTransportedPercentage(TownID town_id, CargoID cargo_id)
/* static */ SQInteger ScriptTown::GetLastMonthTransportedPercentage(TownID town_id, CargoType cargo_type)
{
if (!IsValidTown(town_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo_type)) return -1;
const Town *t = ::Town::Get(town_id);
return ::ToPercent8(t->GetPercentTransported(cargo_id));
return ::ToPercent8(t->GetPercentTransported(cargo_type));
}
/* static */ SQInteger ScriptTown::GetLastMonthReceived(TownID town_id, ScriptCargo::TownEffect towneffect_id)
@@ -214,7 +214,7 @@
EnforceCompanyModeValid(false);
if (!IsValidTown(town_id)) return false;
return ::HasBit(::Town::Get(town_id)->statues, ScriptObject::GetCompany());
return ::Town::Get(town_id)->statues.Test(ScriptObject::GetCompany());
}
/* static */ bool ScriptTown::IsCity(TownID town_id)
@@ -243,7 +243,7 @@
EnforceCompanyModeValid(ScriptCompany::COMPANY_INVALID);
if (!IsValidTown(town_id)) return ScriptCompany::COMPANY_INVALID;
return (ScriptCompany::CompanyID)(int8_t)::Town::Get(town_id)->exclusivity;
return ScriptCompany::ToScriptCompanyID(::Town::Get(town_id)->exclusivity);
}
/* static */ SQInteger ScriptTown::GetExclusiveRightsDuration(TownID town_id)
@@ -258,7 +258,7 @@
EnforceCompanyModeValid(false);
if (!IsValidTown(town_id)) return false;
return HasBit(::GetMaskOfTownActions(ScriptObject::GetCompany(), ::Town::Get(town_id)), town_action);
return ::GetMaskOfTownActions(ScriptObject::GetCompany(), ::Town::Get(town_id)).Test(::TownAction(town_action));
}
/* static */ bool ScriptTown::PerformTownAction(TownID town_id, TownAction town_action)
@@ -267,7 +267,7 @@
EnforcePrecondition(false, IsValidTown(town_id));
EnforcePrecondition(false, IsActionAvailable(town_id, town_action));
return ScriptObject::Command<CMD_DO_TOWN_ACTION>::Do(town_id, town_action);
return ScriptObject::Command<CMD_DO_TOWN_ACTION>::Do(town_id, ::TownAction(town_action));
}
/* static */ bool ScriptTown::ExpandTown(TownID town_id, SQInteger houses)
@@ -317,22 +317,23 @@
ScriptCompany::CompanyID company = ScriptCompany::ResolveCompanyID(company_id);
if (company == ScriptCompany::COMPANY_INVALID) return TOWN_RATING_INVALID;
::CompanyID c = ScriptCompany::FromScriptCompanyID(company);
const Town *t = ::Town::Get(town_id);
if (!HasBit(t->have_ratings, company)) {
if (!t->have_ratings.Test(c)) {
return TOWN_RATING_NONE;
} else if (t->ratings[company] <= RATING_APPALLING) {
} else if (t->ratings[c] <= RATING_APPALLING) {
return TOWN_RATING_APPALLING;
} else if (t->ratings[company] <= RATING_VERYPOOR) {
} else if (t->ratings[c] <= RATING_VERYPOOR) {
return TOWN_RATING_VERY_POOR;
} else if (t->ratings[company] <= RATING_POOR) {
} else if (t->ratings[c] <= RATING_POOR) {
return TOWN_RATING_POOR;
} else if (t->ratings[company] <= RATING_MEDIOCRE) {
} else if (t->ratings[c] <= RATING_MEDIOCRE) {
return TOWN_RATING_MEDIOCRE;
} else if (t->ratings[company] <= RATING_GOOD) {
} else if (t->ratings[c] <= RATING_GOOD) {
return TOWN_RATING_GOOD;
} else if (t->ratings[company] <= RATING_VERYGOOD) {
} else if (t->ratings[c] <= RATING_VERYGOOD) {
return TOWN_RATING_VERY_GOOD;
} else if (t->ratings[company] <= RATING_EXCELLENT) {
} else if (t->ratings[c] <= RATING_EXCELLENT) {
return TOWN_RATING_EXCELLENT;
} else {
return TOWN_RATING_OUTSTANDING;
@@ -346,21 +347,22 @@
if (company == ScriptCompany::COMPANY_INVALID) return TOWN_RATING_INVALID;
const Town *t = ::Town::Get(town_id);
return t->ratings[company];
return t->ratings[ScriptCompany::FromScriptCompanyID(company)];
}
/* static */ bool ScriptTown::ChangeRating(TownID town_id, ScriptCompany::CompanyID company_id, SQInteger delta)
/* static */ bool ScriptTown::ChangeRating(TownID town_id, ScriptCompany::CompanyID company, SQInteger delta)
{
EnforceDeityMode(false);
EnforcePrecondition(false, IsValidTown(town_id));
ScriptCompany::CompanyID company = ScriptCompany::ResolveCompanyID(company_id);
company = ScriptCompany::ResolveCompanyID(company);
EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID);
::CompanyID c = ScriptCompany::FromScriptCompanyID(company);
const Town *t = ::Town::Get(town_id);
int16_t new_rating = Clamp(t->ratings[company] + delta, RATING_MINIMUM, RATING_MAXIMUM);
if (new_rating == t->ratings[company]) return false;
int16_t new_rating = Clamp(t->ratings[c] + delta, RATING_MINIMUM, RATING_MAXIMUM);
if (new_rating == t->ratings[c]) return false;
return ScriptObject::Command<CMD_TOWN_RATING>::Do(town_id, (::CompanyID)company_id, new_rating);
return ScriptObject::Command<CMD_TOWN_RATING>::Do(town_id, c, new_rating);
}
/* static */ SQInteger ScriptTown::GetAllowedNoise(TownID town_id)
@@ -374,7 +376,7 @@
int num = 0;
for (const Station *st : Station::Iterate()) {
if (st->town == t && (st->facilities & FACIL_AIRPORT) && st->airport.type != AT_OILRIG) num++;
if (st->town == t && st->facilities.Test(StationFacility::Airport) && st->airport.type != AT_OILRIG) num++;
}
return std::max(0, 2 - num);
}

View File

@@ -12,6 +12,7 @@
#include "script_cargo.hpp"
#include "script_company.hpp"
#include "../../town.h"
#include "../../town_type.h"
/**
@@ -31,49 +32,49 @@ public:
* absolute percentage, so 10% becomes 35%, with a max of 99%)
* for all stations within 10 tiles.
*/
TOWN_ACTION_ADVERTISE_SMALL = 0,
TOWN_ACTION_ADVERTISE_SMALL = to_underlying(::TownAction::AdvertiseSmall),
/**
* The cargo ratings temporary gains 44% of rating (in
* absolute percentage, so 10% becomes 54%, with a max of 99%)
* for all stations within 15 tiles.
*/
TOWN_ACTION_ADVERTISE_MEDIUM = 1,
TOWN_ACTION_ADVERTISE_MEDIUM = to_underlying(::TownAction::AdvertiseMedium),
/**
* The cargo ratings temporary gains 63% of rating (in
* absolute percentage, so 10% becomes 73%, with a max of 99%)
* for all stations within 20 tiles.
*/
TOWN_ACTION_ADVERTISE_LARGE = 2,
TOWN_ACTION_ADVERTISE_LARGE = to_underlying(::TownAction::AdvertiseLarge),
/**
* Rebuild the roads of this town for 6 economy-months.
* @see \ref ScriptEconomyTime
*/
TOWN_ACTION_ROAD_REBUILD = 3,
TOWN_ACTION_ROAD_REBUILD = to_underlying(::TownAction::RoadRebuild),
/**
* Build a statue in this town.
*/
TOWN_ACTION_BUILD_STATUE = 4,
TOWN_ACTION_BUILD_STATUE = to_underlying(::TownAction::BuildStatue),
/**
* Fund the creation of extra buildings for 3 economy-months.
* @see \ref ScriptEconomyTime
*/
TOWN_ACTION_FUND_BUILDINGS = 5,
TOWN_ACTION_FUND_BUILDINGS = to_underlying(::TownAction::FundBuildings),
/**
* Buy exclusive rights for this town for 12 economy-months.
* @see \ref ScriptEconomyTime
*/
TOWN_ACTION_BUY_RIGHTS = 6,
TOWN_ACTION_BUY_RIGHTS = to_underlying(::TownAction::BuyRights),
/**
* Bribe the town in order to get a higher rating.
*/
TOWN_ACTION_BRIBE = 7,
TOWN_ACTION_BRIBE = to_underlying(::TownAction::Bribe),
};
/**
@@ -196,42 +197,42 @@ public:
/**
* Get the total last economy-month's production of the given cargo at a town.
* @param town_id The index of the town.
* @param cargo_id The index of the cargo.
* @param cargo_type The index of the cargo.
* @pre IsValidTown(town_id).
* @pre ScriptCargo::IsValidCargo(cargo_id).
* @pre ScriptCargo::IsValidCargo(cargo_type).
* @return The last economy-month's production of the given cargo for this town.
* @see \ref ScriptEconomyTime
*/
static SQInteger GetLastMonthProduction(TownID town_id, CargoID cargo_id);
static SQInteger GetLastMonthProduction(TownID town_id, CargoType cargo_type);
/**
* Get the total amount of cargo supplied from a town last economy-month.
* @param town_id The index of the town.
* @param cargo_id The index of the cargo.
* @param cargo_type The index of the cargo.
* @pre IsValidTown(town_id).
* @pre ScriptCargo::IsValidCargo(cargo_id).
* @pre ScriptCargo::IsValidCargo(cargo_type).
* @return The amount of cargo supplied for transport from this town last economy-month.
* @see \ref ScriptEconomyTime
*/
static SQInteger GetLastMonthSupplied(TownID town_id, CargoID cargo_id);
static SQInteger GetLastMonthSupplied(TownID town_id, CargoType cargo_type);
/**
* Get the percentage of transported production of the given cargo at a town last economy-month.
* @param town_id The index of the town.
* @param cargo_id The index of the cargo.
* @param cargo_type The index of the cargo.
* @pre IsValidTown(town_id).
* @pre ScriptCargo::IsValidCargo(cargo_id).
* @pre ScriptCargo::IsValidCargo(cargo_type).
* @return The percentage of given cargo transported from this town last economy-month.
* @see \ref ScriptEconomyTime
*/
static SQInteger GetLastMonthTransportedPercentage(TownID town_id, CargoID cargo_id);
static SQInteger GetLastMonthTransportedPercentage(TownID town_id, CargoType cargo_type);
/**
* Get the total amount of cargo effects received by a town last economy-month.
* @param town_id The index of the town.
* @param towneffect_id The index of the cargo.
* @pre IsValidTown(town_id).
* @pre ScriptCargo::IsValidTownEffect(cargo_id).
* @pre ScriptCargo::IsValidTownEffect(cargo_type).
* @return The amount of cargo received by this town last economy-month for this cargo effect.
* @see \ref ScriptEconomyTime
*/

View File

@@ -102,13 +102,13 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance)
EnforceDeityOrCompanyModeValid(false);
/* Build the piece of road on the 'start' side of the tunnel */
TileIndex end = ScriptObject::GetCallbackVariable(0);
TileIndex start = ScriptTunnel::GetOtherTunnelEnd(end);
TileIndex end(ScriptObject::GetCallbackVariable(0));
TileIndex start{ScriptTunnel::GetOtherTunnelEnd(end)};
DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
return ScriptObject::Command<CMD_BUILD_ROAD>::Do(&::_DoCommandReturnBuildTunnel2, start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2), ScriptRoad::GetRoadType(), DRD_NONE, 0);
return ScriptObject::Command<CMD_BUILD_ROAD>::Do(&::_DoCommandReturnBuildTunnel2, start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2), ScriptRoad::GetRoadType(), DRD_NONE, TownID::Invalid());
}
/* static */ bool ScriptTunnel::_BuildTunnelRoad2()
@@ -116,13 +116,13 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance)
EnforceDeityOrCompanyModeValid(false);
/* Build the piece of road on the 'end' side of the tunnel */
TileIndex end = ScriptObject::GetCallbackVariable(0);
TileIndex start = ScriptTunnel::GetOtherTunnelEnd(end);
TileIndex end(ScriptObject::GetCallbackVariable(0));
TileIndex start{ScriptTunnel::GetOtherTunnelEnd(end)};
DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
return ScriptObject::Command<CMD_BUILD_ROAD>::Do(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1), ScriptRoad::GetRoadType(), DRD_NONE, 0);
return ScriptObject::Command<CMD_BUILD_ROAD>::Do(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1), ScriptRoad::GetRoadType(), DRD_NONE, TownID::Invalid());
}
/* static */ bool ScriptTunnel::RemoveTunnel(TileIndex tile)

View File

@@ -21,14 +21,22 @@
* <th> acquired </th>
* <th> released </th>
* <th> reused </th></tr>
* <tr><td>#BridgeID </td><td> bridge type </td>
* <tr><td>#BridgeType </td><td> bridge type </td>
* <td> introduction \ref newgrf_changes "(1)" </td>
* <td> never \ref newgrf_changes "(1)" </td>
* <td> no \ref newgrf_changes "(1)" </td></tr>
* <tr><td>#CargoID </td><td> cargo type </td>
* <tr><td>#CargoType </td><td> cargo type </td>
* <td> game start \ref newgrf_changes "(1)" </td>
* <td> never \ref newgrf_changes "(1)" </td>
* <td> no \ref newgrf_changes "(1)" </td></tr>
* <tr><td>#ClientID </td><td> network client (player) </td>
* <td> joining server </td>
* <td> leaving server </td>
* <td> no </td></tr>
* <tr><td>#CompanyID </td><td> company </td>
* <td> launch </td>
* <td> merger, bankruptcy </td>
* <td> yes </td></tr>
* <tr><td>#EngineID </td><td> engine type </td>
* <td> introduction, preview \ref dynamic_engines "(2)" </td>
* <td> engines retires \ref dynamic_engines "(2)" </td>
@@ -49,6 +57,14 @@
* <td> game start \ref newgrf_changes "(1)" </td>
* <td> never \ref newgrf_changes "(1)" </td>
* <td> no </td></tr>
* <tr><td>#LeagueTableID</td><td> league table </td>
* <td> creation </td>
* <td> deletion </td>
* <td> yes </td></tr>
* <tr><td>#LeagueTableElementID</td><td> element of a league table </td>
* <td> creation </td>
* <td> deletion </td>
* <td> yes </td></tr>
* <tr><td>#ObjectType </td><td> NewGRF object type </td>
* <td> game start \ref newgrf_changes "(1)" </td>
* <td> never \ref newgrf_changes "(1)" </td>
@@ -104,42 +120,39 @@
#ifndef SCRIPT_TYPES_HPP
#define SCRIPT_TYPES_HPP
#include "../../core/overflowsafe_type.hpp"
#include "../../company_type.h"
#include "../../tile_type.h"
#include <squirrel.h>
#ifdef DOXYGEN_API
/* Define all types here, so they are added to the API docs. */
typedef uint BridgeID; ///< The ID of a bridge type.
typedef uint8_t CargoID; ///< The ID of a cargo.
typedef uint16_t EngineID; ///< The ID of an engine.
typedef uint16_t GoalID; ///< The ID of a goal.
typedef uint16_t GroupID; ///< The ID of a group.
typedef uint16_t IndustryID; ///< The ID of an industry.
typedef uint8_t IndustryType; ///< The ID of an industry-type.
#ifdef DOXYGEN_API
typedef int64_t Money; ///< Money, stored in a 32bit/64bit safe way. For scripts money is always in pounds.
#else
typedef OverflowSafeInt64 Money;
using BridgeType = uint32_t; ///< The ID of a bridge type.
using CargoType = uint8_t; ///< The ID of a cargo type.
using ClientID = uint32_t; //< The ID of a (network) client.
using CompanyID = uint8_t; ///< The ID of a company.
using EngineID = uint16_t; ///< The ID of an engine.
using GoalID = uint16_t; ///< The ID of a goal.
using GroupID = uint16_t; ///< The ID of a group.
using IndustryID = uint16_t; ///< The ID of an industry.
using IndustryType = uint8_t; ///< The ID of an industry-type.
using Money = int64_t; ///< Money, stored in a 32bit/64bit safe way. For scripts money is always in pounds.
using LeagueTableID = uint8_t; ///< The ID of a league table.
using LeagueTableElementID = uint16_t; ///< The ID of an element of a league table.
using ObjectType = uint16_t; ///< The ID of an object-type.
using SignID = uint16_t; ///< The ID of a sign.
using StationID = uint16_t; ///< The ID of a station.
using StringID = uint32_t; ///< The ID of a string.
using SubsidyID = uint16_t; ///< The ID of a subsidy.
using StoryPageID = uint16_t; ///< The ID of a story page.
using StoryPageElementID = uint16_t; ///< The ID of a story page element.
using TileIndex = uint32_t; ///< The ID of a map location.
using TownID = uint16_t; ///< The ID of a town.
using VehicleID = uint32_t; ///< The ID of a vehicle.
#endif /* DOXYGEN_API */
typedef uint16_t ObjectType; ///< The ID of an object-type.
typedef uint16_t SignID; ///< The ID of a sign.
typedef uint16_t StationID; ///< The ID of a station.
typedef uint32_t StringID; ///< The ID of a string.
typedef uint16_t SubsidyID; ///< The ID of a subsidy.
typedef uint16_t StoryPageID; ///< The ID of a story page.
typedef uint16_t StoryPageElementID; ///< The ID of a story page element.
#ifdef DOXYGEN_API
typedef uint32_t TileIndex; ///< The ID of a map location.
#endif /* DOXYGEN_API */
typedef uint16_t TownID; ///< The ID of a town.
typedef uint32_t VehicleID; ///< The ID of a vehicle.
/**
* The types of errors inside the script framework.
*
* Possible value are defined inside each API class in an ErrorMessages enum.
*/
typedef uint ScriptErrorType;
using ScriptErrorType = uint32_t;
#endif /* SCRIPT_TYPES_HPP */

View File

@@ -24,6 +24,7 @@
#include "../../roadveh_cmd.h"
#include "../../train_cmd.h"
#include "../../vehicle_cmd.h"
#include "table/strings.h"
#include "../../safeguards.h"
@@ -46,7 +47,7 @@
{
if (!IsValidVehicle(vehicle_id)) return ScriptCompany::COMPANY_INVALID;
return static_cast<ScriptCompany::CompanyID>((int)::Vehicle::Get(vehicle_id)->owner);
return ScriptCompany::ToScriptCompanyID(::Vehicle::Get(vehicle_id)->owner);
}
/* static */ SQInteger ScriptVehicle::GetNumWagons(VehicleID vehicle_id)
@@ -71,11 +72,11 @@
return v->IsGroundVehicle() ? v->GetGroundVehicleCache()->cached_total_length : -1;
}
/* static */ VehicleID ScriptVehicle::_BuildVehicleInternal(TileIndex depot, EngineID engine_id, CargoID cargo)
/* static */ VehicleID ScriptVehicle::_BuildVehicleInternal(TileIndex depot, EngineID engine_id, CargoType cargo)
{
EnforceCompanyModeValid(VEHICLE_INVALID);
EnforcePrecondition(VEHICLE_INVALID, ScriptEngine::IsBuildable(engine_id));
EnforcePrecondition(VEHICLE_INVALID, !::IsValidCargoID(cargo) || ScriptCargo::IsValidCargo(cargo));
EnforcePrecondition(VEHICLE_INVALID, !::IsValidCargoType(cargo) || ScriptCargo::IsValidCargo(cargo));
::VehicleType type = ::Engine::Get(engine_id)->type;
@@ -84,7 +85,7 @@
if (!ScriptObject::Command<CMD_BUILD_VEHICLE>::Do(&ScriptInstance::DoCommandReturnVehicleID, depot, engine_id, true, cargo, INVALID_CLIENT_ID)) return VEHICLE_INVALID;
/* In case of test-mode, we return VehicleID 0 */
return 0;
return VehicleID::Begin();
}
/* static */ VehicleID ScriptVehicle::BuildVehicle(TileIndex depot, EngineID engine_id)
@@ -92,39 +93,39 @@
return _BuildVehicleInternal(depot, engine_id, INVALID_CARGO);
}
/* static */ VehicleID ScriptVehicle::BuildVehicleWithRefit(TileIndex depot, EngineID engine_id, CargoID cargo)
/* static */ VehicleID ScriptVehicle::BuildVehicleWithRefit(TileIndex depot, EngineID engine_id, CargoType cargo)
{
EnforcePrecondition(VEHICLE_INVALID, ScriptCargo::IsValidCargo(cargo));
return _BuildVehicleInternal(depot, engine_id, cargo);
}
/* static */ SQInteger ScriptVehicle::GetBuildWithRefitCapacity(TileIndex depot, EngineID engine_id, CargoID cargo)
/* static */ SQInteger ScriptVehicle::GetBuildWithRefitCapacity(TileIndex depot, EngineID engine_id, CargoType cargo)
{
if (!ScriptEngine::IsBuildable(engine_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo)) return -1;
auto [res, veh_id, refit_capacity, refit_mail, cargo_capacities] = ::Command<CMD_BUILD_VEHICLE>::Do(DC_QUERY_COST, depot, engine_id, true, cargo, INVALID_CLIENT_ID);
auto [res, veh_id, refit_capacity, refit_mail, cargo_capacities] = ::Command<CMD_BUILD_VEHICLE>::Do(DoCommandFlag::QueryCost, depot, engine_id, true, cargo, INVALID_CLIENT_ID);
return res.Succeeded() ? refit_capacity : -1;
}
/* static */ VehicleID ScriptVehicle::CloneVehicle(TileIndex depot, VehicleID vehicle_id, bool share_orders)
{
EnforceCompanyModeValid(false);
EnforcePrecondition(false, IsPrimaryVehicle(vehicle_id));
EnforceCompanyModeValid(VEHICLE_INVALID);
EnforcePrecondition(VEHICLE_INVALID, IsPrimaryVehicle(vehicle_id));
if (!ScriptObject::Command<CMD_CLONE_VEHICLE>::Do(&ScriptInstance::DoCommandReturnVehicleID, depot, vehicle_id, share_orders)) return VEHICLE_INVALID;
/* In case of test-mode, we return VehicleID 0 */
return 0;
return VehicleID::Begin();
}
/* static */ bool ScriptVehicle::_MoveWagonInternal(VehicleID source_vehicle_id, SQInteger source_wagon, bool move_attached_wagons, SQInteger dest_vehicle_id, SQInteger dest_wagon)
{
EnforceCompanyModeValid(false);
EnforcePrecondition(false, IsValidVehicle(source_vehicle_id) && source_wagon < GetNumWagons(source_vehicle_id));
EnforcePrecondition(false, dest_vehicle_id == -1 || (IsValidVehicle(dest_vehicle_id) && dest_wagon < GetNumWagons(dest_vehicle_id)));
EnforcePrecondition(false, dest_vehicle_id == -1 || (IsValidVehicle(static_cast<VehicleID>(dest_vehicle_id)) && dest_wagon < GetNumWagons(static_cast<VehicleID>(dest_vehicle_id))));
EnforcePrecondition(false, ::Vehicle::Get(source_vehicle_id)->type == VEH_TRAIN);
EnforcePrecondition(false, dest_vehicle_id == -1 || ::Vehicle::Get(dest_vehicle_id)->type == VEH_TRAIN);
EnforcePrecondition(false, dest_vehicle_id == -1 || ::Vehicle::Get(static_cast<VehicleID>(dest_vehicle_id))->type == VEH_TRAIN);
const Train *v = ::Train::Get(source_vehicle_id);
while (source_wagon-- > 0) v = v->GetNextUnit();
@@ -134,7 +135,7 @@
while (dest_wagon-- > 0) w = w->GetNextUnit();
}
return ScriptObject::Command<CMD_MOVE_RAIL_VEHICLE>::Do(v->index, w == nullptr ? ::INVALID_VEHICLE : w->index, move_attached_wagons);
return ScriptObject::Command<CMD_MOVE_RAIL_VEHICLE>::Do(v->index, w == nullptr ? VehicleID::Invalid() : w->index, move_attached_wagons);
}
/* static */ bool ScriptVehicle::MoveWagon(VehicleID source_vehicle_id, SQInteger source_wagon, SQInteger dest_vehicle_id, SQInteger dest_wagon)
@@ -147,16 +148,16 @@
return _MoveWagonInternal(source_vehicle_id, source_wagon, true, dest_vehicle_id, dest_wagon);
}
/* static */ SQInteger ScriptVehicle::GetRefitCapacity(VehicleID vehicle_id, CargoID cargo)
/* static */ SQInteger ScriptVehicle::GetRefitCapacity(VehicleID vehicle_id, CargoType cargo)
{
if (!IsValidVehicle(vehicle_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo)) return -1;
auto [res, refit_capacity, refit_mail, cargo_capacities] = ::Command<CMD_REFIT_VEHICLE>::Do(DC_QUERY_COST, vehicle_id, cargo, 0, false, false, 0);
auto [res, refit_capacity, refit_mail, cargo_capacities] = ::Command<CMD_REFIT_VEHICLE>::Do(DoCommandFlag::QueryCost, vehicle_id, cargo, 0, false, false, 0);
return res.Succeeded() ? refit_capacity : -1;
}
/* static */ bool ScriptVehicle::RefitVehicle(VehicleID vehicle_id, CargoID cargo)
/* static */ bool ScriptVehicle::RefitVehicle(VehicleID vehicle_id, CargoType cargo)
{
EnforceCompanyModeValid(false);
EnforcePrecondition(false, IsValidVehicle(vehicle_id) && ScriptCargo::IsValidCargo(cargo));
@@ -201,7 +202,7 @@
EnforceCompanyModeValid(false);
EnforcePrecondition(false, IsPrimaryVehicle(vehicle_id));
return ScriptObject::Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(vehicle_id, DepotCommand::None, {});
return ScriptObject::Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(vehicle_id, DepotCommandFlags{}, {});
}
/* static */ bool ScriptVehicle::SendVehicleToDepotForServicing(VehicleID vehicle_id)
@@ -209,7 +210,7 @@
EnforceCompanyModeValid(false);
EnforcePrecondition(false, IsPrimaryVehicle(vehicle_id));
return ScriptObject::Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(vehicle_id, DepotCommand::Service, {});
return ScriptObject::Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(vehicle_id, DepotCommandFlag::Service, {});
}
/* static */ bool ScriptVehicle::IsInDepot(VehicleID vehicle_id)
@@ -275,15 +276,15 @@
/* static */ EngineID ScriptVehicle::GetEngineType(VehicleID vehicle_id)
{
if (!IsValidVehicle(vehicle_id)) return INVALID_ENGINE;
if (!IsValidVehicle(vehicle_id)) return ::EngineID::Invalid();
return ::Vehicle::Get(vehicle_id)->engine_type;
}
/* static */ EngineID ScriptVehicle::GetWagonEngineType(VehicleID vehicle_id, SQInteger wagon)
{
if (!IsValidVehicle(vehicle_id)) return INVALID_ENGINE;
if (wagon >= GetNumWagons(vehicle_id)) return INVALID_ENGINE;
if (!IsValidVehicle(vehicle_id)) return ::EngineID::Invalid();
if (wagon >= GetNumWagons(vehicle_id)) return ::EngineID::Invalid();
const Vehicle *v = ::Vehicle::Get(vehicle_id);
if (v->type == VEH_TRAIN) {
@@ -303,8 +304,7 @@
{
if (!IsPrimaryVehicle(vehicle_id)) return std::nullopt;
::SetDParam(0, vehicle_id);
return GetString(STR_VEHICLE_NAME);
return ::StrMakeValid(::GetString(STR_VEHICLE_NAME, vehicle_id));
}
/* static */ SQInteger ScriptVehicle::GetAge(VehicleID vehicle_id)
@@ -345,7 +345,7 @@
if (!IsPrimaryVehicle(vehicle_id)) return -1;
const ::Vehicle *v = ::Vehicle::Get(vehicle_id);
return (v->vehstatus & (::VS_STOPPED | ::VS_CRASHED)) == 0 ? v->GetDisplaySpeed() : 0; // km-ish/h
return !v->vehstatus.Any({::VehState::Stopped, ::VehState::Crashed}) ? v->GetDisplaySpeed() : 0; // km-ish/h
}
/* static */ ScriptVehicle::VehicleState ScriptVehicle::GetState(VehicleID vehicle_id)
@@ -353,12 +353,12 @@
if (!IsValidVehicle(vehicle_id)) return ScriptVehicle::VS_INVALID;
const Vehicle *v = ::Vehicle::Get(vehicle_id);
uint8_t vehstatus = v->vehstatus;
VehStates vehstatus = v->vehstatus;
if (vehstatus & ::VS_CRASHED) return ScriptVehicle::VS_CRASHED;
if (vehstatus.Test(::VehState::Crashed)) return ScriptVehicle::VS_CRASHED;
if (v->breakdown_ctr != 0) return ScriptVehicle::VS_BROKEN;
if (v->IsStoppedInDepot()) return ScriptVehicle::VS_IN_DEPOT;
if (vehstatus & ::VS_STOPPED) return ScriptVehicle::VS_STOPPED;
if (vehstatus.Test(::VehState::Stopped)) return ScriptVehicle::VS_STOPPED;
if (v->current_order.IsType(OT_LOADING)) return ScriptVehicle::VS_AT_STATION;
return ScriptVehicle::VS_RUNNING;
}
@@ -412,7 +412,7 @@
return (ScriptRoad::RoadType)(int)(::RoadVehicle::Get(vehicle_id))->roadtype;
}
/* static */ SQInteger ScriptVehicle::GetCapacity(VehicleID vehicle_id, CargoID cargo)
/* static */ SQInteger ScriptVehicle::GetCapacity(VehicleID vehicle_id, CargoType cargo)
{
if (!IsValidVehicle(vehicle_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo)) return -1;
@@ -425,7 +425,7 @@
return amount;
}
/* static */ SQInteger ScriptVehicle::GetCargoLoad(VehicleID vehicle_id, CargoID cargo)
/* static */ SQInteger ScriptVehicle::GetCargoLoad(VehicleID vehicle_id, CargoType cargo)
{
if (!IsValidVehicle(vehicle_id)) return -1;
if (!ScriptCargo::IsValidCargo(cargo)) return -1;

View File

@@ -11,6 +11,8 @@
#define SCRIPT_VEHICLE_HPP
#include "script_road.hpp"
#include "../../engine_type.h"
#include "../../group_type.h"
/**
* Class that handles all vehicle related functions.
@@ -93,7 +95,7 @@ public:
VS_INVALID = 0xFF, ///< An invalid vehicle state.
};
static const VehicleID VEHICLE_INVALID = 0xFFFFF; ///< Invalid VehicleID.
static constexpr VehicleID VEHICLE_INVALID = ::VehicleID::Invalid(); ///< Invalid VehicleID.
/**
* Checks whether the given vehicle is valid and owned by you.
@@ -357,7 +359,7 @@ public:
* as the vehicle isn't really built yet. Build it for real first before
* assigning orders.
*/
static VehicleID BuildVehicleWithRefit(TileIndex depot, EngineID engine_id, CargoID cargo);
static VehicleID BuildVehicleWithRefit(TileIndex depot, EngineID engine_id, CargoType cargo);
/**
* Gets the capacity of a vehicle built at the given depot with the given engine and refitted to the given cargo.
@@ -370,7 +372,7 @@ public:
* @pre ScriptCargo::IsValidCargo(cargo).
* @return The capacity the vehicle will have when refited.
*/
static SQInteger GetBuildWithRefitCapacity(TileIndex depot, EngineID engine_id, CargoID cargo);
static SQInteger GetBuildWithRefitCapacity(TileIndex depot, EngineID engine_id, CargoType cargo);
/**
* Clones a vehicle at the given depot, copying or cloning its orders.
@@ -431,7 +433,7 @@ public:
* @pre The vehicle must be stopped in the depot.
* @return The capacity the vehicle will have when refited.
*/
static SQInteger GetRefitCapacity(VehicleID vehicle_id, CargoID cargo);
static SQInteger GetRefitCapacity(VehicleID vehicle_id, CargoType cargo);
/**
* Refits a vehicle to the given cargo type.
@@ -447,7 +449,7 @@ public:
* @exception ScriptVehicle::ERR_VEHICLE_NOT_IN_DEPOT
* @return True if and only if the refit succeeded.
*/
static bool RefitVehicle(VehicleID vehicle_id, CargoID cargo);
static bool RefitVehicle(VehicleID vehicle_id, CargoType cargo);
/**
* Sells the given vehicle.
@@ -546,7 +548,7 @@ public:
* @pre ScriptCargo::IsValidCargo(cargo).
* @return The maximum amount of the given cargo the vehicle can transport.
*/
static SQInteger GetCapacity(VehicleID vehicle_id, CargoID cargo);
static SQInteger GetCapacity(VehicleID vehicle_id, CargoType cargo);
/**
* Get the length of a the total vehicle in 1/16's of a tile.
@@ -565,7 +567,7 @@ public:
* @pre ScriptCargo::IsValidCargo(cargo).
* @return The amount of the given cargo the vehicle is currently transporting.
*/
static SQInteger GetCargoLoad(VehicleID vehicle_id, CargoID cargo);
static SQInteger GetCargoLoad(VehicleID vehicle_id, CargoType cargo);
/**
* Get the group of a given vehicle.
@@ -619,7 +621,7 @@ private:
/**
* Internal function used by BuildVehicle(WithRefit).
*/
static VehicleID _BuildVehicleInternal(TileIndex depot, EngineID engine_id, CargoID cargo);
static VehicleID _BuildVehicleInternal(TileIndex depot, EngineID engine_id, CargoType cargo);
/**
* Internal function used by SellWagon(Chain).

Some files were not shown because too many files have changed in this diff Show More