Update to 12.0-beta1
This commit is contained in:
@@ -179,6 +179,7 @@ add_files(
|
||||
script_log.hpp
|
||||
script_map.hpp
|
||||
script_marine.hpp
|
||||
script_newgrf.hpp
|
||||
script_news.hpp
|
||||
script_object.hpp
|
||||
script_order.hpp
|
||||
@@ -246,6 +247,7 @@ add_files(
|
||||
script_log.cpp
|
||||
script_map.cpp
|
||||
script_marine.cpp
|
||||
script_newgrf.cpp
|
||||
script_news.cpp
|
||||
script_object.cpp
|
||||
script_order.cpp
|
||||
|
||||
@@ -13,6 +13,15 @@
|
||||
* functions may still be available if you return an older API version
|
||||
* in GetAPIVersion() in info.nut.
|
||||
*
|
||||
* \b 12.0
|
||||
*
|
||||
* This version is not yet released. The following changes are not set in stone yet.
|
||||
*
|
||||
* API additions:
|
||||
* \li AINewGRF
|
||||
* \li AINewGRFList
|
||||
* \li AIGroup::GetNumVehicles
|
||||
*
|
||||
* \b 1.11.0
|
||||
*
|
||||
* API additions:
|
||||
|
||||
@@ -13,6 +13,14 @@
|
||||
* functions may still be available if you return an older API version
|
||||
* in GetAPIVersion() in info.nut.
|
||||
*
|
||||
* \b 12.0
|
||||
*
|
||||
* This version is not yet released. The following changes are not set in stone yet.
|
||||
*
|
||||
* API additions:
|
||||
* \li GSNewGRF
|
||||
* \li GSNewGRFList
|
||||
*
|
||||
* \b 1.11.0
|
||||
*
|
||||
* API additions:
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
NetworkAdminGameScript(json.c_str());
|
||||
NetworkAdminGameScript(json);
|
||||
|
||||
sq_pushinteger(vm, 1);
|
||||
return 1;
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
|
||||
ScriptCargoList::ScriptCargoList()
|
||||
{
|
||||
const CargoSpec *cs;
|
||||
FOR_ALL_CARGOSPECS(cs) {
|
||||
for (const CargoSpec *cs : CargoSpec::Iterate()) {
|
||||
this->AddItem(cs->Index());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ static NetworkClientInfo *FindClientInfo(ScriptClient::ClientID client)
|
||||
{
|
||||
NetworkClientInfo *ci = FindClientInfo(client);
|
||||
if (ci == nullptr) return nullptr;
|
||||
return stredup(ci->client_name);
|
||||
return stredup(ci->client_name.c_str());
|
||||
}
|
||||
|
||||
/* static */ ScriptCompany::CompanyID ScriptClient::GetCompany(ScriptClient::ClientID client)
|
||||
|
||||
@@ -140,9 +140,9 @@
|
||||
if (quarter > EARLIEST_QUARTER) return -1;
|
||||
|
||||
if (quarter == CURRENT_QUARTER) {
|
||||
return ::Company::Get(company)->cur_economy.delivered_cargo.GetSum<OverflowSafeInt<int32, INT32_MAX, INT32_MIN> >();
|
||||
return ::Company::Get(company)->cur_economy.delivered_cargo.GetSum<OverflowSafeInt32>();
|
||||
}
|
||||
return ::Company::Get(company)->old_economy[quarter - 1].delivered_cargo.GetSum<OverflowSafeInt<int32, INT32_MAX, INT32_MIN> >();
|
||||
return ::Company::Get(company)->old_economy[quarter - 1].delivered_cargo.GetSum<OverflowSafeInt32>();
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptCompany::GetQuarterlyPerformanceRating(ScriptCompany::CompanyID company, uint32 quarter)
|
||||
@@ -260,7 +260,7 @@
|
||||
|
||||
/* static */ bool ScriptCompany::SetAutoRenewStatus(bool autorenew)
|
||||
{
|
||||
return ScriptObject::DoCommand(0, ::GetCompanySettingIndex("company.engine_renew"), autorenew ? 1 : 0, CMD_CHANGE_COMPANY_SETTING);
|
||||
return ScriptObject::DoCommand(0, 0, autorenew ? 1 : 0, CMD_CHANGE_COMPANY_SETTING, "company.engine_renew");
|
||||
}
|
||||
|
||||
/* static */ bool ScriptCompany::GetAutoRenewStatus(CompanyID company)
|
||||
@@ -273,7 +273,7 @@
|
||||
|
||||
/* static */ bool ScriptCompany::SetAutoRenewMonths(int16 months)
|
||||
{
|
||||
return ScriptObject::DoCommand(0, ::GetCompanySettingIndex("company.engine_renew_months"), months, CMD_CHANGE_COMPANY_SETTING);
|
||||
return ScriptObject::DoCommand(0, 0, months, CMD_CHANGE_COMPANY_SETTING, "company.engine_renew_months");
|
||||
}
|
||||
|
||||
/* static */ int16 ScriptCompany::GetAutoRenewMonths(CompanyID company)
|
||||
@@ -288,7 +288,7 @@
|
||||
{
|
||||
EnforcePrecondition(false, money >= 0);
|
||||
EnforcePrecondition(false, (int64)money <= UINT32_MAX);
|
||||
return ScriptObject::DoCommand(0, ::GetCompanySettingIndex("company.engine_renew_money"), money, CMD_CHANGE_COMPANY_SETTING);
|
||||
return ScriptObject::DoCommand(0, 0, money, CMD_CHANGE_COMPANY_SETTING, "company.engine_renew_money");
|
||||
}
|
||||
|
||||
/* static */ Money ScriptCompany::GetAutoRenewMoney(CompanyID company)
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
* Creating instance of this class switches the company used for queries
|
||||
* and commands.
|
||||
* @param company The new company to switch to.
|
||||
* @note When the instance is destroyed, he restores the company that was
|
||||
* @note When the instance is destroyed, it restores the company that was
|
||||
* current when the instance was created!
|
||||
*/
|
||||
ScriptCompanyMode(int company);
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
seprintf(log_message, lastof(log_message), "Break: %s", message);
|
||||
ScriptLog::Log(ScriptLog::LOG_SQ_ERROR, log_message);
|
||||
|
||||
/* Inform script developer that his script has been paused and
|
||||
/* Inform script developer that their script has been paused and
|
||||
* needs manual action to continue. */
|
||||
ShowAIDebugWindow(ScriptObject::GetRootCompany());
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
* data from the loaded game.
|
||||
* - Finally, #Start is called to start execution of the script.
|
||||
*
|
||||
* See also http://wiki.openttd.org/AI:Save/Load for more details.
|
||||
* See also https://wiki.openttd.org/en/Development/Script/Save%20and%20Load for more details.
|
||||
*
|
||||
* @api ai game
|
||||
*/
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
* notified of the call. To avoid race-conditions between #Save and the
|
||||
* other script code, change variables directly after a #Sleep, it is
|
||||
* very unlikely, to get interrupted at that point in the execution.
|
||||
* See also http://wiki.openttd.org/AI:Save/Load for more details.
|
||||
* See also https://wiki.openttd.org/en/Development/Script/Save%20and%20Load for more details.
|
||||
*
|
||||
* @note No other information is saved than the table returned by #Save.
|
||||
* For example all pending events are lost as soon as the game is loaded.
|
||||
@@ -135,11 +135,20 @@ public:
|
||||
/**
|
||||
* Get the OpenTTD version of this executable. The version is formatted
|
||||
* with the bits having the following meaning:
|
||||
* 28-31 major version
|
||||
* 24-27 minor version
|
||||
* 20-23 build
|
||||
* 24-31 major version + 16.
|
||||
* 20-23 minor version.
|
||||
* 19 1 if it is a release, 0 if it is not.
|
||||
* 0-18 revision number; 0 when the revision is unknown.
|
||||
* You have to subtract 16 from the major version to get the correct
|
||||
* value.
|
||||
*
|
||||
* Prior to OpenTTD 12, the bits have the following meaning:
|
||||
* 28-31 major version.
|
||||
* 24-27 minor version.
|
||||
* 20-23 build.
|
||||
* 19 1 if it is a release, 0 if it is not.
|
||||
* 0-18 revision number; 0 when the revision is unknown.
|
||||
*
|
||||
* @return The version in newgrf format.
|
||||
*/
|
||||
static uint GetVersion();
|
||||
|
||||
@@ -7,11 +7,12 @@
|
||||
|
||||
/** @file script_date.cpp Implementation of ScriptDate. */
|
||||
|
||||
#include <time.h>
|
||||
#include "../../stdafx.h"
|
||||
#include "script_date.hpp"
|
||||
#include "../../date_func.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
/* static */ bool ScriptDate::IsValidDate(Date date)
|
||||
|
||||
@@ -118,23 +118,18 @@ bool ScriptEventCompanyAskMerger::AcceptMerger()
|
||||
return ScriptObject::DoCommand(0, this->owner, 0, CMD_BUY_COMPANY);
|
||||
}
|
||||
|
||||
ScriptEventAdminPort::ScriptEventAdminPort(const char *json) :
|
||||
ScriptEventAdminPort::ScriptEventAdminPort(const std::string &json) :
|
||||
ScriptEvent(ET_ADMIN_PORT),
|
||||
json(stredup(json))
|
||||
json(json)
|
||||
{
|
||||
}
|
||||
|
||||
ScriptEventAdminPort::~ScriptEventAdminPort()
|
||||
{
|
||||
free(this->json);
|
||||
}
|
||||
|
||||
#define SKIP_EMPTY(p) while (*(p) == ' ' || *(p) == '\n' || *(p) == '\r') (p)++;
|
||||
#define RETURN_ERROR(stack) { ScriptLog::Error("Received invalid JSON data from AdminPort."); if (stack != 0) sq_pop(vm, stack); return nullptr; }
|
||||
|
||||
SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm)
|
||||
{
|
||||
char *p = this->json;
|
||||
const char *p = this->json.c_str();
|
||||
|
||||
if (this->ReadTable(vm, p) == nullptr) {
|
||||
sq_pushnull(vm);
|
||||
@@ -144,9 +139,9 @@ SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm)
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *ScriptEventAdminPort::ReadString(HSQUIRRELVM vm, char *p)
|
||||
const char *ScriptEventAdminPort::ReadString(HSQUIRRELVM vm, const char *p)
|
||||
{
|
||||
char *value = p;
|
||||
const char *value = p;
|
||||
|
||||
bool escape = false;
|
||||
for (;;) {
|
||||
@@ -168,14 +163,14 @@ char *ScriptEventAdminPort::ReadString(HSQUIRRELVM vm, char *p)
|
||||
p++;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
sq_pushstring(vm, value, -1);
|
||||
*p++ = '"';
|
||||
size_t len = p - value;
|
||||
sq_pushstring(vm, value, len);
|
||||
p++; // Step past the end-of-string marker (")
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, char *p)
|
||||
const char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, const char *p)
|
||||
{
|
||||
sq_newtable(vm);
|
||||
|
||||
@@ -218,7 +213,7 @@ char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, char *p)
|
||||
return p;
|
||||
}
|
||||
|
||||
char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, char *p)
|
||||
const char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, const char *p)
|
||||
{
|
||||
SKIP_EMPTY(p);
|
||||
|
||||
@@ -257,7 +252,7 @@ char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, char *p)
|
||||
sq_newarray(vm, 0);
|
||||
|
||||
/* Empty array? */
|
||||
char *p2 = p + 1;
|
||||
const char *p2 = p + 1;
|
||||
SKIP_EMPTY(p2);
|
||||
if (*p2 == ']') {
|
||||
p = p2 + 1;
|
||||
|
||||
@@ -837,8 +837,7 @@ public:
|
||||
/**
|
||||
* @param json The JSON string which got sent.
|
||||
*/
|
||||
ScriptEventAdminPort(const char *json);
|
||||
~ScriptEventAdminPort();
|
||||
ScriptEventAdminPort(const std::string &json);
|
||||
|
||||
/**
|
||||
* Convert an ScriptEvent to the real instance.
|
||||
@@ -853,28 +852,28 @@ public:
|
||||
SQInteger GetObject(HSQUIRRELVM vm);
|
||||
|
||||
private:
|
||||
char *json; ///< The JSON string.
|
||||
std::string json; ///< The JSON string.
|
||||
|
||||
/**
|
||||
* Read a table from a JSON string.
|
||||
* @param vm The VM used.
|
||||
* @param p The (part of the) JSON string reading.
|
||||
*/
|
||||
char *ReadTable(HSQUIRRELVM vm, char *p);
|
||||
const char *ReadTable(HSQUIRRELVM vm, const char *p);
|
||||
|
||||
/**
|
||||
* Read a value from a JSON string.
|
||||
* @param vm The VM used.
|
||||
* @param p The (part of the) JSON string reading.
|
||||
*/
|
||||
char *ReadValue(HSQUIRRELVM vm, char *p);
|
||||
const char *ReadValue(HSQUIRRELVM vm, const char *p);
|
||||
|
||||
/**
|
||||
* Read a string from a JSON string.
|
||||
* @param vm The VM used.
|
||||
* @param p The (part of the) JSON string reading.
|
||||
*/
|
||||
char *ReadString(HSQUIRRELVM vm, char *p);
|
||||
const char *ReadString(HSQUIRRELVM vm, const char *p);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -968,7 +967,7 @@ public:
|
||||
private:
|
||||
uint16 uniqueid; ///< The uniqueid of the question.
|
||||
ScriptCompany::CompanyID company; ///< The company given the answer.
|
||||
ScriptGoal::QuestionButton button; ///< The button he pressed.
|
||||
ScriptGoal::QuestionButton button; ///< The button that was pressed.
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,7 +34,7 @@ protected:
|
||||
public:
|
||||
/**
|
||||
* Creating instance of this class switches the build mode to Execute.
|
||||
* @note When the instance is destroyed, he restores the mode that was
|
||||
* @note When the instance is destroyed, it restores the mode that was
|
||||
* current when the instance was created!
|
||||
*/
|
||||
ScriptExecMode();
|
||||
|
||||
@@ -17,35 +17,27 @@
|
||||
|
||||
/* static */ bool ScriptGameSettings::IsValid(const char *setting)
|
||||
{
|
||||
uint i;
|
||||
const SettingDesc *sd = GetSettingFromName(setting, &i);
|
||||
return sd != nullptr && sd->desc.cmd != SDT_STRING;
|
||||
const SettingDesc *sd = GetSettingFromName(setting);
|
||||
return sd != nullptr && sd->IsIntSetting();
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptGameSettings::GetValue(const char *setting)
|
||||
{
|
||||
if (!IsValid(setting)) return -1;
|
||||
|
||||
uint index;
|
||||
const SettingDesc *sd = GetSettingFromName(setting, &index);
|
||||
|
||||
void *ptr = GetVariableAddress(&_settings_game, &sd->save);
|
||||
if (sd->desc.cmd == SDT_BOOLX) return *(bool*)ptr;
|
||||
|
||||
return (int32)ReadValue(ptr, sd->save.conv);
|
||||
const SettingDesc *sd = GetSettingFromName(setting);
|
||||
return sd->AsIntSetting()->Read(&_settings_game);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGameSettings::SetValue(const char *setting, int value)
|
||||
{
|
||||
if (!IsValid(setting)) return false;
|
||||
|
||||
uint index;
|
||||
const SettingDesc *sd = GetSettingFromName(setting, &index);
|
||||
const SettingDesc *sd = GetSettingFromName(setting);
|
||||
|
||||
if ((sd->save.conv & SLF_NO_NETWORK_SYNC) != 0) return false;
|
||||
if (sd->desc.cmd != SDT_BOOLX && sd->desc.cmd != SDT_NUMX) return false;
|
||||
if ((sd->flags & SF_NO_NETWORK_SYNC) != 0) return false;
|
||||
|
||||
return ScriptObject::DoCommand(0, index, value, CMD_CHANGE_SETTING);
|
||||
return ScriptObject::DoCommand(0, 0, value, CMD_CHANGE_SETTING, sd->GetName().c_str());
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGameSettings::IsDisabledVehicleType(ScriptVehicle::VehicleType vehicle_type)
|
||||
|
||||
@@ -89,14 +89,14 @@
|
||||
{
|
||||
EnforcePrecondition(false, IsValidGroup(group_id));
|
||||
|
||||
return ScriptObject::DoCommand(0, group_id, enable ? 1 : 0, CMD_SET_GROUP_REPLACE_PROTECTION);
|
||||
return ScriptObject::DoCommand(0, group_id | GroupFlags::GF_REPLACE_PROTECTION, enable ? 1 : 0, CMD_SET_GROUP_FLAG);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGroup::GetAutoReplaceProtection(GroupID group_id)
|
||||
{
|
||||
if (!IsValidGroup(group_id)) return false;
|
||||
|
||||
return ::Group::Get(group_id)->replace_protection;
|
||||
return HasBit(::Group::Get(group_id)->flags, GroupFlags::GF_REPLACE_PROTECTION);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptGroup::GetNumEngines(GroupID group_id, EngineID engine_id)
|
||||
@@ -106,6 +106,15 @@
|
||||
return GetGroupNumEngines(ScriptObject::GetCompany(), group_id, engine_id);
|
||||
}
|
||||
|
||||
/* static */ int32 ScriptGroup::GetNumVehicles(GroupID group_id, ScriptVehicle::VehicleType vehicle_type)
|
||||
{
|
||||
bool valid_group = IsValidGroup(group_id);
|
||||
if (!valid_group && group_id != GROUP_DEFAULT && group_id != GROUP_ALL) return -1;
|
||||
if (!valid_group && (vehicle_type < ScriptVehicle::VT_RAIL || vehicle_type > ScriptVehicle::VT_AIR)) return -1;
|
||||
|
||||
return GetGroupNumVehicle(ScriptObject::GetCompany(), group_id, valid_group ? ::Group::Get(group_id)->vehicle_type : (::VehicleType)vehicle_type);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGroup::MoveVehicle(GroupID group_id, VehicleID vehicle_id)
|
||||
{
|
||||
EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT);
|
||||
@@ -118,7 +127,7 @@
|
||||
{
|
||||
if (HasWagonRemoval() == enable_removal) return true;
|
||||
|
||||
return ScriptObject::DoCommand(0, ::GetCompanySettingIndex("company.renew_keep_length"), enable_removal ? 1 : 0, CMD_CHANGE_COMPANY_SETTING);
|
||||
return ScriptObject::DoCommand(0, 0, enable_removal ? 1 : 0, CMD_CHANGE_COMPANY_SETTING, "company.renew_keep_length");
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGroup::HasWagonRemoval()
|
||||
|
||||
@@ -128,6 +128,20 @@ public:
|
||||
*/
|
||||
static int32 GetNumEngines(GroupID group_id, EngineID engine_id);
|
||||
|
||||
/**
|
||||
* Get the total number of vehicles in a given group and its sub-groups.
|
||||
* @param group_id The group to get the number of vehicles in.
|
||||
* @param vehicle_type The type of vehicle of the group.
|
||||
* @pre IsValidGroup(group_id) || group_id == GROUP_ALL || group_id == GROUP_DEFAULT.
|
||||
* @pre IsValidGroup(group_id) || vehicle_type == ScriptVehicle::VT_ROAD || vehicle_type == ScriptVehicle::VT_RAIL ||
|
||||
* vehicle_type == ScriptVehicle::VT_WATER || vehicle_type == ScriptVehicle::VT_AIR
|
||||
* @return The total number of vehicles in the group with id group_id and it's sub-groups.
|
||||
* @note If the group is valid (neither GROUP_ALL nor GROUP_DEFAULT), the value of
|
||||
* vehicle_type is retrieved from the group itself and not from the input value.
|
||||
* But if the group is GROUP_ALL or GROUP_DEFAULT, then vehicle_type must be valid.
|
||||
*/
|
||||
static int32 GetNumVehicles(GroupID group_id, ScriptVehicle::VehicleType vehicle_type);
|
||||
|
||||
/**
|
||||
* Move a vehicle to a group.
|
||||
* @param group_id The group to move the vehicle to.
|
||||
|
||||
@@ -186,7 +186,7 @@
|
||||
if (!HasHeliport(industry_id)) return INVALID_TILE;
|
||||
|
||||
const Industry *ind = ::Industry::Get(industry_id);
|
||||
TILE_AREA_LOOP(tile_cur, ind->location) {
|
||||
for (TileIndex tile_cur : ind->location) {
|
||||
if (IsTileType(tile_cur, MP_STATION) && IsOilRig(tile_cur)) {
|
||||
return tile_cur;
|
||||
}
|
||||
@@ -208,7 +208,7 @@
|
||||
if (!HasDock(industry_id)) return INVALID_TILE;
|
||||
|
||||
const Industry *ind = ::Industry::Get(industry_id);
|
||||
TILE_AREA_LOOP(tile_cur, ind->location) {
|
||||
for (TileIndex tile_cur : ind->location) {
|
||||
if (IsTileType(tile_cur, MP_STATION) && IsOilRig(tile_cur)) {
|
||||
return tile_cur;
|
||||
}
|
||||
|
||||
@@ -468,8 +468,8 @@ int64 ScriptList::Begin()
|
||||
|
||||
int64 ScriptList::Next()
|
||||
{
|
||||
if (this->initialized == false) {
|
||||
DEBUG(script, 0, "Next() is invalid as Begin() is never called");
|
||||
if (!this->initialized) {
|
||||
Debug(script, 0, "Next() is invalid as Begin() is never called");
|
||||
return 0;
|
||||
}
|
||||
return this->sorter->Next();
|
||||
@@ -482,8 +482,8 @@ bool ScriptList::IsEmpty()
|
||||
|
||||
bool ScriptList::IsEnd()
|
||||
{
|
||||
if (this->initialized == false) {
|
||||
DEBUG(script, 0, "IsEnd() is invalid as Begin() is never called");
|
||||
if (!this->initialized) {
|
||||
Debug(script, 0, "IsEnd() is invalid as Begin() is never called");
|
||||
return true;
|
||||
}
|
||||
return this->sorter->IsEnd();
|
||||
@@ -832,7 +832,7 @@ SQInteger ScriptList::_nexti(HSQUIRRELVM vm)
|
||||
SQInteger idx;
|
||||
sq_getinteger(vm, 2, &idx);
|
||||
|
||||
int val = this->Next();
|
||||
SQInteger val = this->Next();
|
||||
if (this->IsEnd()) {
|
||||
sq_pushnull(vm);
|
||||
return 1;
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
}
|
||||
|
||||
/* Also still print to debug window */
|
||||
DEBUG(script, level, "[%d] [%c] %s", (uint)ScriptObject::GetRootCompany(), logc, log->lines[log->pos]);
|
||||
Debug(script, level, "[{}] [{}] {}", (uint)ScriptObject::GetRootCompany(), logc, log->lines[log->pos]);
|
||||
InvalidateWindowData(WC_AI_DEBUG, 0, ScriptObject::GetRootCompany());
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ class ScriptLog : public ScriptObject {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Log levels; The value is also feed to DEBUG() lvl.
|
||||
* Log levels; The value is also feed to Debug() lvl.
|
||||
* This has no use for you, as script writer.
|
||||
* @api -all
|
||||
*/
|
||||
|
||||
64
src/script/api/script_newgrf.cpp
Normal file
64
src/script/api/script_newgrf.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file script_newgrf.cpp Implementation of ScriptNewGRF and friends. */
|
||||
|
||||
#include "../../stdafx.h"
|
||||
#include "script_newgrf.hpp"
|
||||
#include "../../core/bitmath_func.hpp"
|
||||
#include "../../newgrf_config.h"
|
||||
#include "../../string_func.h"
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
ScriptNewGRFList::ScriptNewGRFList()
|
||||
{
|
||||
for (auto c = _grfconfig; c != nullptr; c = c->next) {
|
||||
if (!HasBit(c->flags, GCF_STATIC)) {
|
||||
this->AddItem(BSWAP32(c->ident.grfid));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ bool ScriptNewGRF::IsLoaded(uint32 grfid)
|
||||
{
|
||||
grfid = BSWAP32(grfid); // 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;
|
||||
}
|
||||
|
||||
/* static */ uint32 ScriptNewGRF::GetVersion(uint32 grfid)
|
||||
{
|
||||
grfid = BSWAP32(grfid); // 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;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* static */ char *ScriptNewGRF::GetName(uint32 grfid)
|
||||
{
|
||||
grfid = BSWAP32(grfid); // Match people's expectations.
|
||||
|
||||
for (auto c = _grfconfig; c != nullptr; c = c->next) {
|
||||
if (!HasBit(c->flags, GCF_STATIC) && c->ident.grfid == grfid) {
|
||||
return ::stredup(c->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
56
src/script/api/script_newgrf.hpp
Normal file
56
src/script/api/script_newgrf.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file script_newgrf.hpp NewGRF info for scripts. */
|
||||
|
||||
#ifndef SCRIPT_NEWGRF_HPP
|
||||
#define SCRIPT_NEWGRF_HPP
|
||||
|
||||
#include "script_list.hpp"
|
||||
|
||||
/**
|
||||
* Create a list of loaded NewGRFs.
|
||||
* @api ai game
|
||||
* @ingroup ScriptList
|
||||
*/
|
||||
class ScriptNewGRFList : public ScriptList {
|
||||
public:
|
||||
ScriptNewGRFList();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class that handles all NewGRF related functions.
|
||||
* @api ai game
|
||||
*/
|
||||
class ScriptNewGRF : public ScriptObject {
|
||||
public:
|
||||
/**
|
||||
* Check if a NewGRF with a given grfid is loaded.
|
||||
* @param grfid The grfid to check.
|
||||
* @return True if and only if a NewGRF with the given grfid is loaded in the game.
|
||||
*/
|
||||
static bool IsLoaded(uint32 grfid);
|
||||
|
||||
/**
|
||||
* Get the version of a loaded NewGRF.
|
||||
* @param grfid The NewGRF to query.
|
||||
* @pre ScriptNewGRF::IsLoaded(grfid).
|
||||
* @return Version of the NewGRF or 0 if the NewGRF specifies no version.
|
||||
*/
|
||||
static uint32 GetVersion(uint32 grfid);
|
||||
|
||||
/**
|
||||
* Get the name of a loaded NewGRF.
|
||||
* @param grfid The NewGRF to query.
|
||||
* @pre ScriptNewGRF::IsLoaded(grfid).
|
||||
* @return The name of the NewGRF or nullptr if no name is defined.
|
||||
*/
|
||||
static char *GetName(uint32 grfid);
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_NEWGRF_HPP */
|
||||
@@ -85,7 +85,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
|
||||
/* static */ void ScriptObject::SetLastCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd)
|
||||
{
|
||||
ScriptStorage *s = GetStorage();
|
||||
DEBUG(script, 6, "SetLastCommand company=%02d tile=%06x p1=%08x p2=%08x cmd=%d", s->root_company, tile, p1, p2, cmd);
|
||||
Debug(script, 6, "SetLastCommand company={:02d} tile={:06x} p1={:08x} p2={:08x} cmd={}", s->root_company, tile, p1, p2, cmd);
|
||||
s->last_tile = tile;
|
||||
s->last_p1 = p1;
|
||||
s->last_p2 = p2;
|
||||
@@ -95,7 +95,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
|
||||
/* static */ bool ScriptObject::CheckLastCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd)
|
||||
{
|
||||
ScriptStorage *s = GetStorage();
|
||||
DEBUG(script, 6, "CheckLastCommand company=%02d tile=%06x p1=%08x p2=%08x cmd=%d", s->root_company, tile, p1, p2, cmd);
|
||||
Debug(script, 6, "CheckLastCommand company={:02d} tile={:06x} p1={:08x} p2={:08x} cmd={}", s->root_company, tile, p1, p2, cmd);
|
||||
if (s->last_tile != tile) return false;
|
||||
if (s->last_p1 != p1) return false;
|
||||
if (s->last_p2 != p2) return false;
|
||||
@@ -283,7 +283,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
|
||||
{
|
||||
char buffer[64];
|
||||
::GetString(buffer, string, lastof(buffer));
|
||||
::str_validate(buffer, lastof(buffer), SVS_NONE);
|
||||
::StrMakeValidInPlace(buffer, lastof(buffer), SVS_NONE);
|
||||
return ::stredup(buffer);
|
||||
}
|
||||
|
||||
@@ -309,10 +309,11 @@ ScriptObject::ActiveInstance::~ActiveInstance()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!StrEmpty(text) && (GetCommandFlags(cmd) & CMD_STR_CTRL) == 0) {
|
||||
std::string command_text = text == nullptr ? std::string{} : text;
|
||||
if (!command_text.empty() && (GetCommandFlags(cmd) & CMD_STR_CTRL) == 0) {
|
||||
/* 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. */
|
||||
::str_validate(const_cast<char *>(text), text + strlen(text), SVS_NONE);
|
||||
command_text = ::StrMakeValid(command_text, SVS_NONE);
|
||||
}
|
||||
|
||||
/* Set the default callback to return a true/false result of the DoCommand */
|
||||
@@ -328,7 +329,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
|
||||
if (!estimate_only && _networking && !_generating_world) SetLastCommand(tile, p1, p2, cmd);
|
||||
|
||||
/* Try to perform the command. */
|
||||
CommandCost res = ::DoCommandPInternal(tile, p1, p2, cmd, (_networking && !_generating_world) ? ScriptObject::GetActiveInstance()->GetDoCommandCallback() : nullptr, text, false, estimate_only);
|
||||
CommandCost res = ::DoCommandPInternal(tile, p1, p2, cmd, (_networking && !_generating_world) ? ScriptObject::GetActiveInstance()->GetDoCommandCallback() : nullptr, command_text, false, estimate_only);
|
||||
|
||||
/* We failed; set the error and bail out */
|
||||
if (res.Failed()) {
|
||||
@@ -365,7 +366,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
|
||||
IncreaseDoCommandCosts(res.GetCost());
|
||||
|
||||
/* Suspend the script player for 1+ ticks, so it simulates multiplayer. This
|
||||
* both avoids confusion when a developer launched his script in a
|
||||
* both avoids confusion when a developer launched the script in a
|
||||
* multiplayer game, but also gives time for the GUI and human player
|
||||
* to interact with the game. */
|
||||
throw Script_Suspend(GetDoCommandDelay(), callback);
|
||||
|
||||
@@ -256,11 +256,11 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
case OT_GOTO_STATION: {
|
||||
const Station *st = ::Station::Get(order->GetDestination());
|
||||
if (st->train_station.tile != INVALID_TILE) {
|
||||
TILE_AREA_LOOP(t, st->train_station) {
|
||||
for (TileIndex t : st->train_station) {
|
||||
if (st->TileBelongsToRailStation(t)) return t;
|
||||
}
|
||||
} else if (st->ship_station.tile != INVALID_TILE) {
|
||||
TILE_AREA_LOOP(t, st->ship_station) {
|
||||
for (TileIndex t : st->ship_station) {
|
||||
if (IsTileType(t, MP_STATION) && (IsDock(t) || IsOilRig(t)) && GetStationIndex(t) == st->index) return t;
|
||||
}
|
||||
} else if (st->bus_stops != nullptr) {
|
||||
@@ -268,7 +268,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
} else if (st->truck_stops != nullptr) {
|
||||
return st->truck_stops->xy;
|
||||
} else if (st->airport.tile != INVALID_TILE) {
|
||||
TILE_AREA_LOOP(tile, st->airport) {
|
||||
for (TileIndex tile : st->airport) {
|
||||
if (st->TileBelongsToAirport(tile) && !::IsHangar(tile)) return tile;
|
||||
}
|
||||
}
|
||||
@@ -278,7 +278,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
case OT_GOTO_WAYPOINT: {
|
||||
const Waypoint *wp = ::Waypoint::Get(order->GetDestination());
|
||||
if (wp->train_station.tile != INVALID_TILE) {
|
||||
TILE_AREA_LOOP(t, wp->train_station) {
|
||||
for (TileIndex t : wp->train_station) {
|
||||
if (wp->TileBelongsToRailStation(t)) return t;
|
||||
}
|
||||
}
|
||||
@@ -564,7 +564,7 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance)
|
||||
/* Make sure we don't go into an infinite loop */
|
||||
int retry = ScriptObject::GetCallbackVariable(3) - 1;
|
||||
if (retry < 0) {
|
||||
DEBUG(script, 0, "Possible infinite loop in SetOrderFlags() detected");
|
||||
Debug(script, 0, "Possible infinite loop in SetOrderFlags() detected");
|
||||
return false;
|
||||
}
|
||||
ScriptObject::SetCallbackVariable(3, retry);
|
||||
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
SQInteger Peek(HSQUIRRELVM vm);
|
||||
SQInteger Exists(HSQUIRRELVM vm);
|
||||
SQInteger Clear(HSQUIRRELVM vm);
|
||||
#endif
|
||||
#endif /* DOXYGEN_API */
|
||||
|
||||
/**
|
||||
* Check if the queue is empty.
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
int index = 0;
|
||||
const StationSpec *spec = StationClass::GetByGrf(file->grfid, res, &index);
|
||||
if (spec == nullptr) {
|
||||
DEBUG(grf, 1, "%s returned an invalid station ID for 'AI construction/purchase selection (18)' callback", file->filename);
|
||||
Debug(grf, 1, "{} returned an invalid station ID for 'AI construction/purchase selection (18)' callback", file->filename);
|
||||
} else {
|
||||
/* We might have gotten an usable station spec. Try to build it, but if it fails we'll fall back to the original station. */
|
||||
if (ScriptObject::DoCommand(tile, p1, p2 | spec->cls_id | index << 8, CMD_BUILD_RAIL_STATION)) return true;
|
||||
|
||||
@@ -279,7 +279,7 @@ public:
|
||||
class ScriptStationList_Vehicle : public ScriptList {
|
||||
public:
|
||||
/**
|
||||
* @param vehicle_id The vehicle to get the list of stations he has in its orders from.
|
||||
* @param vehicle_id The vehicle to get the list of stations it has in its orders from.
|
||||
*/
|
||||
ScriptStationList_Vehicle(VehicleID vehicle_id);
|
||||
};
|
||||
|
||||
@@ -36,7 +36,7 @@ protected:
|
||||
public:
|
||||
/**
|
||||
* Creating instance of this class switches the build mode to Testing.
|
||||
* @note When the instance is destroyed, he restores the mode that was
|
||||
* @note When the instance is destroyed, it restores the mode that was
|
||||
* current when the instance was created!
|
||||
*/
|
||||
ScriptTestMode();
|
||||
|
||||
@@ -82,7 +82,7 @@ SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm)
|
||||
sq_getstring(vm, -1, &value);
|
||||
|
||||
this->params[parameter] = stredup(value);
|
||||
ValidateString(this->params[parameter]);
|
||||
StrMakeValidInPlace(this->params[parameter]);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm)
|
||||
sq_pop(vm, 3);
|
||||
|
||||
/* Get the 'real' instance of this class */
|
||||
sq_getinstanceup(vm, -1, &real_instance, 0);
|
||||
sq_getinstanceup(vm, -1, &real_instance, nullptr);
|
||||
if (real_instance == nullptr) return SQ_ERROR;
|
||||
|
||||
ScriptText *value = static_cast<ScriptText *>(real_instance);
|
||||
@@ -157,7 +157,7 @@ SQInteger ScriptText::_set(HSQUIRRELVM vm)
|
||||
if (sq_gettype(vm, 2) == OT_STRING) {
|
||||
const SQChar *key_string;
|
||||
sq_getstring(vm, 2, &key_string);
|
||||
ValidateString(key_string);
|
||||
StrMakeValidInPlace(const_cast<char *>(key_string));
|
||||
|
||||
if (strncmp(key_string, "param_", 6) != 0 || strlen(key_string) > 8) return SQ_ERROR;
|
||||
k = atoi(key_string + 6);
|
||||
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
* @param ... Optional arguments for this string.
|
||||
*/
|
||||
ScriptText(StringID string, ...);
|
||||
#endif
|
||||
#endif /* DOXYGEN_API */
|
||||
~ScriptText();
|
||||
|
||||
#ifndef DOXYGEN_API
|
||||
|
||||
@@ -21,7 +21,7 @@ void ScriptTileList::AddRectangle(TileIndex t1, TileIndex t2)
|
||||
if (!::IsValidTile(t2)) return;
|
||||
|
||||
TileArea ta(t1, t2);
|
||||
TILE_AREA_LOOP(t, ta) this->AddItem(t);
|
||||
for (TileIndex t : ta) this->AddItem(t);
|
||||
}
|
||||
|
||||
void ScriptTileList::AddTile(TileIndex tile)
|
||||
@@ -37,7 +37,7 @@ void ScriptTileList::RemoveRectangle(TileIndex t1, TileIndex t2)
|
||||
if (!::IsValidTile(t2)) return;
|
||||
|
||||
TileArea ta(t1, t2);
|
||||
TILE_AREA_LOOP(t, ta) this->RemoveItem(t);
|
||||
for (TileIndex t : ta) this->RemoveItem(t);
|
||||
}
|
||||
|
||||
void ScriptTileList::RemoveTile(TileIndex tile)
|
||||
@@ -55,7 +55,7 @@ void ScriptTileList::RemoveTile(TileIndex tile)
|
||||
*/
|
||||
static void FillIndustryCatchment(const Industry *i, int radius, BitmapTileArea &bta)
|
||||
{
|
||||
TILE_AREA_LOOP(cur_tile, i->location) {
|
||||
for (TileIndex cur_tile : i->location) {
|
||||
if (!::IsTileType(cur_tile, MP_INDUSTRY) || ::GetIndustryIndex(cur_tile) != i->index) continue;
|
||||
|
||||
int tx = TileX(cur_tile);
|
||||
@@ -156,7 +156,7 @@ ScriptTileList_StationType::ScriptTileList_StationType(StationID station_id, Scr
|
||||
if ((station_type & ScriptStation::STATION_DOCK) != 0) station_type_value |= (1 << ::STATION_DOCK) | (1 << ::STATION_OILRIG);
|
||||
|
||||
TileArea ta(::TileXY(rect->left, rect->top), rect->right - rect->left + 1, rect->bottom - rect->top + 1);
|
||||
TILE_AREA_LOOP(cur_tile, ta) {
|
||||
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;
|
||||
|
||||
@@ -34,7 +34,9 @@ public:
|
||||
class ScriptWaypointList_Vehicle : public ScriptList {
|
||||
public:
|
||||
/**
|
||||
* @param vehicle_id The vehicle to get the list of waypoints he has in its orders from.
|
||||
* Get the waypoints from the orders of the given vehicle. Duplicates are
|
||||
* not added. Waypoints are added in the order of the vehicle's orders.
|
||||
* @param vehicle_id The vehicle to get the list of waypoints for.
|
||||
*/
|
||||
ScriptWaypointList_Vehicle(VehicleID vehicle_id);
|
||||
};
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
if (ScriptGame::IsMultiplayer()) return;
|
||||
|
||||
if (number == NUMBER_ALL) {
|
||||
DeleteWindowByClass((::WindowClass)window);
|
||||
CloseWindowByClass((::WindowClass)window);
|
||||
return;
|
||||
}
|
||||
|
||||
DeleteWindowById((::WindowClass)window, number);
|
||||
CloseWindowById((::WindowClass)window, number);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptWindow::IsOpen(WindowClass window, uint32 number)
|
||||
|
||||
Reference in New Issue
Block a user