1
0
Fork 0

Add: [Script] Saving/loading ScriptList

pull/13700/head
glx22 2025-02-14 02:20:28 +01:00 committed by Loïc Guilloux
parent d6a261439b
commit a6f558ce2a
7 changed files with 67 additions and 3 deletions

View File

@ -25,6 +25,7 @@
* 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

@ -25,6 +25,7 @@
* 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
*

View File

@ -77,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

View File

@ -403,6 +403,56 @@ 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 */

View File

@ -149,6 +149,9 @@ protected:
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

@ -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;

View File

@ -20,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.