diff --git a/Memory.xml b/Memory.xml
index 6b9570cb6..5360d6481 100644
--- a/Memory.xml
+++ b/Memory.xml
@@ -1088,6 +1088,11 @@
+
+
+
+
+
@@ -2332,6 +2337,12 @@
+
+
+
+
+
+
cmake
@@ -3210,6 +3221,12 @@
+
+
+
+
+
+
diff --git a/library/Core.cpp b/library/Core.cpp
index 95a05ee6b..4a3dacd25 100644
--- a/library/Core.cpp
+++ b/library/Core.cpp
@@ -928,7 +928,7 @@ bool Core::SelectHotkey(int sym, int modifiers)
if (modifiers & 1)
idx += 8;
- if (!strict_virtual_cast(screen) ||
+ if (strict_virtual_cast(screen) &&
df::global::ui->main.mode != ui_sidebar_mode::Hotkeys)
{
cmd = df::global::ui->main.hotkeys[idx].name;
diff --git a/library/DataDefs.cpp b/library/DataDefs.cpp
index 772b3393d..bcdb388b5 100644
--- a/library/DataDefs.cpp
+++ b/library/DataDefs.cpp
@@ -160,17 +160,21 @@ void virtual_identity::Init(Core *core)
}
}
-#define GLOBAL(name,tname) \
- df::tname *df::global::name = NULL;
+#define SIMPLE_GLOBAL(name,tname) \
+ tname *df::global::name = NULL;
+#define GLOBAL(name,tname) SIMPLE_GLOBAL(name,df::tname)
DF_KNOWN_GLOBALS
#undef GLOBAL
+#undef SIMPLE_GLOBAL
void DFHack::InitDataDefGlobals(Core *core) {
OffsetGroup *global_table = core->vinfo->getGroup("global");
uint32_t tmp;
-#define GLOBAL(name,tname) \
- if (global_table->getSafeAddress(#name,tmp)) df::global::name = (df::tname*)tmp;
+#define SIMPLE_GLOBAL(name,tname) \
+ if (global_table->getSafeAddress(#name,tmp)) df::global::name = (tname*)tmp;
+#define GLOBAL(name,tname) SIMPLE_GLOBAL(name,df::tname)
DF_KNOWN_GLOBALS
#undef GLOBAL
+#undef SIMPLE_GLOBAL
}
diff --git a/library/include/DataDefs.h b/library/include/DataDefs.h
index f6781526c..75b2ab2e5 100644
--- a/library/include/DataDefs.h
+++ b/library/include/DataDefs.h
@@ -175,11 +175,18 @@ namespace df {
GLOBAL(ui,ui) \
GLOBAL(gview,interface) \
GLOBAL(init,init) \
- GLOBAL(d_init,d_init)
-
-#define GLOBAL(name,tname) \
- struct tname; \
+ GLOBAL(d_init,d_init) \
+ SIMPLE_GLOBAL(ui_look_cursor,int) \
+ SIMPLE_GLOBAL(ui_workshop_job_cursor,int) \
+ GLOBAL(ui_sidebar_menus,ui_sidebar_menus) \
+ GLOBAL(ui_build_selector,ui_build_selector) \
+ GLOBAL(ui_look_list,ui_look_list)
+
+#define SIMPLE_GLOBAL(name,tname) \
namespace global { extern DFHACK_EXPORT tname *name; }
+#define GLOBAL(name,tname) \
+ struct tname; SIMPLE_GLOBAL(name,tname)
DF_KNOWN_GLOBALS
#undef GLOBAL
+#undef SIMPLE_GLOBAL
}
diff --git a/library/xml b/library/xml
index c40a36fb7..7a730830c 160000
--- a/library/xml
+++ b/library/xml
@@ -1 +1 @@
-Subproject commit c40a36fb73cfba11fe4adaa551bdb401a3c75ad0
+Subproject commit 7a730830c515fea701ff73b33cb604f48a4531fc
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index 783c6507c..133905727 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -60,6 +60,7 @@ DFHACK_PLUGIN(seedwatch seedwatch.cpp)
DFHACK_PLUGIN(initflags initflags.cpp)
DFHACK_PLUGIN(stockpiles stockpiles.cpp)
DFHACK_PLUGIN(rename rename.cpp)
+DFHACK_PLUGIN(fixwagons fixwagons.cpp)
#DFHACK_PLUGIN(versionosd versionosd.cpp)
# this is the skeleton plugin. If you want to make your own, make a copy and then change it
diff --git a/plugins/fixwagons.cpp b/plugins/fixwagons.cpp
new file mode 100644
index 000000000..29253880e
--- /dev/null
+++ b/plugins/fixwagons.cpp
@@ -0,0 +1,110 @@
+// I'll fix his little red wagon...
+
+#include "Core.h"
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+using std::string;
+using std::vector;
+using namespace DFHack;
+
+using df::global::world;
+using df::historical_entity;
+using df::entity_raw_flags;
+using df::creature_raw;
+using df::creature_raw_flags;
+
+command_result df_fixwagons (Core *c, vector ¶meters)
+{
+ if (!parameters.empty())
+ return CR_WRONG_USAGE;
+
+ CoreSuspender suspend(c);
+ int32_t wagon_creature = -1, wagon_puller_creature = -1;
+ creature_raw *wagon, *wagon_puller;
+ for (int i = 0; i < world->raws.creatures.all.size(); i++)
+ {
+ creature_raw *cr = world->raws.creatures.all[i];
+ if (cr->flags.is_set(creature_raw_flags::EQUIPMENT_WAGON) && (wagon_creature == -1))
+ {
+ wagon = cr;
+ wagon_creature = i;
+ }
+ if ((cr->creature_id == "HORSE") && (wagon_puller_creature == -1))
+ {
+ wagon_puller = cr;
+ wagon_puller_creature = i;
+ }
+ }
+ if (wagon_creature == -1)
+ {
+ c->con.printerr("Couldn't find a valid wagon creature!\n");
+ return CR_FAILURE;
+ }
+ if (wagon_puller_creature == -1)
+ {
+ c->con.printerr("Couldn't find 'HORSE' creature for default wagon puller!\n");
+ return CR_FAILURE;
+ }
+ int count = 0;
+ for (int i = 0; i < world->entities.all.size(); i++)
+ {
+ bool updated = false;
+ historical_entity *ent = world->entities.all[i];
+ if (!ent->entity_raw->flags.is_set(entity_raw_flags::COMMON_DOMESTIC_PULL))
+ continue;
+ if (ent->resources.animals.wagon_races.size() == 0)
+ {
+ updated = true;
+ for (int j = 0; j < wagon->caste.size(); j++)
+ {
+ ent->resources.animals.wagon_races.push_back(wagon_creature);
+ ent->resources.animals.wagon_castes.push_back(j);
+ }
+ }
+ if (ent->resources.animals.wagon_puller_races.size() == 0)
+ {
+ updated = true;
+ for (int j = 0; j < wagon_puller->caste.size(); j++)
+ {
+ ent->resources.animals.wagon_puller_races.push_back(wagon_puller_creature);
+ ent->resources.animals.wagon_puller_castes.push_back(j);
+ }
+ }
+ if (updated)
+ count++;
+ }
+ if(count)
+ c->con.print("Fixed %d civilizations to bring wagons once again.\n", count);
+ return CR_OK;
+}
+
+DFhackCExport const char * plugin_name ( void )
+{
+ return "fixwagons";
+}
+
+DFhackCExport command_result plugin_init ( Core * c, std::vector &commands)
+{
+ commands.clear();
+ commands.push_back(PluginCommand(
+ "fixwagons", "Fix all civilizations to be able to bring wagons.",
+ df_fixwagons, false,
+ " Since DF v0.31.1 merchants no longer bring wagons due to a bug.\n"
+ " This command re-enables them for all appropriate civilizations.\n"
+ ));
+ return CR_OK;
+}
+
+DFhackCExport command_result plugin_shutdown ( Core * c )
+{
+ return CR_OK;
+}