diff --git a/projects/openttd_vs140.vcxproj b/projects/openttd_vs140.vcxproj
index 4acddaf242..d2ef91a877 100644
--- a/projects/openttd_vs140.vcxproj
+++ b/projects/openttd_vs140.vcxproj
@@ -1152,6 +1152,7 @@
+
@@ -1219,6 +1220,7 @@
+
diff --git a/projects/openttd_vs140.vcxproj.filters b/projects/openttd_vs140.vcxproj.filters
index f5220a6c3c..f37355d847 100644
--- a/projects/openttd_vs140.vcxproj.filters
+++ b/projects/openttd_vs140.vcxproj.filters
@@ -2553,6 +2553,9 @@
Script API
+
+ Script API
+
Script API
@@ -2754,6 +2757,9 @@
Script API Implementation
+
+ Script API Implementation
+
Script API Implementation
diff --git a/projects/openttd_vs141.vcxproj b/projects/openttd_vs141.vcxproj
index 6f12343986..1e2c8aa668 100644
--- a/projects/openttd_vs141.vcxproj
+++ b/projects/openttd_vs141.vcxproj
@@ -1152,6 +1152,7 @@
+
@@ -1219,6 +1220,7 @@
+
diff --git a/projects/openttd_vs141.vcxproj.filters b/projects/openttd_vs141.vcxproj.filters
index f5220a6c3c..f37355d847 100644
--- a/projects/openttd_vs141.vcxproj.filters
+++ b/projects/openttd_vs141.vcxproj.filters
@@ -2553,6 +2553,9 @@
Script API
+
+ Script API
+
Script API
@@ -2754,6 +2757,9 @@
Script API Implementation
+
+ Script API Implementation
+
Script API Implementation
diff --git a/projects/openttd_vs142.vcxproj b/projects/openttd_vs142.vcxproj
index ce748dd11d..66a7de6918 100644
--- a/projects/openttd_vs142.vcxproj
+++ b/projects/openttd_vs142.vcxproj
@@ -1152,6 +1152,7 @@
+
@@ -1219,6 +1220,7 @@
+
diff --git a/projects/openttd_vs142.vcxproj.filters b/projects/openttd_vs142.vcxproj.filters
index f5220a6c3c..f37355d847 100644
--- a/projects/openttd_vs142.vcxproj.filters
+++ b/projects/openttd_vs142.vcxproj.filters
@@ -2553,6 +2553,9 @@
Script API
+
+ Script API
+
Script API
@@ -2754,6 +2757,9 @@
Script API Implementation
+
+ Script API Implementation
+
Script API Implementation
diff --git a/source.list b/source.list
index 05c1bcbac4..f2dbf76563 100644
--- a/source.list
+++ b/source.list
@@ -887,6 +887,7 @@ script/api/script_marine.hpp
script/api/script_news.hpp
script/api/script_object.hpp
script/api/script_order.hpp
+script/api/script_priorityqueue.hpp
script/api/script_rail.hpp
script/api/script_railtypelist.hpp
script/api/script_road.hpp
@@ -956,6 +957,7 @@ script/api/script_marine.cpp
script/api/script_news.cpp
script/api/script_object.cpp
script/api/script_order.cpp
+script/api/script_priorityqueue.cpp
script/api/script_rail.cpp
script/api/script_railtypelist.cpp
script/api/script_road.cpp
diff --git a/src/ai/ai_instance.cpp b/src/ai/ai_instance.cpp
index a4d06763fa..49f8cff64d 100644
--- a/src/ai/ai_instance.cpp
+++ b/src/ai/ai_instance.cpp
@@ -57,6 +57,7 @@
#include "../script/api/ai/ai_map.hpp.sq"
#include "../script/api/ai/ai_marine.hpp.sq"
#include "../script/api/ai/ai_order.hpp.sq"
+#include "../script/api/ai/ai_priorityqueue.hpp.sq"
#include "../script/api/ai/ai_rail.hpp.sq"
#include "../script/api/ai/ai_railtypelist.hpp.sq"
#include "../script/api/ai/ai_road.hpp.sq"
@@ -164,6 +165,7 @@ void AIInstance::RegisterAPI()
SQAIMap_Register(this->engine);
SQAIMarine_Register(this->engine);
SQAIOrder_Register(this->engine);
+ SQAIPriorityQueue_Register(this->engine);
SQAIRail_Register(this->engine);
SQAIRailTypeList_Register(this->engine);
SQAIRoad_Register(this->engine);
diff --git a/src/game/game_instance.cpp b/src/game/game_instance.cpp
index 4424c801c6..47d51e28ee 100644
--- a/src/game/game_instance.cpp
+++ b/src/game/game_instance.cpp
@@ -59,6 +59,7 @@
#include "../script/api/game/game_marine.hpp.sq"
#include "../script/api/game/game_news.hpp.sq"
#include "../script/api/game/game_order.hpp.sq"
+#include "../script/api/game/game_priorityqueue.hpp.sq"
#include "../script/api/game/game_rail.hpp.sq"
#include "../script/api/game/game_railtypelist.hpp.sq"
#include "../script/api/game/game_road.hpp.sq"
@@ -173,6 +174,7 @@ void GameInstance::RegisterAPI()
SQGSMarine_Register(this->engine);
SQGSNews_Register(this->engine);
SQGSOrder_Register(this->engine);
+ SQGSPriorityQueue_Register(this->engine);
SQGSRail_Register(this->engine);
SQGSRailTypeList_Register(this->engine);
SQGSRoad_Register(this->engine);
diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt
index 0a51385f38..deadd33a80 100644
--- a/src/lang/croatian.txt
+++ b/src/lang/croatian.txt
@@ -1031,6 +1031,7 @@ STR_GAME_OPTIONS_CURRENCY_MXN :Meksički Pesos
STR_GAME_OPTIONS_CURRENCY_NTD :Novi Tajvanski Dolar (NTD)
STR_GAME_OPTIONS_CURRENCY_CNY :Kineski Renminbi (CNY)
STR_GAME_OPTIONS_CURRENCY_HKD :Hongkonški Dolar (HKD)
+STR_GAME_OPTIONS_CURRENCY_INR :Indijska Rupija (INR)
############ end of currency region
STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Cestovna vozila
diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp
index 6083396eeb..dd87a4948b 100644
--- a/src/network/network_content_gui.cpp
+++ b/src/network/network_content_gui.cpp
@@ -951,7 +951,7 @@ public:
{
if (this->auto_select && !rci->IsSelected()) _network_content_client.ToggleSelectedState(rci);
this->content.ForceRebuild();
- this->InvalidateData();
+ this->InvalidateData(0, false);
}
void OnDownloadComplete(ContentID cid) override
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index e20c94e3e0..1e03c5f6be 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -9279,18 +9279,18 @@ GRFFile::GRFFile(const GRFConfig *config)
}
/* Initialise rail type map with default rail types */
- memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
+ std::fill(std::begin(this->railtype_map), std::end(this->railtype_map), INVALID_RAILTYPE);
this->railtype_map[0] = RAILTYPE_RAIL;
this->railtype_map[1] = RAILTYPE_ELECTRIC;
this->railtype_map[2] = RAILTYPE_MONO;
this->railtype_map[3] = RAILTYPE_MAGLEV;
/* Initialise road type map with default road types */
- memset(this->roadtype_map, INVALID_ROADTYPE, sizeof(this->roadtype_map));
+ std::fill(std::begin(this->roadtype_map), std::end(this->roadtype_map), INVALID_ROADTYPE);
this->roadtype_map[0] = ROADTYPE_ROAD;
/* Initialise tram type map with default tram types */
- memset(this->tramtype_map, INVALID_ROADTYPE, sizeof(this->tramtype_map));
+ std::fill(std::begin(this->tramtype_map), std::end(this->tramtype_map), INVALID_ROADTYPE);
this->tramtype_map[0] = ROADTYPE_TRAM;
/* Copy the initial parameter list
diff --git a/src/newgrf.h b/src/newgrf.h
index 8b6362db7d..24093f6564 100644
--- a/src/newgrf.h
+++ b/src/newgrf.h
@@ -244,7 +244,7 @@ struct GRFFile : ZeroedMemoryAllocator {
std::vector roadtype_list; ///< Roadtype translation table (road)
RoadType roadtype_map[ROADTYPE_END];
- std::vector tramtype_list; ///, Roadtype translation table (tram)
+ std::vector tramtype_list; ///< Roadtype translation table (tram)
RoadType tramtype_map[ROADTYPE_END];
CanalProperties canal_local_properties[CF_END]; ///< Canal properties as set by this NewGRF
diff --git a/src/os/windows/crashlog_win.cpp b/src/os/windows/crashlog_win.cpp
index 7e4bb2aec4..bc164c12ce 100644
--- a/src/os/windows/crashlog_win.cpp
+++ b/src/os/windows/crashlog_win.cpp
@@ -617,6 +617,9 @@ void *_safe_esp = nullptr;
static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep)
{
+ /* Disable our event loop. */
+ SetWindowLongPtr(GetActiveWindow(), GWLP_WNDPROC, (LONG_PTR)&DefWindowProc);
+
if (CrashLogWindows::current != nullptr) {
CrashLog::AfterCrashLogCleanup();
ExitProcess(2);
diff --git a/src/os/windows/ottdres.rc.in b/src/os/windows/ottdres.rc.in
index 44c04c919d..861015eb70 100644
--- a/src/os/windows/ottdres.rc.in
+++ b/src/os/windows/ottdres.rc.in
@@ -44,17 +44,17 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_DEFAULT
// Dialog
//
-100 DIALOG DISCARDABLE 0, 0, 305, 99
+100 DIALOG DISCARDABLE 0, 0, 305, 101
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Fatal Application Failure"
FONT 8, "MS Sans Serif"
BEGIN
- PUSHBUTTON "&Close",12,7,80,50,14
- PUSHBUTTON "&Emergency save",13,155,80,68,14
- PUSHBUTTON "",15,243,80,55,14
- EDITTEXT 11,7,101,291,118,ES_MULTILINE | ES_READONLY | WS_VSCROLL |
+ PUSHBUTTON "&Close",12,7,82,60,14
+ PUSHBUTTON "&Emergency save",13,158,82,60,14
+ PUSHBUTTON "",15,238,82,60,14
+ EDITTEXT 11,7,103,291,118,ES_MULTILINE | ES_READONLY | WS_VSCROLL |
WS_HSCROLL | NOT WS_TABSTOP
- LTEXT "",10,36,7,262,65
+ LTEXT "",10,36,5,262,72
ICON 100,IDC_STATIC,9,9,20,20
END
diff --git a/src/script/api/ai/ai_priorityqueue.hpp.sq b/src/script/api/ai/ai_priorityqueue.hpp.sq
new file mode 100644
index 0000000000..6e5fcf82e9
--- /dev/null
+++ b/src/script/api/ai/ai_priorityqueue.hpp.sq
@@ -0,0 +1,31 @@
+/*
+ * 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 .
+ */
+
+/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
+
+#include "../script_priorityqueue.hpp"
+#include "../template/template_priorityqueue.hpp.sq"
+
+
+template <> const char *GetClassName() { return "AIPriorityQueue"; }
+
+void SQAIPriorityQueue_Register(Squirrel *engine)
+{
+ DefSQClass SQAIPriorityQueue("AIPriorityQueue");
+ SQAIPriorityQueue.PreRegister(engine);
+ SQAIPriorityQueue.AddConstructor(engine, "x");
+
+ SQAIPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Insert, "Insert");
+ SQAIPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Pop, "Pop");
+ SQAIPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Peek, "Peek");
+ SQAIPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Exists, "Exists");
+ SQAIPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Clear, "Clear");
+ SQAIPriorityQueue.DefSQMethod(engine, &ScriptPriorityQueue::IsEmpty, "IsEmpty", 1, "x");
+ SQAIPriorityQueue.DefSQMethod(engine, &ScriptPriorityQueue::Count, "Count", 1, "x");
+
+ SQAIPriorityQueue.PostRegister(engine);
+}
diff --git a/src/script/api/ai_changelog.hpp b/src/script/api/ai_changelog.hpp
index bcb7df67f2..a579bb27bc 100644
--- a/src/script/api/ai_changelog.hpp
+++ b/src/script/api/ai_changelog.hpp
@@ -17,6 +17,9 @@
*
* This version is not yet released. The following changes are not set in stone yet.
*
+ * API additions:
+ * \li AIPriorityQueue
+ *
* \b 1.10.0
*
* API additions:
diff --git a/src/script/api/game/game_priorityqueue.hpp.sq b/src/script/api/game/game_priorityqueue.hpp.sq
new file mode 100644
index 0000000000..fade5e2a1e
--- /dev/null
+++ b/src/script/api/game/game_priorityqueue.hpp.sq
@@ -0,0 +1,31 @@
+/*
+ * 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 .
+ */
+
+/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
+
+#include "../script_priorityqueue.hpp"
+#include "../template/template_priorityqueue.hpp.sq"
+
+
+template <> const char *GetClassName() { return "GSPriorityQueue"; }
+
+void SQGSPriorityQueue_Register(Squirrel *engine)
+{
+ DefSQClass SQGSPriorityQueue("GSPriorityQueue");
+ SQGSPriorityQueue.PreRegister(engine);
+ SQGSPriorityQueue.AddConstructor(engine, "x");
+
+ SQGSPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Insert, "Insert");
+ SQGSPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Pop, "Pop");
+ SQGSPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Peek, "Peek");
+ SQGSPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Exists, "Exists");
+ SQGSPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Clear, "Clear");
+ SQGSPriorityQueue.DefSQMethod(engine, &ScriptPriorityQueue::IsEmpty, "IsEmpty", 1, "x");
+ SQGSPriorityQueue.DefSQMethod(engine, &ScriptPriorityQueue::Count, "Count", 1, "x");
+
+ SQGSPriorityQueue.PostRegister(engine);
+}
diff --git a/src/script/api/game_changelog.hpp b/src/script/api/game_changelog.hpp
index 69c4d971a5..fc917a0120 100644
--- a/src/script/api/game_changelog.hpp
+++ b/src/script/api/game_changelog.hpp
@@ -24,6 +24,7 @@
* \li GSStoryPage::MakePushButtonReference
* \li GSStoryPage::MakeTileButtonReference
* \li GSStoryPage::MakeVehicleButtonReference
+ * \li GSPriorityQueue
*
* \b 1.10.0
*
diff --git a/src/script/api/script_priorityqueue.cpp b/src/script/api/script_priorityqueue.cpp
new file mode 100644
index 0000000000..3130084126
--- /dev/null
+++ b/src/script/api/script_priorityqueue.cpp
@@ -0,0 +1,107 @@
+/*
+ * 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_priorityqueue.cpp Implementation of ScriptPriorityQueue. */
+
+#include "../../stdafx.h"
+#include "script_priorityqueue.hpp"
+#include "script_error.hpp"
+#include "../squirrel_helper.hpp"
+#include "../script_instance.hpp"
+#include "../../debug.h"
+#include
+
+#include "../../safeguards.h"
+
+
+static bool operator==(const ScriptPriorityQueue::PriorityItem &lhs, const HSQOBJECT &rhs)
+{
+ return lhs.second._type == rhs._type && lhs.second._unVal.raw == rhs._unVal.raw;
+}
+
+
+ScriptPriorityQueue::~ScriptPriorityQueue()
+{
+ /* Release reference to stored objects. */
+ auto inst = ScriptObject::GetActiveInstance();
+ if (!inst->InShutdown()) {
+ for (auto &i : this->queue) inst->ReleaseSQObject(const_cast(&i.second));
+ }
+}
+
+SQInteger ScriptPriorityQueue::Insert(HSQUIRRELVM vm)
+{
+ HSQOBJECT item;
+ int64 priority;
+ sq_resetobject(&item);
+ sq_getstackobj(vm, 2, &item);
+ sq_getinteger(vm, 3, &priority);
+
+ sq_addref(vm, &item); // Keep object alive.
+
+ this->queue.emplace_back(priority, item);
+ std::push_heap(this->queue.begin(), this->queue.end(), this->comp);
+
+ return SQConvert::Return(vm, true);
+}
+
+SQInteger ScriptPriorityQueue::Pop(HSQUIRRELVM vm)
+{
+ if (this->IsEmpty()) {
+ ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_FAILED);
+ sq_pushnull(vm);
+ return 1;
+ }
+
+ HSQOBJECT item = this->queue.front().second;
+ std::pop_heap(this->queue.begin(), this->queue.end(), this->comp);
+ this->queue.pop_back();
+
+ /* Store the object on the Squirrel stack before releasing it to make sure the ref count can't drop to zero. */
+ auto ret = SQConvert::Return(vm, item);
+ sq_release(vm, &item);
+ return ret;
+}
+
+SQInteger ScriptPriorityQueue::Peek(HSQUIRRELVM vm)
+{
+ if (this->IsEmpty()) {
+ ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_FAILED);
+ sq_pushnull(vm);
+ return 1;
+ }
+
+ return SQConvert::Return(vm, this->queue.front().second);
+}
+
+SQInteger ScriptPriorityQueue::Exists(HSQUIRRELVM vm)
+{
+ HSQOBJECT item;
+ sq_resetobject(&item);
+ sq_getstackobj(vm, 2, &item);
+
+ return SQConvert::Return(vm, std::find(this->queue.cbegin(), this->queue.cend(), item) != this->queue.cend());
+}
+
+SQInteger ScriptPriorityQueue::Clear(HSQUIRRELVM vm)
+{
+ /* Release reference to stored objects. */
+ for (auto &i : this->queue) sq_release(vm, const_cast(&i.second));
+ this->queue.clear();
+
+ return 0;
+}
+
+bool ScriptPriorityQueue::IsEmpty()
+{
+ return this->queue.empty();
+}
+
+SQInteger ScriptPriorityQueue::Count()
+{
+ return (SQInteger)this->queue.size();
+}
diff --git a/src/script/api/script_priorityqueue.hpp b/src/script/api/script_priorityqueue.hpp
new file mode 100644
index 0000000000..5f8718e424
--- /dev/null
+++ b/src/script/api/script_priorityqueue.hpp
@@ -0,0 +1,94 @@
+/*
+ * 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_priorityqueue.hpp A queue that keeps a list of items sorted by a priority. */
+/** @defgroup ScriptPriorityQueue Classes that create a priority queue of items. */
+
+#ifndef SCRIPT_PRIORITYQUEUE_HPP
+#define SCRIPT_PRIORITYQUEUE_HPP
+
+#include "script_object.hpp"
+#include
+#include
+
+/**
+ * Class that creates a queue which keeps its items ordered by an item priority.
+ * @api ai game
+ */
+class ScriptPriorityQueue : public ScriptObject {
+public:
+ typedef std::pair PriorityItem;
+private:
+ struct PriorityComparator {
+ bool operator()(const PriorityItem &lhs, const PriorityItem &rhs) const noexcept
+ {
+ return lhs.first > rhs.first;
+ }
+ };
+
+ PriorityComparator comp;
+ std::vector queue; ///< The priority list
+
+public:
+ ~ScriptPriorityQueue();
+
+#ifdef DOXYGEN_API
+ /**
+ * Add a single item to the queue.
+ * @param item The item to add. Can be any Squirrel type. Should be unique, otherwise it is ignored.
+ * @param priority The priority to assign the item.
+ * @return True if the item was inserted, false if it was already in the queue.
+ */
+ bool Insert(void *item, int64 priority);
+
+ /**
+ * Remove and return the item with the lowest priority.
+ * @return The item with the lowest priority, removed from the queue. Returns null on an empty queue.
+ * @pre !IsEmpty()
+ */
+ void *Pop();
+
+ /**
+ * Get the item with the lowest priority, keeping it in the queue.
+ * @return The item with the lowest priority. Returns null on an empty queue.
+ * @pre !IsEmpty()
+ */
+ void *Peek();
+
+ /**
+ * Check if an items is already included in the queue.
+ * @return true if the items is already in the queue.
+ * @note Performance is O(n), use only when absolutely required.
+ */
+ bool Exists(void *item);
+
+ /**
+ * Clear the queue, making Count() returning 0 and IsEmpty() returning true.
+ */
+ void Clear();
+#else
+ SQInteger Insert(HSQUIRRELVM vm);
+ SQInteger Pop(HSQUIRRELVM vm);
+ SQInteger Peek(HSQUIRRELVM vm);
+ SQInteger Exists(HSQUIRRELVM vm);
+ SQInteger Clear(HSQUIRRELVM vm);
+#endif
+
+ /**
+ * Check if the queue is empty.
+ * @return true if the queue is empty.
+ */
+ bool IsEmpty();
+
+ /**
+ * Returns the amount of items in the queue.
+ * @return amount of items in the queue.
+ */
+ SQInteger Count();
+};
+
+#endif /* SCRIPT_PRIORITYQUEUE_HPP */
diff --git a/src/script/api/script_story_page.cpp b/src/script/api/script_story_page.cpp
index 39ae3d53ff..8fda69e6f5 100644
--- a/src/script/api/script_story_page.cpp
+++ b/src/script/api/script_story_page.cpp
@@ -83,6 +83,10 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
case SPET_BUTTON_VEHICLE:
refid = reference;
break;
+ case SPET_TEXT:
+ break;
+ default:
+ NOT_REACHED();
}
if (!ScriptObject::DoCommand(reftile,
@@ -124,6 +128,10 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
case SPET_BUTTON_VEHICLE:
refid = reference;
break;
+ case SPET_TEXT:
+ break;
+ default:
+ NOT_REACHED();
}
return ScriptObject::DoCommand(reftile,
diff --git a/src/script/api/template/template_priorityqueue.hpp.sq b/src/script/api/template/template_priorityqueue.hpp.sq
new file mode 100644
index 0000000000..14c63324fb
--- /dev/null
+++ b/src/script/api/template/template_priorityqueue.hpp.sq
@@ -0,0 +1,19 @@
+/*
+ * 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 .
+ */
+
+/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
+
+#include "../script_priorityqueue.hpp"
+
+namespace SQConvert {
+ /* Allow ScriptPriorityQueue to be used as Squirrel parameter */
+ template <> inline ScriptPriorityQueue *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptPriorityQueue *)instance; }
+ template <> inline ScriptPriorityQueue &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptPriorityQueue *)instance; }
+ template <> inline const ScriptPriorityQueue *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptPriorityQueue *)instance; }
+ template <> inline const ScriptPriorityQueue &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptPriorityQueue *)instance; }
+ template <> inline int Return(HSQUIRRELVM vm, ScriptPriorityQueue *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "PriorityQueue", res, nullptr, DefSQDestructorCallback, true); return 1; }
+} // namespace SQConvert
diff --git a/src/script/script_instance.cpp b/src/script/script_instance.cpp
index a38a315ffc..81283cb772 100644
--- a/src/script/script_instance.cpp
+++ b/src/script/script_instance.cpp
@@ -58,6 +58,7 @@ ScriptInstance::ScriptInstance(const char *APIName) :
is_save_data_on_stack(false),
suspend(0),
is_paused(false),
+ in_shutdown(false),
callback(nullptr)
{
this->storage = new ScriptStorage();
@@ -136,6 +137,7 @@ bool ScriptInstance::LoadCompatibilityScripts(const char *api_version, Subdirect
ScriptInstance::~ScriptInstance()
{
ScriptObject::ActiveInstance active(this);
+ this->in_shutdown = true;
if (instance != nullptr) this->engine->ReleaseObject(this->instance);
if (engine != nullptr) delete this->engine;
@@ -154,6 +156,7 @@ void ScriptInstance::Died()
{
DEBUG(script, 0, "The script died unexpectedly.");
this->is_dead = true;
+ this->in_shutdown = true;
this->last_allocated_memory = this->GetAllocatedMemory(); // Update cache
@@ -718,3 +721,8 @@ size_t ScriptInstance::GetAllocatedMemory() const
if (this->engine == nullptr) return this->last_allocated_memory;
return this->engine->GetAllocatedMemory();
}
+
+void ScriptInstance::ReleaseSQObject(HSQOBJECT *obj)
+{
+ if (!this->in_shutdown) this->engine->ReleaseObject(obj);
+}
diff --git a/src/script/script_instance.hpp b/src/script/script_instance.hpp
index e5024c80bc..c097e0eb7b 100644
--- a/src/script/script_instance.hpp
+++ b/src/script/script_instance.hpp
@@ -200,6 +200,17 @@ public:
size_t GetAllocatedMemory() const;
+ /**
+ * Indicate whether this instance is currently being destroyed.
+ */
+ inline bool InShutdown() const { return this->in_shutdown; }
+
+ /**
+ * Decrease the ref count of a squirrel object.
+ * @param obj The object to release.
+ **/
+ void ReleaseSQObject(HSQOBJECT *obj);
+
protected:
class Squirrel *engine; ///< A wrapper around the squirrel vm.
const char *versionAPI; ///< Current API used by this script.
@@ -242,6 +253,7 @@ private:
bool is_save_data_on_stack; ///< Is the save data still on the squirrel stack?
int suspend; ///< The amount of ticks to suspend this script before it's allowed to continue.
bool is_paused; ///< Is the script paused? (a paused script will not be executed until unpaused)
+ bool in_shutdown; ///< Is this instance currently being destructed?
Script_SuspendCallbackProc *callback; ///< Callback that should be called in the next tick the script runs.
size_t last_allocated_memory; ///< Last known allocated memory value (for display for crashed scripts)
diff --git a/src/story_gui.cpp b/src/story_gui.cpp
index 96c411fe9c..2de96a1a52 100644
--- a/src/story_gui.cpp
+++ b/src/story_gui.cpp
@@ -459,7 +459,7 @@ protected:
}
}
/* Position element in main column */
- LayoutCacheElement ce{ pe };
+ LayoutCacheElement ce{ pe, {} };
ce.bounds.left = left_offset;
ce.bounds.right = max_width - right_offset;
ce.bounds.top = main_y;
@@ -479,7 +479,7 @@ protected:
std::vector &cur_floats = (fl == ElementFloat::Left) ? left_floats : right_floats;
/* Position element */
cur_width = max(cur_width, this->GetPageElementFloatWidth(*pe));
- LayoutCacheElement ce{ pe };
+ LayoutCacheElement ce{ pe, {} };
ce.bounds.left = (fl == ElementFloat::Left) ? 0 : (max_width - cur_width);
ce.bounds.right = (fl == ElementFloat::Left) ? cur_width : max_width;
ce.bounds.top = cur_y;
@@ -745,11 +745,7 @@ public:
case SPET_BUTTON_PUSH:
case SPET_BUTTON_TILE:
case SPET_BUTTON_VEHICLE: {
- const int height = FONT_HEIGHT_NORMAL;
const int tmargin = WD_BEVEL_TOP + WD_FRAMETEXT_TOP;
- const int bmargin = WD_BEVEL_BOTTOM + WD_FRAMETEXT_BOTTOM;
- const int width = ce.bounds.right - ce.bounds.left;
- const int hmargin = width / 5;
const FrameFlags frame = this->active_button_id == ce.pe->index ? FR_LOWERED : FR_NONE;
const Colours bgcolour = StoryPageButtonData{ ce.pe->referenced_id }.GetColour();
diff --git a/src/video/cocoa/wnd_quartz.mm b/src/video/cocoa/wnd_quartz.mm
index 5183b51f2f..fbb8db77cf 100644
--- a/src/video/cocoa/wnd_quartz.mm
+++ b/src/video/cocoa/wnd_quartz.mm
@@ -318,6 +318,8 @@ bool WindowQuartzSubdriver::SetVideoMode(int width, int height, int bpp)
[this->window setColorSpace:[NSColorSpace sRGBColorSpace]];
this->color_space = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
+ if (this->color_space == nullptr) this->color_space = CGColorSpaceCreateDeviceRGB();
+ if (this->color_space == nullptr) error("Could not get a valid colour space for drawing.");
bool ret = WindowResized();
this->UpdatePalette(0, 256);