# HG changeset patch # User Tyler Trahan # Date 2024-01-23 15:42:10 # Node ID 9d9a6cccb728e244809bb7c5fbdfe9b0af2d0672 # Parent 41091a9754aa5fa395d195e2e3f77740173f8b2f Add: AI/GS Time Mode to choose between economy (default) and calendar time (#11603) diff --git a/src/script/api/CMakeLists.txt b/src/script/api/CMakeLists.txt --- a/src/script/api/CMakeLists.txt +++ b/src/script/api/CMakeLists.txt @@ -151,6 +151,7 @@ add_files( script_basestation.hpp script_bridge.hpp script_bridgelist.hpp + script_timemode.hpp script_cargo.hpp script_cargolist.hpp script_cargomonitor.hpp @@ -225,6 +226,7 @@ add_files( script_basestation.cpp script_bridge.cpp script_bridgelist.cpp + script_timemode.cpp script_cargo.cpp script_cargolist.cpp script_cargomonitor.cpp diff --git a/src/script/api/ai_changelog.hpp b/src/script/api/ai_changelog.hpp --- a/src/script/api/ai_changelog.hpp +++ b/src/script/api/ai_changelog.hpp @@ -18,6 +18,7 @@ * This version is not yet released. The following changes are not set in stone yet. * * API additions: + * \li AITimeMode * \li AITown::ROAD_LAYOUT_RANDOM * \li AIVehicle::IsPrimaryVehicle * diff --git a/src/script/api/game_changelog.hpp b/src/script/api/game_changelog.hpp --- a/src/script/api/game_changelog.hpp +++ b/src/script/api/game_changelog.hpp @@ -22,6 +22,7 @@ * \li GSAsyncMode * \li GSCompanyMode::IsValid * \li GSCompanyMode::IsDeity + * \li GSTimeMode * \li GSTown::ROAD_LAYOUT_RANDOM * \li GSVehicle::IsPrimaryVehicle * \li GSOrder::SetOrderJumpTo diff --git a/src/script/api/script_date.cpp b/src/script/api/script_date.cpp --- a/src/script/api/script_date.cpp +++ b/src/script/api/script_date.cpp @@ -9,7 +9,9 @@ #include "../../stdafx.h" #include "script_date.hpp" +#include "script_timemode.hpp" #include "../../timer/timer_game_calendar.h" +#include "../../timer/timer_game_economy.h" #include @@ -22,14 +24,21 @@ /* static */ ScriptDate::Date ScriptDate::GetCurrentDate() { - return (ScriptDate::Date)TimerGameCalendar::date.base(); + if (ScriptTimeMode::IsCalendarMode()) return (ScriptDate::Date)TimerGameCalendar::date.base(); + + return (ScriptDate::Date)TimerGameEconomy::date.base(); } /* static */ SQInteger ScriptDate::GetYear(ScriptDate::Date date) { if (date < 0) return DATE_INVALID; - ::TimerGameCalendar::YearMonthDay ymd = ::TimerGameCalendar::ConvertDateToYMD(date); + if (ScriptTimeMode::IsCalendarMode()) { + ::TimerGameCalendar::YearMonthDay ymd = ::TimerGameCalendar::ConvertDateToYMD(date); + return ymd.year.base(); + } + + ::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(date); return ymd.year.base(); } @@ -37,7 +46,12 @@ { if (date < 0) return DATE_INVALID; - ::TimerGameCalendar::YearMonthDay ymd = ::TimerGameCalendar::ConvertDateToYMD(date); + if (ScriptTimeMode::IsCalendarMode()) { + ::TimerGameCalendar::YearMonthDay ymd = ::TimerGameCalendar::ConvertDateToYMD(date); + return ymd.month + 1; + } + + ::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(date); return ymd.month + 1; } @@ -45,7 +59,12 @@ { if (date < 0) return DATE_INVALID; - ::TimerGameCalendar::YearMonthDay ymd = ::TimerGameCalendar::ConvertDateToYMD(date); + if (ScriptTimeMode::IsCalendarMode()) { + ::TimerGameCalendar::YearMonthDay ymd = ::TimerGameCalendar::ConvertDateToYMD(date); + return ymd.day; + } + + ::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(date); return ymd.day; } @@ -55,7 +74,9 @@ if (day_of_month < 1 || day_of_month > 31) return DATE_INVALID; if (year < 0 || year > CalendarTime::MAX_YEAR) return DATE_INVALID; - return (ScriptDate::Date)::TimerGameCalendar::ConvertYMDToDate(year, month - 1, day_of_month).base(); + if (ScriptTimeMode::IsCalendarMode()) return (ScriptDate::Date)::TimerGameCalendar::ConvertYMDToDate(year, month - 1, day_of_month).base(); + + return (ScriptDate::Date)::TimerGameEconomy::ConvertYMDToDate(year, month - 1, day_of_month).base(); } /* static */ SQInteger ScriptDate::GetSystemTime() diff --git a/src/script/api/script_object.cpp b/src/script/api/script_object.cpp --- a/src/script/api/script_object.cpp +++ b/src/script/api/script_object.cpp @@ -200,6 +200,16 @@ ScriptObject::ActiveInstance::~ActiveIns return GetStorage()->allow_do_command; } +/* static */ void ScriptObject::SetTimeMode(bool calendar) +{ + GetStorage()->time_mode = calendar; +} + +/* static */ bool ScriptObject::IsCalendarTimeMode() +{ + return GetStorage()->time_mode; +} + /* static */ void ScriptObject::SetCompany(CompanyID company) { if (GetStorage()->root_company == INVALID_OWNER) GetStorage()->root_company = company; diff --git a/src/script/api/script_object.hpp b/src/script/api/script_object.hpp --- a/src/script/api/script_object.hpp +++ b/src/script/api/script_object.hpp @@ -245,6 +245,20 @@ protected: static bool GetAllowDoCommand(); /** + * Set if the script is running in calendar time or economy time mode. + * Calendar time is used by OpenTTD for technology like vehicle introductions and expiration, and variable snowline. It can be sped up or slowed down by the player. + * Economy time always runs at the same pace and handles things like cargo production, everything related to money, etc. + * @param Calendar Should we use calendar time mode? (Set to false for economy time mode.) + */ + static void SetTimeMode(bool calendar); + + /** + * Check if the script is operating in calendar time mode, or in economy time mode. See SetTimeMode() for more information. + * @return True if we are in calendar time mode, false if we are in economy time mode. + */ + static bool IsCalendarTimeMode(); + + /** * Set the current company to execute commands for or request * information about. * @param company The new company. diff --git a/src/script/api/script_timemode.cpp b/src/script/api/script_timemode.cpp new file mode 100644 --- /dev/null +++ b/src/script/api/script_timemode.cpp @@ -0,0 +1,29 @@ +/* + * 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 . + */ + +/** @file script_timemode.cpp Implementation of ScriptTimeMode. */ + +#include "../../stdafx.h" +#include "script_timemode.hpp" + +#include "../../safeguards.h" + +ScriptTimeMode::ScriptTimeMode(bool calendar) +{ + this->last_time_mode = ScriptObject::IsCalendarTimeMode(); + ScriptObject::SetTimeMode(calendar); +} + +ScriptTimeMode::~ScriptTimeMode() +{ + ScriptObject::SetTimeMode(this->last_time_mode); +} + +/* static */ bool ScriptTimeMode::IsCalendarMode() +{ + return ScriptObject::IsCalendarTimeMode(); +} diff --git a/src/script/api/script_timemode.hpp b/src/script/api/script_timemode.hpp new file mode 100644 --- /dev/null +++ b/src/script/api/script_timemode.hpp @@ -0,0 +1,45 @@ +/* + * 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 . + */ + +/** @file script_timemode.hpp Switch the time mode. */ + +#ifndef SCRIPT_TIMEMODE_HPP +#define SCRIPT_TIMEMODE_HPP + +#include "script_object.hpp" + +/** + * Class to switch the current time. + * If you create an instance of this class, the mode will be switched to either calendar time or economy time mode. + * @note Destroying this object will restore the previous time mode. + * @api ai game + */ +class ScriptTimeMode : public ScriptObject { +private: + bool last_time_mode; ///< The last time mode we were using. +public: + /** + * Creating an instance of this class switches the time mode used for queries and commands. + * Calendar time is used by OpenTTD for technology like vehicle introductions and expiration, and variable snowline. It can be sped up or slowed down by the player. + * Economy time always runs at the same pace and handles things like cargo production, everything related to money, etc. + * @param Calendar Should we use calendar time mode? (Set to false for economy time mode.) + */ + ScriptTimeMode(bool calendar); + + /** + * Destroying this instance resets the time mode to the mode it was in when the instance was created. + */ + ~ScriptTimeMode(); + + /** + * Check if the script is operating in calendar time mode, or in economy time mode. See ScriptTimeMode() for more information. + * @return True if we are in calendar time mode, false if we are in economy time mode. + */ + static bool IsCalendarMode(); +}; + +#endif /* SCRIPT_TIMEMODE_HPP */ diff --git a/src/script/script_storage.hpp b/src/script/script_storage.hpp --- a/src/script/script_storage.hpp +++ b/src/script/script_storage.hpp @@ -41,6 +41,7 @@ private: class ScriptObject *mode_instance; ///< The instance belonging to the current build mode. ScriptAsyncModeProc *async_mode; ///< The current command async mode we are in. class ScriptObject *async_mode_instance; ///< The instance belonging to the current command async mode. + bool time_mode; ///< True if we in calendar time mode, or false (default) if we are in economy time mode. CompanyID root_company; ///< The root company, the company that the script really belongs to. CompanyID company; ///< The current company. @@ -70,6 +71,7 @@ public: mode_instance (nullptr), async_mode (nullptr), async_mode_instance (nullptr), + time_mode (false), root_company (INVALID_OWNER), company (INVALID_OWNER), delay (1),