|
|
@ -57,6 +57,7 @@ using namespace DFHack;
|
|
|
|
#include "df/building_trapst.h"
|
|
|
|
#include "df/building_trapst.h"
|
|
|
|
#include "df/building_type.h"
|
|
|
|
#include "df/building_type.h"
|
|
|
|
#include "df/building_workshopst.h"
|
|
|
|
#include "df/building_workshopst.h"
|
|
|
|
|
|
|
|
#include "df/cri_unitst.h"
|
|
|
|
#include "df/d_init.h"
|
|
|
|
#include "df/d_init.h"
|
|
|
|
#include "df/game_mode.h"
|
|
|
|
#include "df/game_mode.h"
|
|
|
|
#include "df/general_ref.h"
|
|
|
|
#include "df/general_ref.h"
|
|
|
@ -459,7 +460,7 @@ DEFINE_GET_FOCUS_STRING_HANDLER(dwarfmode)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!newFocusString.size()) {
|
|
|
|
if (!newFocusString.size()) {
|
|
|
|
focusStrings.push_back(baseFocus);
|
|
|
|
focusStrings.push_back(baseFocus + "/Default");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -475,12 +476,14 @@ DEFINE_GET_FOCUS_STRING_HANDLER(dungeonmode)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
bool Gui::matchFocusString(std::string focusString, bool prefixMatch) {
|
|
|
|
bool Gui::matchFocusString(std::string focus_string, df::viewscreen *top) {
|
|
|
|
focusString = toLower(focusString);
|
|
|
|
focus_string = toLower(focus_string);
|
|
|
|
std::vector<std::string> currentFocusStrings = getFocusStrings(getCurViewscreen(true));
|
|
|
|
if (!top)
|
|
|
|
|
|
|
|
top = getCurViewscreen(true);
|
|
|
|
|
|
|
|
std::vector<std::string> currentFocusStrings = getFocusStrings(top);
|
|
|
|
|
|
|
|
|
|
|
|
return std::find_if(currentFocusStrings.begin(), currentFocusStrings.end(), [&focusString, &prefixMatch](std::string item) {
|
|
|
|
return std::find_if(currentFocusStrings.begin(), currentFocusStrings.end(), [&focus_string](std::string item) {
|
|
|
|
return prefixMatch ? prefix_matches(focusString, toLower(item)) : focusString == toLower(item);
|
|
|
|
return prefix_matches(focus_string, toLower(item));
|
|
|
|
}) != currentFocusStrings.end();
|
|
|
|
}) != currentFocusStrings.end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -535,17 +538,7 @@ std::vector<std::string> Gui::getFocusStrings(df::viewscreen* top)
|
|
|
|
|
|
|
|
|
|
|
|
bool Gui::default_hotkey(df::viewscreen *top)
|
|
|
|
bool Gui::default_hotkey(df::viewscreen *top)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Default hotkey guard function
|
|
|
|
return World::isFortressMode() || World::isAdventureMode();
|
|
|
|
for (;top ;top = top->parent)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (strict_virtual_cast<df::viewscreen_dwarfmodest>(top))
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
/* TODO: understand how this changes for v50
|
|
|
|
|
|
|
|
if (strict_virtual_cast<df::viewscreen_dungeonmodest>(top))
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Gui::anywhere_hotkey(df::viewscreen *) {
|
|
|
|
bool Gui::anywhere_hotkey(df::viewscreen *) {
|
|
|
@ -553,24 +546,7 @@ bool Gui::anywhere_hotkey(df::viewscreen *) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Gui::dwarfmode_hotkey(df::viewscreen *top) {
|
|
|
|
bool Gui::dwarfmode_hotkey(df::viewscreen *top) {
|
|
|
|
return World::isFortressMode();
|
|
|
|
return matchFocusString("dwarfmode", top);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Gui::unitjobs_hotkey(df::viewscreen *top)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* TODO: understand how this changes for v50
|
|
|
|
|
|
|
|
// Require the unit or jobs list
|
|
|
|
|
|
|
|
return !!strict_virtual_cast<df::viewscreen_joblistst>(top) ||
|
|
|
|
|
|
|
|
!!strict_virtual_cast<df::viewscreen_unitlistst>(top);
|
|
|
|
|
|
|
|
*/ return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Gui::item_details_hotkey(df::viewscreen *top)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* TODO: understand how this changes for v50
|
|
|
|
|
|
|
|
// Require the main dwarf mode screen
|
|
|
|
|
|
|
|
return !!strict_virtual_cast<df::viewscreen_itemst>(top);
|
|
|
|
|
|
|
|
*/ return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool has_cursor()
|
|
|
|
static bool has_cursor()
|
|
|
@ -595,164 +571,82 @@ bool Gui::workshop_job_hotkey(df::viewscreen *top)
|
|
|
|
if (!dwarfmode_hotkey(top))
|
|
|
|
if (!dwarfmode_hotkey(top))
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
/* TODO: understand how this changes for v50
|
|
|
|
df::building *selected = getAnyBuilding(top);
|
|
|
|
using namespace ui_sidebar_mode;
|
|
|
|
|
|
|
|
using df::global::ui_workshop_in_add;
|
|
|
|
|
|
|
|
using df::global::ui_workshop_job_cursor;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (plotinfo->main.mode) {
|
|
|
|
|
|
|
|
case QueryBuilding:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!ui_workshop_job_cursor) // allow missing
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
df::building *selected = world->selected_building;
|
|
|
|
|
|
|
|
if (!virtual_cast<df::building_workshopst>(selected) &&
|
|
|
|
if (!virtual_cast<df::building_workshopst>(selected) &&
|
|
|
|
!virtual_cast<df::building_furnacest>(selected))
|
|
|
|
!virtual_cast<df::building_furnacest>(selected))
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
// No jobs?
|
|
|
|
|
|
|
|
if (selected->jobs.empty() ||
|
|
|
|
if (selected->jobs.empty() ||
|
|
|
|
selected->jobs[0]->job_type == job_type::DestroyBuilding)
|
|
|
|
selected->jobs[0]->job_type == job_type::DestroyBuilding)
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
// Add job gui activated?
|
|
|
|
|
|
|
|
if (ui_workshop_in_add && *ui_workshop_in_add)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
*/ return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Gui::build_selector_hotkey(df::viewscreen *top)
|
|
|
|
bool Gui::build_selector_hotkey(df::viewscreen *top)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!dwarfmode_hotkey(top))
|
|
|
|
using df::global::buildreq;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* TODO: understand how this changes for v50
|
|
|
|
if (!dwarfmode_hotkey(top))
|
|
|
|
using namespace ui_sidebar_mode;
|
|
|
|
|
|
|
|
using df::global::ui_build_selector;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (plotinfo->main.mode) {
|
|
|
|
|
|
|
|
case Build:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!ui_build_selector) // allow missing
|
|
|
|
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
// Not selecting, or no choices?
|
|
|
|
if (buildreq->building_type < 0 ||
|
|
|
|
if (ui_build_selector->building_type < 0 ||
|
|
|
|
buildreq->stage != 2 ||
|
|
|
|
ui_build_selector->stage != 2 ||
|
|
|
|
buildreq->choices.empty())
|
|
|
|
ui_build_selector->choices.empty())
|
|
|
|
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
*/ return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Gui::view_unit_hotkey(df::viewscreen *top)
|
|
|
|
bool Gui::view_unit_hotkey(df::viewscreen *top)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!dwarfmode_hotkey(top))
|
|
|
|
if (!dwarfmode_hotkey(top))
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
/* TODO: understand how this changes for v50
|
|
|
|
|
|
|
|
using df::global::ui_selected_unit;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (plotinfo->main.mode != ui_sidebar_mode::ViewUnits)
|
|
|
|
return !!getAnyUnit(top);
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!ui_selected_unit) // allow missing
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return vector_get(world->units.active, *ui_selected_unit) != NULL;
|
|
|
|
|
|
|
|
*/ return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Gui::unit_inventory_hotkey(df::viewscreen *top)
|
|
|
|
bool Gui::any_job_hotkey(df::viewscreen *top)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
using df::global::ui_unit_view_mode;
|
|
|
|
return matchFocusString("dwarfmode/Info/JOBS", top)
|
|
|
|
|
|
|
|
|| matchFocusString("dwarfmode/Info/CREATURES/CITIZEN", top)
|
|
|
|
if (!view_unit_hotkey(top))
|
|
|
|
|| workshop_job_hotkey(top);
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!ui_unit_view_mode)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ui_unit_view_mode->value == df::ui_unit_view_mode::Inventory;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
df::job *Gui::getSelectedWorkshopJob(color_ostream &out, bool quiet)
|
|
|
|
df::job *Gui::getSelectedWorkshopJob(color_ostream &out, bool quiet)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
using df::global::ui_workshop_job_cursor;
|
|
|
|
auto bld = getSelectedBuilding(out, true);
|
|
|
|
|
|
|
|
if (!bld)
|
|
|
|
if (!workshop_job_hotkey(Core::getTopViewscreen())) {
|
|
|
|
|
|
|
|
if (!quiet)
|
|
|
|
|
|
|
|
out.printerr("Not in a workshop, or no job is highlighted.\n");
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
df::building *selected = world->selected_building;
|
|
|
|
// no way to select a specific job; just get the first one
|
|
|
|
int idx = *ui_workshop_job_cursor;
|
|
|
|
return bld->jobs.size() ? bld->jobs[0] : NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (size_t(idx) >= selected->jobs.size())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
out.printerr("Invalid job cursor index: %d\n", idx);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return selected->jobs[idx];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Gui::any_job_hotkey(df::viewscreen *top)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* TODO: understand how this changes for v50
|
|
|
|
|
|
|
|
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_joblistst, top))
|
|
|
|
|
|
|
|
return vector_get(screen->jobs, screen->cursor_pos) != NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_unitlistst, top))
|
|
|
|
|
|
|
|
return vector_get(screen->jobs[screen->page], screen->cursor_pos[screen->page]) != NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return workshop_job_hotkey(top);
|
|
|
|
|
|
|
|
*/ return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
df::job *Gui::getSelectedJob(color_ostream &out, bool quiet)
|
|
|
|
df::job *Gui::getSelectedJob(color_ostream &out, bool quiet)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* TODO: understand how this changes for v50
|
|
|
|
using df::global::game;
|
|
|
|
df::viewscreen *top = Core::getTopViewscreen();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_jobst, top))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return screen->job;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VIRTUAL_CAST_VAR(joblist, df::viewscreen_joblistst, top))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::job *job = vector_get(joblist->jobs, joblist->cursor_pos);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!job && !quiet)
|
|
|
|
auto top = Core::getTopViewscreen();
|
|
|
|
out.printerr("Selected unit has no job\n");
|
|
|
|
if (auto dfscreen = dfhack_viewscreen::try_cast(top))
|
|
|
|
|
|
|
|
return dfscreen->getSelectedJob();
|
|
|
|
|
|
|
|
|
|
|
|
return job;
|
|
|
|
if (matchFocusString("dwarfmode/Info/JOBS")) {
|
|
|
|
|
|
|
|
auto &cri_job = game->main_interface.info.jobs.cri_job;
|
|
|
|
|
|
|
|
// no way to select specific jobs; just get the first one
|
|
|
|
|
|
|
|
return cri_job.size() ? cri_job[0]->jb : NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (VIRTUAL_CAST_VAR(unitlist, df::viewscreen_unitlistst, top))
|
|
|
|
|
|
|
|
{
|
|
|
|
if (auto unit = getAnyUnit(top)) {
|
|
|
|
int page = unitlist->page;
|
|
|
|
df::job *job = unit->job.current_job;
|
|
|
|
df::job *job = vector_get(unitlist->jobs[page], unitlist->cursor_pos[page]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!job && !quiet)
|
|
|
|
if (!job && !quiet)
|
|
|
|
out.printerr("Selected unit has no job\n");
|
|
|
|
out.printerr("Selected unit has no job\n");
|
|
|
|
|
|
|
|
|
|
|
|
return job;
|
|
|
|
return job;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (auto dfscreen = dfhack_viewscreen::try_cast(top))
|
|
|
|
|
|
|
|
return dfscreen->getSelectedJob();
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
return getSelectedWorkshopJob(out, quiet);
|
|
|
|
return getSelectedWorkshopJob(out, quiet);
|
|
|
|
*/ return getSelectedWorkshopJob(out, quiet);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
df::unit *Gui::getAnyUnit(df::viewscreen *top)
|
|
|
|
df::unit *Gui::getAnyUnit(df::viewscreen *top)
|
|
|
|