From ec5e7ed5e02d4510f694f38baf1baae81e7b9dec Mon Sep 17 00:00:00 2001 From: glx22 Date: Sat, 20 Dec 2025 03:53:59 +0100 Subject: [PATCH] Change: [Script] ScripTiletList::[Add|Remove]Rectangle are now suspendable --- src/script/api/script_tilelist.cpp | 54 +++++++++++++++++++++++++----- src/script/api/script_tilelist.hpp | 12 +++++++ 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/script/api/script_tilelist.cpp b/src/script/api/script_tilelist.cpp index fed35b230b..eb42a8c112 100644 --- a/src/script/api/script_tilelist.cpp +++ b/src/script/api/script_tilelist.cpp @@ -30,13 +30,32 @@ ScriptObject *ScriptTileList::CloneObject() const return clone; } -void ScriptTileList::AddRectangle(TileIndex t1, TileIndex t2) +bool ScriptTileList::AddRectangle(TileIndex t1, TileIndex t2) { - if (!::IsValidTile(t1)) return; - if (!::IsValidTile(t2)) return; + if (!::IsValidTile(t1)) return false; + if (!::IsValidTile(t2)) return false; TileArea ta(t1, t2); - for (TileIndex t : ta) this->AddItem(t.base()); + + ScriptObject::DisableDoCommandScope disabler{}; + + OrthogonalTileIterator begin = ta.begin(); + if (disabler.GetOriginalValue() && this->resume_iter.has_value()) { + begin = this->resume_iter.value(); + } + + for (OrthogonalTileIterator iter = begin; iter != ta.end(); ++iter) { + TileIndex t = iter; + if (disabler.GetOriginalValue() && iter != begin && ScriptController::GetOpsTillSuspend() < 0) { + this->resume_iter = iter; + return true; + } + this->AddItem(t.base()); + ScriptController::DecreaseOps(5); + } + + this->resume_iter.reset(); + return false; } void ScriptTileList::AddTile(TileIndex tile) @@ -46,13 +65,32 @@ void ScriptTileList::AddTile(TileIndex tile) this->AddItem(tile.base()); } -void ScriptTileList::RemoveRectangle(TileIndex t1, TileIndex t2) +bool ScriptTileList::RemoveRectangle(TileIndex t1, TileIndex t2) { - if (!::IsValidTile(t1)) return; - if (!::IsValidTile(t2)) return; + if (!::IsValidTile(t1)) return false; + if (!::IsValidTile(t2)) return false; TileArea ta(t1, t2); - for (TileIndex t : ta) this->RemoveItem(t.base()); + + ScriptObject::DisableDoCommandScope disabler{}; + + OrthogonalTileIterator begin = ta.begin(); + if (disabler.GetOriginalValue() && this->resume_iter.has_value()) { + begin = this->resume_iter.value(); + } + + for (OrthogonalTileIterator iter = begin; iter != ta.end(); ++iter) { + TileIndex t = iter; + if (disabler.GetOriginalValue() && iter != begin && ScriptController::GetOpsTillSuspend() < 0) { + this->resume_iter = iter; + return true; + } + this->RemoveItem(t.base()); + ScriptController::DecreaseOps(5); + } + + this->resume_iter.reset(); + return false; } void ScriptTileList::RemoveTile(TileIndex tile) diff --git a/src/script/api/script_tilelist.hpp b/src/script/api/script_tilelist.hpp index d126b9312c..e89ff0610f 100644 --- a/src/script/api/script_tilelist.hpp +++ b/src/script/api/script_tilelist.hpp @@ -20,6 +20,8 @@ * @ingroup ScriptList */ class ScriptTileList : public ScriptList { +private: + std::optional resume_iter; protected: virtual bool SaveObject(HSQUIRRELVM) const override; virtual ScriptObject *CloneObject() const override; @@ -30,8 +32,13 @@ public: * @param tile_to The other corner of the tiles to add. * @pre ScriptMap::IsValidTile(tile_from). * @pre ScriptMap::IsValidTile(tile_to). + * @suspendable */ +#ifdef DOXYGEN_API void AddRectangle(TileIndex tile_from, TileIndex tile_to); +#else + bool AddRectangle(TileIndex tile_from, TileIndex tile_to); +#endif /* DOXYGEN_API */ /** * Add a tile to the to-be-evaluated tiles. @@ -46,8 +53,13 @@ public: * @param tile_to The other corner of the files to remove. * @pre ScriptMap::IsValidTile(tile_from). * @pre ScriptMap::IsValidTile(tile_to). + * @suspendable */ +#ifdef DOXYGEN_API void RemoveRectangle(TileIndex tile_from, TileIndex tile_to); +#else + bool RemoveRectangle(TileIndex tile_from, TileIndex tile_to); +#endif /* DOXYGEN_API */ /** * Remove a tile from the list.