From d3c496cc2bf7d96475cb46871eae7233c153918c Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 5 May 2017 14:45:46 -0400 Subject: [PATCH] Add getSelectedPlant() and related functions Currently only works with the center tile of multi-tile trees --- docs/Lua API.rst | 4 +++ library/LuaApi.cpp | 1 + library/include/modules/Gui.h | 6 +++++ library/include/modules/Screen.h | 11 +++++--- library/lua/utils.lua | 2 ++ library/modules/Gui.cpp | 45 ++++++++++++++++++++++++++++++++ library/modules/Screen.cpp | 9 +++++++ 7 files changed, 74 insertions(+), 4 deletions(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 2db98abad..1c08407ae 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -921,6 +921,10 @@ Gui module Returns the building selected via :kbd:`q`, :kbd:`t`, :kbd:`k` or :kbd:`i`. +* ``dfhack.gui.getSelectedPlant([silent])`` + + Returns the plant selected via :kbd:`k`. + * ``dfhack.gui.writeToGamelog(text)`` Writes a string to :file:`gamelog.txt` without doing an announcement. diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index fd4ce1c02..2a4fb64d3 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1453,6 +1453,7 @@ static const LuaWrapper::FunctionReg dfhack_gui_module[] = { WRAPM(Gui, getSelectedUnit), WRAPM(Gui, getSelectedItem), WRAPM(Gui, getSelectedBuilding), + WRAPM(Gui, getSelectedPlant), WRAPM(Gui, writeToGamelog), WRAPM(Gui, makeAnnouncement), WRAPM(Gui, addCombatReport), diff --git a/library/include/modules/Gui.h b/library/include/modules/Gui.h index ae53e7603..7ea4d0e48 100644 --- a/library/include/modules/Gui.h +++ b/library/include/modules/Gui.h @@ -45,6 +45,7 @@ namespace df { struct job; struct unit; struct item; + struct plant; }; /** @@ -104,6 +105,11 @@ namespace DFHack DFHACK_EXPORT df::building *getAnyBuilding(df::viewscreen *top); DFHACK_EXPORT df::building *getSelectedBuilding(color_ostream &out, bool quiet = false); + // A plant is selected, e.g. via 'k' + DFHACK_EXPORT bool any_plant_hotkey(df::viewscreen *top); + DFHACK_EXPORT df::plant *getAnyPlant(df::viewscreen *top); + DFHACK_EXPORT df::plant *getSelectedPlant(color_ostream &out, bool quiet = false); + // Low-level API that gives full control over announcements and reports DFHACK_EXPORT void writeToGamelog(std::string message); diff --git a/library/include/modules/Screen.h b/library/include/modules/Screen.h index 2c4a29062..4e53b0b54 100644 --- a/library/include/modules/Screen.h +++ b/library/include/modules/Screen.h @@ -44,6 +44,7 @@ namespace df struct item; struct unit; struct building; + struct plant; } /** @@ -326,10 +327,11 @@ namespace DFHack virtual std::string getFocusString() = 0; virtual void onShow() {}; virtual void onDismiss() {}; - virtual df::unit *getSelectedUnit() { return NULL; } - virtual df::item *getSelectedItem() { return NULL; } - virtual df::job *getSelectedJob() { return NULL; } - virtual df::building *getSelectedBuilding() { return NULL; } + virtual df::unit *getSelectedUnit() { return nullptr; } + virtual df::item *getSelectedItem() { return nullptr; } + virtual df::job *getSelectedJob() { return nullptr; } + virtual df::building *getSelectedBuilding() { return nullptr; } + virtual df::plant *getSelectedPlant() { return nullptr; } }; class DFHACK_EXPORT dfhack_lua_viewscreen : public dfhack_viewscreen { @@ -369,5 +371,6 @@ namespace DFHack virtual df::item *getSelectedItem(); virtual df::job *getSelectedJob(); virtual df::building *getSelectedBuilding(); + virtual df::plant *getSelectedPlant(); }; } diff --git a/library/lua/utils.lua b/library/lua/utils.lua index 4800042f0..07db41808 100644 --- a/library/lua/utils.lua +++ b/library/lua/utils.lua @@ -635,6 +635,8 @@ function df_shortcut_var(k) return dfhack.gui.getSelectedWorkshopJob() elseif k == 'unit' then return dfhack.gui.getSelectedUnit() + elseif k == 'plant' then + return dfhack.gui.getSelectedPlant() else for g in pairs(df.global) do if g == k then diff --git a/library/modules/Gui.cpp b/library/modules/Gui.cpp index 9a86e69ec..5ad569c5a 100644 --- a/library/modules/Gui.cpp +++ b/library/modules/Gui.cpp @@ -92,6 +92,7 @@ using namespace DFHack; #include "df/game_mode.h" #include "df/unit.h" #include "df/occupation.h" +#include "df/plant.h" using namespace df::enums; using df::global::gview; @@ -1120,6 +1121,50 @@ df::building *Gui::getSelectedBuilding(color_ostream &out, bool quiet) return building; } +df::plant *Gui::getAnyPlant(df::viewscreen *top) +{ + using df::global::cursor; + using df::global::ui; + using df::global::world; + + if (auto dfscreen = dfhack_viewscreen::try_cast(top)) + return dfscreen->getSelectedPlant(); + + if (Gui::dwarfmode_hotkey(top)) + { + if (!cursor || !ui || !world) + return nullptr; + + if (ui->main.mode == ui_sidebar_mode::LookAround) + { + for (df::plant *plant : world->plants.all) + { + if (plant->pos.x == cursor->x && plant->pos.y == cursor->y && plant->pos.z == cursor->z) + { + return plant; + } + } + } + } + + return nullptr; +} + +bool Gui::any_plant_hotkey(df::viewscreen *top) +{ + return getAnyPlant(top) != nullptr; +} + +df::plant *Gui::getSelectedPlant(color_ostream &out, bool quiet) +{ + df::plant *plant = getAnyPlant(Core::getTopViewscreen()); + + if (!plant && !quiet) + out.printerr("No plant is selected in the UI.\n"); + + return plant; +} + // DFHACK_EXPORT void Gui::writeToGamelog(std::string message) diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index 71103ffda..0b9a500fa 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -57,6 +57,7 @@ using namespace DFHack; #include "df/job.h" #include "df/building.h" #include "df/renderer.h" +#include "df/plant.h" using namespace df::enums; using df::global::init; @@ -934,3 +935,11 @@ df::building *dfhack_lua_viewscreen::getSelectedBuilding() safe_call_lua(do_notify, 1, 1); return Lua::GetDFObject(Lua::Core::State, -1); } + +df::plant *dfhack_lua_viewscreen::getSelectedPlant() +{ + Lua::StackUnwinder frame(Lua::Core::State); + lua_pushstring(Lua::Core::State, "onGetSelectedPlant"); + safe_call_lua(do_notify, 1, 1); + return Lua::GetDFObject(Lua::Core::State, -1); +}