diff --git a/regression/regression/main.nut b/regression/regression/main.nut index f023f0f7d0..025ece0c3a 100644 --- a/regression/regression/main.nut +++ b/regression/regression/main.nut @@ -1828,6 +1828,17 @@ function Regression::Vehicle() print(" GetLastErrorString(): " + AIError.GetLastErrorString()); print(" SendVehicleToDepot(): " + AIVehicle.SendVehicleToDepot(13)); print(" GetLastErrorString(): " + AIError.GetLastErrorString()); + print(" BuildVehicle(): " + AIVehicle.BuildVehicle(33417, 116)); + print(" AppendOrder(): " + AIOrder.AppendOrder(20, 33421, AIOrder.OF_NONE)); + print(" GetLastError(): " + AIError.GetLastError()); + print(" GetLastErrorString(): " + AIError.GetLastErrorString()); + print(" GetExtraLastError(): " + AIError.GetExtraLastError()); + print(" GetExtraLastErrorString(): " + AIError.GetExtraLastErrorString()); + print(" SellVehicle(): " + AIVehicle.SellVehicle(20)); + print(" GetLastError(): " + AIError.GetLastError()); + print(" GetLastErrorString(): " + AIError.GetLastErrorString()); + print(" GetExtraLastError(): " + AIError.GetExtraLastError()); + print(" GetExtraLastErrorString(): " + AIError.GetExtraLastErrorString()); local list = AIVehicleList(); local in_depot = AIVehicleList(AIVehicle.IsInDepot); diff --git a/regression/regression/result.txt b/regression/regression/result.txt index 8611b2f8aa..d9b4763929 100644 --- a/regression/regression/result.txt +++ b/regression/regression/result.txt @@ -9546,6 +9546,17 @@ ERROR: IsEnd() is invalid as Begin() is never called GetLastErrorString(): ERR_VEHICLE_NOT_IN_DEPOT SendVehicleToDepot(): false GetLastErrorString(): ERR_UNKNOWN + BuildVehicle(): 20 + AppendOrder(): false + GetLastError(): 1 + GetLastErrorString(): ERR_UNKNOWN + GetExtraLastError(): 1 + GetExtraLastErrorString(): ERR_UNKNOWN + SellVehicle(): true + GetLastError(): 0 + GetLastErrorString(): ERR_NONE + GetExtraLastError(): 0 + GetExtraLastErrorString(): ERR_NONE --VehicleList-- Count(): 5 @@ -9588,7 +9599,7 @@ ERROR: IsEnd() is invalid as Begin() is never called 13 => 5490 12 => 5489 CurrentSpeed ListDump: - 12 => 27 + 12 => 31 17 => 0 16 => 0 14 => 0 @@ -9763,9 +9774,9 @@ ERROR: IsEnd() is invalid as Begin() is never called --Valuate() with excessive CPU usage-- Your script made an error: excessive CPU usage in valuator function -*FUNCTION [unknown()] regression/main.nut line [2065] +*FUNCTION [unknown()] regression/main.nut line [2076] *FUNCTION [Valuate()] NATIVE line [-1] -*FUNCTION [Start()] regression/main.nut line [2066] +*FUNCTION [Start()] regression/main.nut line [2077] [id] 0 [this] TABLE @@ -9774,7 +9785,7 @@ Your script made an error: excessive CPU usage in valuator function [this] INSTANCE Your script made an error: excessive CPU usage in valuator function -*FUNCTION [Start()] regression/main.nut line [2066] +*FUNCTION [Start()] regression/main.nut line [2077] [Infinite] CLOSURE [list] INSTANCE diff --git a/src/script/api/ai_changelog.hpp b/src/script/api/ai_changelog.hpp index ecc51d8072..5a5c6a205f 100644 --- a/src/script/api/ai_changelog.hpp +++ b/src/script/api/ai_changelog.hpp @@ -21,6 +21,8 @@ * \li AIEventVehicleCrashed::GetVictims * \li AIEventCompanyRenamed * \li AIEventPresidentRenamed + * \li AIError::GetExtraLastError + * \li AIError::GetExtraLastErrorString * * \b 14.0 * diff --git a/src/script/api/game_changelog.hpp b/src/script/api/game_changelog.hpp index 655cfac0b6..92a53f09f0 100644 --- a/src/script/api/game_changelog.hpp +++ b/src/script/api/game_changelog.hpp @@ -21,6 +21,8 @@ * \li GSEventVehicleCrashed::GetVictims * \li GSEventCompanyRenamed * \li GSEventPresidentRenamed + * \li GSError::GetExtraLastError + * \li GSError::GetExtraLastErrorString * * \b 14.0 * diff --git a/src/script/api/script_error.cpp b/src/script/api/script_error.cpp index a3f0e48d96..776dd82533 100644 --- a/src/script/api/script_error.cpp +++ b/src/script/api/script_error.cpp @@ -23,11 +23,21 @@ ScriptError::ScriptErrorMapString ScriptError::error_map_string = ScriptError::S return ScriptObject::GetLastError(); } +/* static */ ScriptErrorType ScriptError::GetExtraLastError() +{ + return ScriptObject::GetExtraLastError(); +} + /* static */ std::optional ScriptError::GetLastErrorString() { return (*error_map_string.find(ScriptError::GetLastError())).second; } +/* static */ std::optional ScriptError::GetExtraLastErrorString() +{ + return (*error_map_string.find(ScriptError::GetExtraLastError())).second; +} + /* static */ ScriptErrorType ScriptError::StringToError(StringID internal_string_id) { StringIndexInTab index = GetStringIndex(internal_string_id); diff --git a/src/script/api/script_error.hpp b/src/script/api/script_error.hpp index 84f2d6e86f..11e046b32f 100644 --- a/src/script/api/script_error.hpp +++ b/src/script/api/script_error.hpp @@ -21,6 +21,7 @@ #define EnforcePrecondition(returnval, condition) \ if (!(condition)) { \ ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_FAILED); \ + ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN); \ return returnval; \ } @@ -33,6 +34,7 @@ #define EnforcePreconditionCustomError(returnval, condition, error_code) \ if (!(condition)) { \ ScriptObject::SetLastError(error_code); \ + ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN); \ return returnval; \ } @@ -44,6 +46,7 @@ #define EnforcePreconditionEncodedText(returnval, string) \ if (string.empty()) { \ ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_FAILED); \ + ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN); \ return returnval; \ } @@ -60,6 +63,7 @@ #define EnforceCompanyModeValid_Void() \ if (!ScriptCompanyMode::IsValid()) { \ ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY); \ + ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN); \ return; \ } @@ -83,6 +87,7 @@ #define EnforceDeityOrCompanyModeValid_Void() \ if (!(ScriptCompanyMode::IsDeity() || ScriptCompanyMode::IsValid())) { \ ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY); \ + ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN); \ return; \ } @@ -190,12 +195,24 @@ public: */ static ScriptErrorType GetLastError(); + /** + * Get the extra last error. + * @return An ErrorMessages enum value. + */ + static ScriptErrorType GetExtraLastError(); + /** * Get the last error in string format (for human readability). * @return An ErrorMessage enum item, as string. */ static std::optional GetLastErrorString(); + /** + * Get the extra last error in string format (for human readability). + * @return An ErrorMessage enum item, as string. + */ + static std::optional GetExtraLastErrorString(); + /** * Get the error based on the OpenTTD StringID. * @api -all diff --git a/src/script/api/script_object.cpp b/src/script/api/script_object.cpp index cc94b18ff0..8f947b57b3 100644 --- a/src/script/api/script_object.cpp +++ b/src/script/api/script_object.cpp @@ -150,11 +150,21 @@ ScriptObject::ActiveInstance::~ActiveInstance() GetStorage()->last_error = last_error; } +/* static */ void ScriptObject::SetExtraLastError(ScriptErrorType extra_last_error) +{ + GetStorage()->extra_last_error = extra_last_error; +} + /* static */ ScriptErrorType ScriptObject::GetLastError() { return GetStorage()->last_error; } +/* static */ ScriptErrorType ScriptObject::GetExtraLastError() +{ + return GetStorage()->extra_last_error; +} + /* static */ void ScriptObject::SetLastCost(Money last_cost) { GetStorage()->last_cost = last_cost; @@ -286,6 +296,7 @@ std::tuple ScriptObject::DoCommandPrep() if (!ScriptCompanyMode::IsDeity() && !ScriptCompanyMode::IsValid()) { ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY); + ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN); return { true, estimate_only, asynchronous, networking }; } @@ -300,11 +311,13 @@ bool ScriptObject::DoCommandProcessResult(const CommandCost &res, Script_Suspend /* We failed; set the error and bail out */ if (res.Failed()) { SetLastError(ScriptError::StringToError(res.GetErrorMessage())); + SetExtraLastError(ScriptError::StringToError(res.GetExtraErrorMessage())); return false; } /* No error, then clear it. */ SetLastError(ScriptError::ERR_NONE); + SetExtraLastError(ScriptError::ERR_NONE); /* Estimates, update the cost for the estimate and be done */ if (estimate_only) { diff --git a/src/script/api/script_object.hpp b/src/script/api/script_object.hpp index c6533991df..297093cdcf 100644 --- a/src/script/api/script_object.hpp +++ b/src/script/api/script_object.hpp @@ -174,11 +174,21 @@ protected: */ static void SetLastError(ScriptErrorType last_error); + /** + * Set the DoCommand extra last error. + */ + static void SetExtraLastError(ScriptErrorType extra_last_error); + /** * Get the DoCommand last error. */ static ScriptErrorType GetLastError(); + /** + * Get the DoCommand extra last error. + */ + static ScriptErrorType GetExtraLastError(); + /** * Set the road type. */ diff --git a/src/script/api/script_priorityqueue.cpp b/src/script/api/script_priorityqueue.cpp index c9cdc82862..b11492a968 100644 --- a/src/script/api/script_priorityqueue.cpp +++ b/src/script/api/script_priorityqueue.cpp @@ -52,6 +52,7 @@ SQInteger ScriptPriorityQueue::Pop(HSQUIRRELVM vm) { if (this->IsEmpty()) { ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_FAILED); + ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN); sq_pushnull(vm); return 1; } @@ -70,6 +71,7 @@ SQInteger ScriptPriorityQueue::Peek(HSQUIRRELVM vm) { if (this->IsEmpty()) { ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_FAILED); + ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN); sq_pushnull(vm); return 1; } diff --git a/src/script/api/script_town.cpp b/src/script/api/script_town.cpp index 7c601e3884..d8c286932f 100644 --- a/src/script/api/script_town.cpp +++ b/src/script/api/script_town.cpp @@ -305,6 +305,7 @@ uint32_t townnameparts; if (!GenerateTownName(ScriptObject::GetRandomizer(), &townnameparts)) { ScriptObject::SetLastError(ScriptError::ERR_NAME_IS_NOT_UNIQUE); + ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN); return false; } diff --git a/src/script/script_instance.cpp b/src/script/script_instance.cpp index 91a15acb6e..18098ca6c5 100644 --- a/src/script/script_instance.cpp +++ b/src/script/script_instance.cpp @@ -759,6 +759,7 @@ bool ScriptInstance::DoCommandCallback(const CommandCost &result, const CommandD if (result.Failed()) { ScriptObject::SetLastError(ScriptError::StringToError(result.GetErrorMessage())); + ScriptObject::SetExtraLastError(ScriptError::StringToError(result.GetExtraErrorMessage())); } else { ScriptObject::IncreaseDoCommandCosts(result.GetCost()); ScriptObject::SetLastCost(result.GetCost()); diff --git a/src/script/script_storage.hpp b/src/script/script_storage.hpp index 3edfe978c1..02996906d4 100644 --- a/src/script/script_storage.hpp +++ b/src/script/script_storage.hpp @@ -51,6 +51,7 @@ private: CommandCost costs; ///< The costs the script is tracking. Money last_cost; ///< The last cost of the command. ScriptErrorType last_error{}; ///< The last error of the command. + ScriptErrorType extra_last_error{}; ///< The extra last error of the command. bool last_command_res; ///< The last result of the command. CommandDataBuffer last_data; ///< The last data passed to a command.