Merge branch 'master' of git://github.com/peterix/dfhack

develop
Warmist 2012-03-04 14:47:09 +02:00
commit 69e1da184c
63 changed files with 569 additions and 480 deletions

@ -47,6 +47,7 @@ using namespace std;
#include "modules/Gui.h" #include "modules/Gui.h"
#include "modules/World.h" #include "modules/World.h"
#include "modules/Graphic.h" #include "modules/Graphic.h"
//#include "modules/Windows.h"
using namespace DFHack; using namespace DFHack;
#include "SDL_events.h" #include "SDL_events.h"
@ -635,7 +636,6 @@ bool Core::Init()
cerr << "Initializing Console.\n"; cerr << "Initializing Console.\n";
// init the console. // init the console.
Gui * g = getGui();
bool is_text_mode = false; bool is_text_mode = false;
if(init && init->display.flag.is_set(init_display_flags::TEXT)) if(init && init->display.flag.is_set(init_display_flags::TEXT))
{ {
@ -877,20 +877,19 @@ bool Core::ncurses_wgetch(int in, int & out)
{ {
int idx = in - KEY_F(1); int idx = in - KEY_F(1);
// FIXME: copypasta, push into a method! // FIXME: copypasta, push into a method!
Gui * g = getGui(); if(df::global::ui && df::global::gview)
if(df::global::ui && df::global::gview && g->df_menu_state)
{ {
df::viewscreen * ws = g->GetCurrentScreen(); df::viewscreen * ws = Gui::GetCurrentScreen();
// FIXME: USE ENUMS if (strict_virtual_cast<df::viewscreen_dwarfmodest>(ws) &&
if(((t_virtual *)ws)->getClassName() == "viewscreen_dwarfmodest" && *g->df_menu_state == 0x23) df::global::ui->main.mode != ui_sidebar_mode::Hotkeys)
{ {
out = in; setHotkeyCmd(df::global::ui->main.hotkeys[idx].name);
return true; return false;
} }
else else
{ {
setHotkeyCmd(df::global::ui->main.hotkeys[idx].name); out = in;
return false; return true;
} }
} }
} }
@ -1123,7 +1122,6 @@ TYPE * Core::get##TYPE() \
return s_mods.p##TYPE;\ return s_mods.p##TYPE;\
} }
MODULE_GETTER(Gui);
MODULE_GETTER(World); MODULE_GETTER(World);
MODULE_GETTER(Materials); MODULE_GETTER(Materials);
MODULE_GETTER(Notes); MODULE_GETTER(Notes);

@ -341,7 +341,7 @@ bool Plugin::can_invoke_hotkey( std::string & command, df::viewscreen *top )
else if (cmd.guard) else if (cmd.guard)
cr = cmd.guard(&c, top); cr = cmd.guard(&c, top);
else else
cr = default_hotkey(&c, top); cr = Gui::default_hotkey(&c, top);
break; break;
} }
} }

@ -52,7 +52,6 @@ namespace DFHack
{ {
class Process; class Process;
class Module; class Module;
class Gui;
class World; class World;
class Materials; class Materials;
class Notes; class Notes;
@ -98,8 +97,6 @@ namespace DFHack
/// Is everything OK? /// Is everything OK?
bool isValid(void) { return !errorstate; } bool isValid(void) { return !errorstate; }
/// get the gui module
Gui * getGui();
/// get the world module /// get the world module
World * getWorld(); World * getWorld();
/// get the materials module /// get the materials module
@ -153,7 +150,6 @@ namespace DFHack
// Module storage // Module storage
struct struct
{ {
Gui * pGui;
World * pWorld; World * pWorld;
Materials * pMaterials; Materials * pMaterials;
Notes * pNotes; Notes * pNotes;

@ -182,10 +182,13 @@ namespace DFHack
std::string plugin_path; std::string plugin_path;
}; };
// Predefined hotkey guards namespace Gui
DFHACK_EXPORT bool default_hotkey(Core *, df::viewscreen *); {
DFHACK_EXPORT bool dwarfmode_hotkey(Core *, df::viewscreen *); // Predefined hotkey guards
DFHACK_EXPORT bool cursor_hotkey(Core *, df::viewscreen *); DFHACK_EXPORT bool default_hotkey(Core *, df::viewscreen *);
DFHACK_EXPORT bool dwarfmode_hotkey(Core *, df::viewscreen *);
DFHACK_EXPORT bool cursor_hotkey(Core *, df::viewscreen *);
}
}; };
/// You have to have this in every plugin you write - just once. Ideally on top of the main file. /// You have to have this in every plugin you write - just once. Ideally on top of the main file.

@ -35,8 +35,6 @@ distribution.
namespace DFHack namespace DFHack
{ {
namespace Simple
{
namespace Buildings namespace Buildings
{ {
/** /**
@ -86,4 +84,3 @@ DFHACK_EXPORT bool ReadCustomWorkshopTypes(std::map <uint32_t, std::string> & bt
} }
} }
}

@ -38,8 +38,6 @@ distribution.
*/ */
namespace DFHack namespace DFHack
{ {
namespace Simple
{
namespace Constructions namespace Constructions
{ {
// "Simplified" copy of construction // "Simplified" copy of construction
@ -61,5 +59,4 @@ DFHACK_EXPORT bool copyConstruction (const int32_t index, t_construction &out);
DFHACK_EXPORT df::construction * getConstruction (const int32_t index); DFHACK_EXPORT df::construction * getConstruction (const int32_t index);
} }
} }
}
#endif #endif

@ -37,8 +37,6 @@ distribution.
*/ */
namespace DFHack namespace DFHack
{ {
namespace Simple
{
namespace Engravings namespace Engravings
{ {
// "Simplified" copy of engraving // "Simplified" copy of engraving
@ -62,5 +60,4 @@ DFHACK_EXPORT bool copyEngraving (const int32_t index, t_engraving &out);
DFHACK_EXPORT df::engraving * getEngraving (const int32_t index); DFHACK_EXPORT df::engraving * getEngraving (const int32_t index);
} }
} }
}
#endif #endif

@ -23,9 +23,6 @@ distribution.
*/ */
#pragma once #pragma once
#ifndef CL_MOD_GUI
#define CL_MOD_GUI
#include "Export.h" #include "Export.h"
#include "Module.h" #include "Module.h"
#include "Virtual.h" #include "Virtual.h"
@ -44,108 +41,81 @@ namespace df {
}; };
/** /**
* \defgroup grp_gui query DF's GUI state * \defgroup grp_gui utility code that helps dealing with DF's user interface
* @ingroup grp_modules * @ingroup grp_modules
*/ */
namespace DFHack namespace DFHack
{ {
class Core; class Core;
// Full-screen item details view
DFHACK_EXPORT bool item_details_hotkey(Core *, df::viewscreen *top);
// 'u'nits or 'j'obs full-screen view
DFHACK_EXPORT bool unitjobs_hotkey(Core *, df::viewscreen *top);
// A job is selected in a workshop
DFHACK_EXPORT bool workshop_job_hotkey(Core *c, df::viewscreen *top);
// Building material selection mode
DFHACK_EXPORT bool build_selector_hotkey(Core *c, df::viewscreen *top);
// A unit is selected in the 'v' mode
DFHACK_EXPORT bool view_unit_hotkey(Core *c, df::viewscreen *top);
// Above + the inventory page is selected.
DFHACK_EXPORT bool unit_inventory_hotkey(Core *c, df::viewscreen *top);
// In workshop_job_hotkey, returns the job
DFHACK_EXPORT df::job *getSelectedWorkshopJob(Core *c, bool quiet = false);
// A job is selected in a workshop, or unitjobs
DFHACK_EXPORT bool any_job_hotkey(Core *c, df::viewscreen *top);
DFHACK_EXPORT df::job *getSelectedJob(Core *c, bool quiet = false);
// A unit is selected via 'v', 'k', unitjobs, or
// a full-screen item view of a cage or suchlike
DFHACK_EXPORT bool any_unit_hotkey(Core *c, df::viewscreen *top);
DFHACK_EXPORT df::unit *getSelectedUnit(Core *c, bool quiet = false);
// An item is selected via 'v'->inventory, 'k', 't', or
// a full-screen item view of a container. Note that in the
// last case, the highlighted contained item is returned, not
// the container itself.
DFHACK_EXPORT bool any_item_hotkey(Core *c, df::viewscreen *top);
DFHACK_EXPORT df::item *getSelectedItem(Core *c, bool quiet = false);
// Show a plain announcement, or a titan-style popup message
DFHACK_EXPORT void showAnnouncement(std::string message, int color = 7, bool bright = true);
DFHACK_EXPORT void showPopupAnnouncement(std::string message, int color = 7, bool bright = true);
class DFContextShared;
/**
* One tile of the screen. Possibly outdated.
* \ingroup grp_gui
*/
struct t_screen
{
uint8_t symbol;
uint8_t foreground;
uint8_t background;
uint8_t bright;
uint8_t gtile;
uint8_t grayscale;
};
/** /**
* The Gui module * The Gui module
* \ingroup grp_modules * \ingroup grp_modules
* \ingroup grp_gui * \ingroup grp_gui
*/ */
class DFHACK_EXPORT Gui: public Module namespace Gui
{ {
public: // Full-screen item details view
DFHACK_EXPORT bool item_details_hotkey(Core *, df::viewscreen *top);
// 'u'nits or 'j'obs full-screen view
DFHACK_EXPORT bool unitjobs_hotkey(Core *, df::viewscreen *top);
// A job is selected in a workshop
DFHACK_EXPORT bool workshop_job_hotkey(Core *c, df::viewscreen *top);
// Building material selection mode
DFHACK_EXPORT bool build_selector_hotkey(Core *c, df::viewscreen *top);
// A unit is selected in the 'v' mode
DFHACK_EXPORT bool view_unit_hotkey(Core *c, df::viewscreen *top);
// Above + the inventory page is selected.
DFHACK_EXPORT bool unit_inventory_hotkey(Core *c, df::viewscreen *top);
// In workshop_job_hotkey, returns the job
DFHACK_EXPORT df::job *getSelectedWorkshopJob(Core *c, bool quiet = false);
// A job is selected in a workshop, or unitjobs
DFHACK_EXPORT bool any_job_hotkey(Core *c, df::viewscreen *top);
DFHACK_EXPORT df::job *getSelectedJob(Core *c, bool quiet = false);
// A unit is selected via 'v', 'k', unitjobs, or
// a full-screen item view of a cage or suchlike
DFHACK_EXPORT bool any_unit_hotkey(Core *c, df::viewscreen *top);
DFHACK_EXPORT df::unit *getSelectedUnit(Core *c, bool quiet = false);
// An item is selected via 'v'->inventory, 'k', 't', or
// a full-screen item view of a container. Note that in the
// last case, the highlighted contained item is returned, not
// the container itself.
DFHACK_EXPORT bool any_item_hotkey(Core *c, df::viewscreen *top);
DFHACK_EXPORT df::item *getSelectedItem(Core *c, bool quiet = false);
// Show a plain announcement, or a titan-style popup message
DFHACK_EXPORT void showAnnouncement(std::string message, int color = 7, bool bright = true);
DFHACK_EXPORT void showPopupAnnouncement(std::string message, int color = 7, bool bright = true);
Gui();
~Gui();
bool Start();
bool Finish();
/* /*
* Cursor and window coords * Cursor and window coords
*/ */
bool getViewCoords (int32_t &x, int32_t &y, int32_t &z); DFHACK_EXPORT bool getViewCoords (int32_t &x, int32_t &y, int32_t &z);
bool setViewCoords (const int32_t x, const int32_t y, const int32_t z); DFHACK_EXPORT bool setViewCoords (const int32_t x, const int32_t y, const int32_t z);
bool getCursorCoords (int32_t &x, int32_t &y, int32_t &z);
bool setCursorCoords (const int32_t x, const int32_t y, const int32_t z);
bool getDesignationCoords (int32_t &x, int32_t &y, int32_t &z); DFHACK_EXPORT bool getCursorCoords (int32_t &x, int32_t &y, int32_t &z);
bool setDesignationCoords (const int32_t x, const int32_t y, const int32_t z); DFHACK_EXPORT bool setCursorCoords (const int32_t x, const int32_t y, const int32_t z);
bool getMousePos (int32_t & x, int32_t & y); DFHACK_EXPORT bool getDesignationCoords (int32_t &x, int32_t &y, int32_t &z);
DFHACK_EXPORT bool setDesignationCoords (const int32_t x, const int32_t y, const int32_t z);
DFHACK_EXPORT bool getMousePos (int32_t & x, int32_t & y);
/* /*
* Gui screens * Gui screens
*/ */
/// Get the current top-level view-screen /// Get the current top-level view-screen
df::viewscreen * GetCurrentScreen(); DFHACK_EXPORT df::viewscreen * GetCurrentScreen();
/// The DF menu state (designation menu ect)
uint32_t * df_menu_state;
/* /// get the size of the window buffer
* Window size in tiles DFHACK_EXPORT bool getWindowSize(int32_t & width, int32_t & height);
*/
bool getWindowSize(int32_t & width, int32_t & height);
/* /**
*Menu width: *Menu width:
*3:3 - menu and area map closed *3:3 - menu and area map closed
*2:3 - menu open single width *2:3 - menu open single width
*1:3 - menu open double width *1:3 - menu open double width
@ -153,18 +123,7 @@ namespace DFHack
*2:2 - area map open *2:2 - area map open
*/ */
bool getMenuWidth(uint8_t & menu_width, uint8_t & area_map_width); DFHACK_EXPORT bool getMenuWidth(uint8_t & menu_width, uint8_t & area_map_width);
bool setMenuWidth(const uint8_t menu_width, const uint8_t area_map_width); DFHACK_EXPORT bool setMenuWidth(const uint8_t menu_width, const uint8_t area_map_width);
}
/*
* Screen tiles
*/
bool getScreenTiles(int32_t width, int32_t height, t_screen screen[]);
private:
struct Private;
Private *d;
};
} }
#endif

@ -112,8 +112,6 @@ struct dfh_item
* \ingroup grp_modules * \ingroup grp_modules
* \ingroup grp_items * \ingroup grp_items
*/ */
namespace Simple
{
namespace Items namespace Items
{ {
@ -141,5 +139,4 @@ DFHACK_EXPORT bool removeItemOwner(df::item * item);
DFHACK_EXPORT bool readItemRefs(const df::item * item, const df::general_ref_type type, DFHACK_EXPORT bool readItemRefs(const df::item * item, const df::general_ref_type type,
/*output*/ std::vector<int32_t> &values); /*output*/ std::vector<int32_t> &values);
} }
}
} }

@ -33,7 +33,6 @@ distribution.
#include "df/map_block.h" #include "df/map_block.h"
#include "df/block_square_event_mineralst.h" #include "df/block_square_event_mineralst.h"
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
namespace MapExtras namespace MapExtras
{ {
void SquashVeins (DFCoord bcoord, mapblock40d & mb, t_blockmaterials & materials) void SquashVeins (DFCoord bcoord, mapblock40d & mb, t_blockmaterials & materials)

@ -192,8 +192,6 @@ typedef struct
* \ingroup grp_modules * \ingroup grp_modules
* \ingroup grp_maps * \ingroup grp_maps
*/ */
namespace Simple
{
namespace Maps namespace Maps
{ {
@ -324,7 +322,6 @@ extern DFHACK_EXPORT bool RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, d
/// read all plants in this block /// read all plants in this block
extern DFHACK_EXPORT bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df::plant *>*& plants); extern DFHACK_EXPORT bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df::plant *>*& plants);
}
} }
} }
#endif #endif

@ -41,8 +41,6 @@ distribution.
namespace DFHack namespace DFHack
{ {
namespace Simple
{
namespace Translation namespace Translation
{ {
// simple check to make sure if there's actual language data present // simple check to make sure if there's actual language data present
@ -56,5 +54,4 @@ DFHACK_EXPORT bool copyName(df::language_name * address, df::language_name * tar
DFHACK_EXPORT std::string TranslateName (const df::language_name * name, bool inEnglish = true); DFHACK_EXPORT std::string TranslateName (const df::language_name * name, bool inEnglish = true);
} }
} }
}
#endif #endif

@ -39,8 +39,6 @@ distribution.
*/ */
namespace DFHack namespace DFHack
{ {
namespace Simple
{
namespace Units namespace Units
{ {
/** /**
@ -196,5 +194,4 @@ DFHACK_EXPORT bool RemoveOwnedItemByIdx(const uint32_t index, int32_t id);
DFHACK_EXPORT bool RemoveOwnedItemByPtr(df::unit * unit, int32_t id); DFHACK_EXPORT bool RemoveOwnedItemByPtr(df::unit * unit, int32_t id);
} }
} }
}
#endif #endif

@ -36,8 +36,6 @@ distribution.
namespace DFHack namespace DFHack
{ {
namespace Simple
{
namespace Vegetation namespace Vegetation
{ {
const uint32_t sapling_to_tree_threshold = 120 * 28 * 12 * 3; // 3 years const uint32_t sapling_to_tree_threshold = 120 * 28 * 12 * 3; // 3 years
@ -69,5 +67,4 @@ DFHACK_EXPORT df::plant * getPlant(const int32_t index);
DFHACK_EXPORT bool copyPlant (const int32_t index, t_plant &out); DFHACK_EXPORT bool copyPlant (const int32_t index, t_plant &out);
} }
} }
}
#endif #endif

@ -6,7 +6,9 @@
#include "DataDefs.h" #include "DataDefs.h"
#include "df/vermin.h" #include "df/vermin.h"
namespace DFHack { namespace Simple { namespace Vermin namespace DFHack
{
namespace Vermin
{ {
/** /**
* Structure for holding a read DF vermin spawn point object * Structure for holding a read DF vermin spawn point object
@ -38,4 +40,5 @@ namespace DFHack { namespace Simple { namespace Vermin
* Write into vermin object * Write into vermin object
*/ */
DFHACK_EXPORT bool Write (const uint32_t index, t_vermin & point); DFHACK_EXPORT bool Write (const uint32_t index, t_vermin & point);
} } } // end DFHack::Simple::Vermin }// end DFHack::Vermin
}

@ -40,8 +40,6 @@ distribution.
namespace DFHack namespace DFHack
{ {
namespace Simple
{
namespace Kitchen namespace Kitchen
{ {
typedef uint8_t t_exclusionType; typedef uint8_t t_exclusionType;
@ -83,4 +81,3 @@ DFHACK_EXPORT void clearLimits();
DFHACK_EXPORT std::size_t size(); DFHACK_EXPORT std::size_t size();
} }
} }
}

@ -38,7 +38,6 @@ using namespace std;
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include "Core.h" #include "Core.h"
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
#include "DataDefs.h" #include "DataDefs.h"
#include "df/world.h" #include "df/world.h"

@ -38,7 +38,6 @@ using namespace std;
#include "modules/Constructions.h" #include "modules/Constructions.h"
#include "df/world.h" #include "df/world.h"
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using df::global::world; using df::global::world;
bool Constructions::isValid() bool Constructions::isValid()

@ -39,7 +39,6 @@ using namespace std;
#include "df/world.h" #include "df/world.h"
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using df::global::world; using df::global::world;
bool Engravings::isValid() bool Engravings::isValid()

@ -69,7 +69,7 @@ using df::global::gps;
// Predefined common guard functions // Predefined common guard functions
bool DFHack::default_hotkey(Core *, df::viewscreen *top) bool Gui::default_hotkey(Core *, df::viewscreen *top)
{ {
// Default hotkey guard function // Default hotkey guard function
for (;top ;top = top->parent) for (;top ;top = top->parent)
@ -78,26 +78,26 @@ bool DFHack::default_hotkey(Core *, df::viewscreen *top)
return false; return false;
} }
bool DFHack::dwarfmode_hotkey(Core *, df::viewscreen *top) bool Gui::dwarfmode_hotkey(Core *, df::viewscreen *top)
{ {
// Require the main dwarf mode screen // Require the main dwarf mode screen
return !!strict_virtual_cast<df::viewscreen_dwarfmodest>(top); return !!strict_virtual_cast<df::viewscreen_dwarfmodest>(top);
} }
bool DFHack::unitjobs_hotkey(Core *, df::viewscreen *top) bool Gui::unitjobs_hotkey(Core *, df::viewscreen *top)
{ {
// Require the unit or jobs list // Require the unit or jobs list
return !!strict_virtual_cast<df::viewscreen_joblistst>(top) || return !!strict_virtual_cast<df::viewscreen_joblistst>(top) ||
!!strict_virtual_cast<df::viewscreen_unitlistst>(top); !!strict_virtual_cast<df::viewscreen_unitlistst>(top);
} }
bool DFHack::item_details_hotkey(Core *, df::viewscreen *top) bool Gui::item_details_hotkey(Core *, df::viewscreen *top)
{ {
// Require the main dwarf mode screen // Require the main dwarf mode screen
return !!strict_virtual_cast<df::viewscreen_itemst>(top); return !!strict_virtual_cast<df::viewscreen_itemst>(top);
} }
bool DFHack::cursor_hotkey(Core *c, df::viewscreen *top) bool Gui::cursor_hotkey(Core *c, df::viewscreen *top)
{ {
if (!dwarfmode_hotkey(c, top)) if (!dwarfmode_hotkey(c, top))
return false; return false;
@ -109,7 +109,7 @@ bool DFHack::cursor_hotkey(Core *c, df::viewscreen *top)
return true; return true;
} }
bool DFHack::workshop_job_hotkey(Core *c, df::viewscreen *top) bool Gui::workshop_job_hotkey(Core *c, df::viewscreen *top)
{ {
using namespace ui_sidebar_mode; using namespace ui_sidebar_mode;
using df::global::ui; using df::global::ui;
@ -147,7 +147,7 @@ bool DFHack::workshop_job_hotkey(Core *c, df::viewscreen *top)
} }
} }
bool DFHack::build_selector_hotkey(Core *c, df::viewscreen *top) bool Gui::build_selector_hotkey(Core *c, df::viewscreen *top)
{ {
using namespace ui_sidebar_mode; using namespace ui_sidebar_mode;
using df::global::ui; using df::global::ui;
@ -175,7 +175,7 @@ bool DFHack::build_selector_hotkey(Core *c, df::viewscreen *top)
} }
} }
bool DFHack::view_unit_hotkey(Core *c, df::viewscreen *top) bool Gui::view_unit_hotkey(Core *c, df::viewscreen *top)
{ {
using df::global::ui; using df::global::ui;
using df::global::world; using df::global::world;
@ -191,7 +191,7 @@ bool DFHack::view_unit_hotkey(Core *c, df::viewscreen *top)
return vector_get(world->units.other[0], *ui_selected_unit) != NULL; return vector_get(world->units.other[0], *ui_selected_unit) != NULL;
} }
bool DFHack::unit_inventory_hotkey(Core *c, df::viewscreen *top) bool Gui::unit_inventory_hotkey(Core *c, df::viewscreen *top)
{ {
using df::global::ui_unit_view_mode; using df::global::ui_unit_view_mode;
@ -203,7 +203,7 @@ bool DFHack::unit_inventory_hotkey(Core *c, df::viewscreen *top)
return ui_unit_view_mode->value == df::ui_unit_view_mode::Inventory; return ui_unit_view_mode->value == df::ui_unit_view_mode::Inventory;
} }
df::job *DFHack::getSelectedWorkshopJob(Core *c, bool quiet) df::job *Gui::getSelectedWorkshopJob(Core *c, bool quiet)
{ {
using df::global::world; using df::global::world;
using df::global::ui_workshop_job_cursor; using df::global::ui_workshop_job_cursor;
@ -226,7 +226,7 @@ df::job *DFHack::getSelectedWorkshopJob(Core *c, bool quiet)
return selected->jobs[idx]; return selected->jobs[idx];
} }
bool DFHack::any_job_hotkey(Core *c, df::viewscreen *top) bool Gui::any_job_hotkey(Core *c, df::viewscreen *top)
{ {
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_joblistst, top)) if (VIRTUAL_CAST_VAR(screen, df::viewscreen_joblistst, top))
return vector_get(screen->jobs, screen->cursor_pos) != NULL; return vector_get(screen->jobs, screen->cursor_pos) != NULL;
@ -237,7 +237,7 @@ bool DFHack::any_job_hotkey(Core *c, df::viewscreen *top)
return workshop_job_hotkey(c,top); return workshop_job_hotkey(c,top);
} }
df::job *DFHack::getSelectedJob(Core *c, bool quiet) df::job *Gui::getSelectedJob(Core *c, bool quiet)
{ {
df::viewscreen *top = c->getTopViewscreen(); df::viewscreen *top = c->getTopViewscreen();
@ -285,7 +285,7 @@ static df::unit *getAnyUnit(Core *c, df::viewscreen *top)
return ref ? ref->getUnit() : NULL; return ref ? ref->getUnit() : NULL;
} }
if (!dwarfmode_hotkey(c,top)) if (!Gui::dwarfmode_hotkey(c,top))
return NULL; return NULL;
switch (ui->main.mode) { switch (ui->main.mode) {
@ -312,12 +312,12 @@ static df::unit *getAnyUnit(Core *c, df::viewscreen *top)
} }
} }
bool DFHack::any_unit_hotkey(Core *c, df::viewscreen *top) bool Gui::any_unit_hotkey(Core *c, df::viewscreen *top)
{ {
return getAnyUnit(c, top) != NULL; return getAnyUnit(c, top) != NULL;
} }
df::unit *DFHack::getSelectedUnit(Core *c, bool quiet) df::unit *Gui::getSelectedUnit(Core *c, bool quiet)
{ {
df::unit *unit = getAnyUnit(c, c->getTopViewscreen()); df::unit *unit = getAnyUnit(c, c->getTopViewscreen());
@ -344,7 +344,7 @@ static df::item *getAnyItem(Core *c, df::viewscreen *top)
return ref ? ref->getItem() : NULL; return ref ? ref->getItem() : NULL;
} }
if (!dwarfmode_hotkey(c,top)) if (!Gui::dwarfmode_hotkey(c,top))
return NULL; return NULL;
switch (ui->main.mode) { switch (ui->main.mode) {
@ -387,12 +387,12 @@ static df::item *getAnyItem(Core *c, df::viewscreen *top)
} }
} }
bool DFHack::any_item_hotkey(Core *c, df::viewscreen *top) bool Gui::any_item_hotkey(Core *c, df::viewscreen *top)
{ {
return getAnyItem(c, top) != NULL; return getAnyItem(c, top) != NULL;
} }
df::item *DFHack::getSelectedItem(Core *c, bool quiet) df::item *Gui::getSelectedItem(Core *c, bool quiet)
{ {
df::item *item = getAnyItem(c, c->getTopViewscreen()); df::item *item = getAnyItem(c, c->getTopViewscreen());
@ -404,7 +404,7 @@ df::item *DFHack::getSelectedItem(Core *c, bool quiet)
// //
void DFHack::showAnnouncement(std::string message, int color, bool bright) void Gui::showAnnouncement(std::string message, int color, bool bright)
{ {
using df::global::world; using df::global::world;
using df::global::cur_year; using df::global::cur_year;
@ -455,7 +455,7 @@ void DFHack::showAnnouncement(std::string message, int color, bool bright)
} }
void DFHack::showPopupAnnouncement(std::string message, int color, bool bright) void Gui::showPopupAnnouncement(std::string message, int color, bool bright)
{ {
using df::global::world; using df::global::world;
@ -466,77 +466,6 @@ void DFHack::showPopupAnnouncement(std::string message, int color, bool bright)
world->status.popups.push_back(popup); world->status.popups.push_back(popup);
} }
//
Module* DFHack::createGui()
{
return new Gui();
}
struct Gui::Private
{
Private()
{
Started = false;
StartedMenu = false;
StartedScreen = false;
}
bool Started;
int32_t * window_x_offset;
int32_t * window_y_offset;
int32_t * window_z_offset;
bool StartedMenu;
uint8_t * menu_width_offset;
uint8_t * area_map_width_offset;
bool StartedScreen;
void * screen_tiles_ptr_offset;
Process * owner;
};
Gui::Gui()
{
Core & c = Core::getInstance();
d = new Private;
d->owner = c.p;
VersionInfo * mem = c.vinfo;
// Setting up menu state
df_menu_state = (uint32_t *) & df::global::ui->main.mode;
d->window_x_offset = (int32_t *) mem->getAddress ("window_x");
d->window_y_offset = (int32_t *) mem->getAddress ("window_y");
d->window_z_offset = (int32_t *) mem->getAddress ("window_z");
if(d->window_z_offset && d->window_y_offset && d->window_x_offset)
d->Started = true;
d->menu_width_offset = (uint8_t *) mem->getAddress("ui_menu_width");
d->area_map_width_offset = (uint8_t *) mem->getAddress("ui_area_map_width");
if (d->menu_width_offset && d->area_map_width_offset)
d->StartedMenu = true;
d->screen_tiles_ptr_offset = (void *) mem->getAddress ("screen_tiles_pointer");
if(d->screen_tiles_ptr_offset)
d->StartedScreen = true;
}
Gui::~Gui()
{
delete d;
}
bool Gui::Start()
{
return true;
}
bool Gui::Finish()
{
return true;
}
df::viewscreen * Gui::GetCurrentScreen() df::viewscreen * Gui::GetCurrentScreen()
{ {
df::viewscreen * ws = &gview->view; df::viewscreen * ws = &gview->view;
@ -552,27 +481,18 @@ df::viewscreen * Gui::GetCurrentScreen()
bool Gui::getViewCoords (int32_t &x, int32_t &y, int32_t &z) bool Gui::getViewCoords (int32_t &x, int32_t &y, int32_t &z)
{ {
if (!d->Started) return false; x = *df::global::window_x;
Process * p = d->owner; y = *df::global::window_y;
z = *df::global::window_z;
p->readDWord (d->window_x_offset, (uint32_t &) x);
p->readDWord (d->window_y_offset, (uint32_t &) y);
p->readDWord (d->window_z_offset, (uint32_t &) z);
return true; return true;
} }
//FIXME: confine writing of coords to map bounds?
bool Gui::setViewCoords (const int32_t x, const int32_t y, const int32_t z) bool Gui::setViewCoords (const int32_t x, const int32_t y, const int32_t z)
{ {
if (!d->Started) auto cursor = df::global::cursor;
{ (*df::global::window_x) = x;
return false; (*df::global::window_y) = y;
} (*df::global::window_z) = z;
Process * p = d->owner;
p->writeDWord (d->window_x_offset, (uint32_t) x);
p->writeDWord (d->window_y_offset, (uint32_t) y);
p->writeDWord (d->window_z_offset, (uint32_t) z);
return true; return true;
} }
@ -581,8 +501,7 @@ bool Gui::getCursorCoords (int32_t &x, int32_t &y, int32_t &z)
x = df::global::cursor->x; x = df::global::cursor->x;
y = df::global::cursor->y; y = df::global::cursor->y;
z = df::global::cursor->z; z = df::global::cursor->z;
if (x == -30000) return false; return (x == -30000) ? false : true;
return true;
} }
//FIXME: confine writing of coords to map bounds? //FIXME: confine writing of coords to map bounds?
@ -599,8 +518,7 @@ bool Gui::getDesignationCoords (int32_t &x, int32_t &y, int32_t &z)
x = df::global::selection_rect->start_x; x = df::global::selection_rect->start_x;
y = df::global::selection_rect->start_y; y = df::global::selection_rect->start_y;
z = df::global::selection_rect->start_z; z = df::global::selection_rect->start_z;
if (x == -30000) return false; return (x == -30000) ? false : true;
return true;
} }
bool Gui::setDesignationCoords (const int32_t x, const int32_t y, const int32_t z) bool Gui::setDesignationCoords (const int32_t x, const int32_t y, const int32_t z)
@ -615,8 +533,7 @@ bool Gui::getMousePos (int32_t & x, int32_t & y)
{ {
x = gps->mouse_x; x = gps->mouse_x;
y = gps->mouse_y; y = gps->mouse_y;
if(x == -1) return false; return (x == -1) ? false : true;
return true;
} }
bool Gui::getWindowSize (int32_t &width, int32_t &height) bool Gui::getWindowSize (int32_t &width, int32_t &height)
@ -628,49 +545,14 @@ bool Gui::getWindowSize (int32_t &width, int32_t &height)
bool Gui::getMenuWidth(uint8_t &menu_width, uint8_t &area_map_width) bool Gui::getMenuWidth(uint8_t &menu_width, uint8_t &area_map_width)
{ {
if (!d->StartedMenu) return false; menu_width = *df::global::ui_menu_width;
area_map_width = *df::global::ui_area_map_width;
Process * p = d->owner;
p->readByte (d->menu_width_offset, menu_width);
p->readByte (d->area_map_width_offset, area_map_width);
return true; return true;
} }
bool Gui::setMenuWidth(const uint8_t menu_width, const uint8_t area_map_width) bool Gui::setMenuWidth(const uint8_t menu_width, const uint8_t area_map_width)
{ {
if (!d->StartedMenu) return false; *df::global::ui_menu_width = menu_width;
*df::global::ui_area_map_width = area_map_width;
Process * p = d->owner;
p->writeByte (d->menu_width_offset, menu_width);
p->writeByte (d->area_map_width_offset, area_map_width);
return true; return true;
} }
bool Gui::getScreenTiles (int32_t width, int32_t height, t_screen screen[])
{
if(!d->StartedScreen) return false;
void * screen_addr = (void *) d->owner->readDWord(d->screen_tiles_ptr_offset);
uint8_t* tiles = new uint8_t[width*height*4/* + 80 + width*height*4*/];
d->owner->read (screen_addr, (width*height*4/* + 80 + width*height*4*/), tiles);
for(int32_t iy=0; iy<height; iy++)
{
for(int32_t ix=0; ix<width; ix++)
{
screen[ix + iy*width].symbol = tiles[(iy + ix*height)*4 +0];
screen[ix + iy*width].foreground = tiles[(iy + ix*height)*4 +1];
screen[ix + iy*width].background = tiles[(iy + ix*height)*4 +2];
screen[ix + iy*width].bright = tiles[(iy + ix*height)*4 +3];
//screen[ix + iy*width].gtile = tiles[width*height*4 + 80 + iy + ix*height +0];
//screen[ix + iy*width].grayscale = tiles[width*height*4 + 80 + iy + ix*height +1];
}
}
delete [] tiles;
return true;
}

@ -66,7 +66,6 @@ using namespace std;
#include "df/general_ref.h" #include "df/general_ref.h"
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using namespace df::enums; using namespace df::enums;
using df::global::world; using df::global::world;

@ -47,7 +47,6 @@ using namespace std;
#include "df/feature_init.h" #include "df/feature_init.h"
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using namespace df::enums; using namespace df::enums;
using df::global::world; using df::global::world;

@ -467,7 +467,7 @@ void MaterialInfo::getMatchBits(df::job_item_flags2 &ok, df::job_item_flags2 &ma
TEST(fire_safe, material->heat.melting_point > 11000); TEST(fire_safe, material->heat.melting_point > 11000);
TEST(magma_safe, material->heat.melting_point > 12000); TEST(magma_safe, material->heat.melting_point > 12000);
TEST(deep_material, FLAG(inorganic, inorganic_flags::DEEP_ANY)); TEST(deep_material, FLAG(inorganic, inorganic_flags::SPECIAL));
TEST(non_economic, inorganic && !(ui && ui->economic_stone[index])); TEST(non_economic, inorganic && !(ui && ui->economic_stone[index]));
TEST(plant, plant); TEST(plant, plant);

@ -37,7 +37,6 @@ using namespace std;
#include "Core.h" #include "Core.h"
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using namespace df::enums; using namespace df::enums;
#include "DataDefs.h" #include "DataDefs.h"

@ -50,7 +50,6 @@ using namespace std;
#include "df/unit_inventory_item.h" #include "df/unit_inventory_item.h"
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using df::global::world; using df::global::world;
using df::global::ui; using df::global::ui;

@ -40,7 +40,6 @@ using namespace DFHack;
#include "df/world.h" #include "df/world.h"
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using df::global::world; using df::global::world;
bool Vegetation::isValid() bool Vegetation::isValid()

@ -37,7 +37,6 @@ using namespace std;
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include "Core.h" #include "Core.h"
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
#include "DataDefs.h" #include "DataDefs.h"
#include "df/world.h" #include "df/world.h"

@ -17,7 +17,6 @@ using namespace std;
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include "Core.h" #include "Core.h"
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
#include "DataDefs.h" #include "DataDefs.h"
#include "df/world.h" #include "df/world.h"

@ -1 +1 @@
Subproject commit 0b7140582457982434df8d5756b5132d15a6b1f4 Subproject commit cd7c4b1c8f6a73a9ed7cdf04b65ee2a75910202c

@ -11,18 +11,22 @@
#include "DataDefs.h" #include "DataDefs.h"
#include "df/world.h" #include "df/world.h"
#include "df/ui_advmode.h" #include "df/ui_advmode.h"
#include "df/item.h"
#include "df/unit.h" #include "df/unit.h"
#include "df/unit_inventory_item.h" #include "df/unit_inventory_item.h"
#include "df/map_block.h"
#include "df/nemesis_record.h" #include "df/nemesis_record.h"
#include "df/historical_figure.h" #include "df/historical_figure.h"
#include "df/general_ref_is_nemesisst.h" #include "df/general_ref_is_nemesisst.h"
#include "df/general_ref_contains_itemst.h" #include "df/general_ref_contains_itemst.h"
#include "df/general_ref_building_civzone_assignedst.h"
#include "df/material.h" #include "df/material.h"
#include "df/craft_material_class.h" #include "df/craft_material_class.h"
#include "df/viewscreen_optionst.h" #include "df/viewscreen_optionst.h"
#include "df/viewscreen_dungeonmodest.h" #include "df/viewscreen_dungeonmodest.h"
#include "df/viewscreen_dungeon_monsterstatusst.h" #include "df/viewscreen_dungeon_monsterstatusst.h"
#include <math.h>
using namespace DFHack; using namespace DFHack;
using namespace df::enums; using namespace df::enums;
@ -33,7 +37,7 @@ using df::global::ui_advmode;
using df::nemesis_record; using df::nemesis_record;
using df::historical_figure; using df::historical_figure;
using namespace DFHack::Simple::Translation; using namespace DFHack::Translation;
/********************* /*********************
* PLUGIN INTERFACE * * PLUGIN INTERFACE *
@ -59,6 +63,9 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
" list-equipped [all]\n" " list-equipped [all]\n"
" List armor and weapons equipped by your companions.\n" " List armor and weapons equipped by your companions.\n"
" If all is specified, also lists non-metal clothing.\n" " If all is specified, also lists non-metal clothing.\n"
" metal-detector [all-types] [non-trader]\n"
" Reveal metal armor and weapons in shops. The options\n"
" disable the checks on item type and being in shop.\n"
)); ));
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
@ -201,7 +208,7 @@ bool bodySwap(Core *c, df::unit *player)
df::nemesis_record *getPlayerNemesis(Core *c, bool restore_swap) df::nemesis_record *getPlayerNemesis(Core *c, bool restore_swap)
{ {
auto real_nemesis = df::nemesis_record::find(ui_advmode->player_id); auto real_nemesis = vector_get(world->nemesis.all, ui_advmode->player_id);
if (!real_nemesis || !real_nemesis->unit) if (!real_nemesis || !real_nemesis->unit)
{ {
c->con.printerr("Invalid player nemesis id: %d\n", ui_advmode->player_id); c->con.printerr("Invalid player nemesis id: %d\n", ui_advmode->player_id);
@ -274,7 +281,11 @@ void sortCompanionNemesis(std::vector<nemesis_record*> *list, int player_id = -1
output.reserve(list->size()); output.reserve(list->size());
if (player_id < 0) if (player_id < 0)
player_id = ui_advmode->player_id; {
auto real_nemesis = vector_get(world->nemesis.all, ui_advmode->player_id);
if (real_nemesis)
player_id = real_nemesis->id;
}
// Index records; find the player // Index records; find the player
for (size_t i = 0; i < list->size(); i++) for (size_t i = 0; i < list->size(); i++)
@ -380,6 +391,87 @@ void listUnitInventory(std::vector<inv_item> *list, df::unit *unit)
} }
} }
bool isShopItem(df::item *item)
{
for (size_t k = 0; k < item->itemrefs.size(); k++)
{
auto ref = item->itemrefs[k];
if (virtual_cast<df::general_ref_building_civzone_assignedst>(ref))
return true;
}
return false;
}
bool isWeaponArmor(df::item *item)
{
using namespace df::enums::item_type;
switch (item->getType()) {
case HELM:
case ARMOR:
case WEAPON:
case AMMO:
case GLOVES:
case PANTS:
case SHOES:
return true;
default:
return false;
}
}
int containsMetalItems(df::item *item, bool all, bool non_trader)
{
int cnt = 0;
auto &refs = item->itemrefs;
for (size_t i = 0; i < refs.size(); i++)
{
auto ref = refs[i];
if (!strict_virtual_cast<df::general_ref_contains_itemst>(ref))
continue;
df::item *child = ref->getItem();
if (!child) continue;
cnt += containsMetalItems(child, all, non_trader);
}
if (!non_trader && !isShopItem(item))
return cnt;
if (!all && !isWeaponArmor(item))
return cnt;
MaterialInfo minfo(item);
if (minfo.getCraftClass() != craft_material_class::Metal)
return cnt;
return ++cnt;
}
void joinCounts(std::map<df::coord, int> &counts)
{
for (auto it = counts.begin(); it != counts.end(); it++)
{
df::coord pt = it->first;
while (pt.x > 0 && counts.count(pt - df::coord(1,0,0)))
pt.x--;
while (pt.y > 0 &&counts.count(pt - df::coord(0,1,0)))
pt.y--;
while (pt.x < 0 && counts.count(pt + df::coord(1,0,0)))
pt.x++;
while (pt.y < 0 &&counts.count(pt + df::coord(0,1,0)))
pt.y++;
if (pt == it->first)
continue;
counts[pt] += it->second;
it->second = 0;
}
}
/********************* /*********************
* FORMATTING * * FORMATTING *
*********************/ *********************/
@ -428,6 +520,37 @@ static size_t formatSize(std::vector<std::string> *out, const std::map<std::stri
return len; return len;
} }
static std::string formatDirection(df::coord delta)
{
std::string ns, ew, dir;
if (delta.x > 0)
ew = "E";
else if (delta.x < 0)
ew = "W";
if (delta.y > 0)
ns = "S";
else if (delta.y < 0)
ns = "N";
if (abs(delta.x) > abs(delta.y)*5)
dir = ew;
else if (abs(delta.y) > abs(delta.x)*5)
dir = ns;
else if (abs(delta.x) > abs(delta.y)*2)
dir = ew + ns + ew;
else if (abs(delta.y) > abs(delta.x)*2)
dir = ns + ns + ew;
else if (delta.x || delta.y)
dir = ns + ew;
else
dir = "***";
int dist = (int)sqrt((double)(delta.x*delta.x + delta.y*delta.y));
return stl_sprintf("%d away %s %+d", dist, dir.c_str(), delta.z);
}
static void printEquipped(Core *c, df::unit *unit, bool all) static void printEquipped(Core *c, df::unit *unit, bool all)
{ {
std::vector<inv_item> items; std::vector<inv_item> items;
@ -465,6 +588,12 @@ static void printEquipped(Core *c, df::unit *unit, bool all)
// Add to the right table // Add to the right table
int count = item->getStackSize(); int count = item->getStackSize();
if (is_weapon)
{
weapons[name] += count;
continue;
}
switch (iinfo.type) { switch (iinfo.type) {
case item_type::HELM: case item_type::HELM:
head[name] += count; head[name] += count;
@ -570,7 +699,7 @@ command_result adv_bodyswap (Core * c, std::vector <std::string> & parameters)
// Permanently re-link everything // Permanently re-link everything
if (permanent) if (permanent)
{ {
ui_advmode->player_id = new_nemesis->id; ui_advmode->player_id = linear_index(world->nemesis.all, new_nemesis);
// Flag 0 appears to be the 'active adventurer' flag, and // Flag 0 appears to be the 'active adventurer' flag, and
// the player_id field above seems to be computed using it // the player_id field above seems to be computed using it
@ -636,6 +765,67 @@ command_result adv_tools (Core * c, std::vector <std::string> & parameters)
return CR_OK; return CR_OK;
} }
else if (command == "metal-detector")
{
bool all = false, non_trader = false;
for (size_t i = 1; i < parameters.size(); i++)
{
if (parameters[i] == "all-types")
all = true;
else if (parameters[i] == "non-trader")
non_trader = true;
else
return CR_WRONG_USAGE;
}
auto *player = getPlayerNemesis(c, false);
if (!player)
return CR_FAILURE;
df::coord player_pos = player->unit->pos;
int total = 0;
std::map<df::coord,int> counts;
for (size_t i = 0; i < world->map.map_blocks.size(); i++)
{
df::map_block *block = world->map.map_blocks[i];
for (size_t j = 0; j < block->items.size(); j++)
{
df::item *item = df::item::find(block->items[j]);
if (!item)
continue;
int num = containsMetalItems(item, all, non_trader);
if (!num)
continue;
total += num;
counts[(item->pos - player_pos)/10] += num;
auto &designations = block->designation;
auto &dgn = designations[item->pos.x%16][item->pos.y%16];
dgn.bits.hidden = 0; // revealed
dgn.bits.pile = 1; // visible
}
}
joinCounts(counts);
c->con.print("%d items of metal merchandise found in the vicinity.\n", total);
for (auto it = counts.begin(); it != counts.end(); it++)
{
if (!it->second)
continue;
df::coord delta = it->first * 10;
c->con.print(" %s: %d\n", formatDirection(delta).c_str(), it->second);
}
return CR_OK;
}
else else
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }

@ -56,12 +56,12 @@ DFhackCExport command_result plugin_init ( Core * c, vector <PluginCommand> &com
)); ));
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"autodump-destroy-here", "Destroy items marked for dumping under cursor.", "autodump-destroy-here", "Destroy items marked for dumping under cursor.",
df_autodump_destroy_here, cursor_hotkey, df_autodump_destroy_here, Gui::cursor_hotkey,
" Identical to autodump destroy-here, but intended for use as keybinding.\n" " Identical to autodump destroy-here, but intended for use as keybinding.\n"
)); ));
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"autodump-destroy-item", "Destroy the selected item.", "autodump-destroy-item", "Destroy the selected item.",
df_autodump_destroy_item, any_item_hotkey, df_autodump_destroy_item, Gui::any_item_hotkey,
" Destroy the selected item. The item may be selected\n" " Destroy the selected item. The item may be selected\n"
" in the 'k' list, or inside a container. If called\n" " in the 'k' list, or inside a container. If called\n"
" again before the game is resumed, cancels destroy.\n" " again before the game is resumed, cancels destroy.\n"
@ -108,7 +108,6 @@ static command_result autodump_main(Core * c, vector <string> & parameters)
} }
DFHack::VersionInfo *mem = c->vinfo; DFHack::VersionInfo *mem = c->vinfo;
DFHack::Gui * Gui = c->getGui();
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); c->con.printerr("Map is not available!\n");
@ -124,7 +123,7 @@ static command_result autodump_main(Core * c, vector <string> & parameters)
DFCoord pos_cursor; DFCoord pos_cursor;
if(!destroy || here) if(!destroy || here)
{ {
if (!Gui->getCursorCoords(cx,cy,cz)) if (!Gui::getCursorCoords(cx,cy,cz))
{ {
c->con.printerr("Cursor position not found. Please enabled the cursor.\n"); c->con.printerr("Cursor position not found. Please enabled the cursor.\n");
return CR_FAILURE; return CR_FAILURE;
@ -307,7 +306,7 @@ command_result df_autodump_destroy_item(Core * c, vector <string> & parameters)
if (!parameters.empty()) if (!parameters.empty())
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
df::item *item = getSelectedItem(c); df::item *item = Gui::getSelectedItem(c);
if (!item) if (!item)
return CR_FAILURE; return CR_FAILURE;

@ -13,7 +13,6 @@
using std::vector; using std::vector;
using std::string; using std::string;
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using namespace df::enums; using namespace df::enums;
using df::global::world; using df::global::world;

@ -16,7 +16,6 @@
using std::vector; using std::vector;
using std::string; using std::string;
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using namespace df::enums; using namespace df::enums;
using df::global::world; using df::global::world;
@ -208,7 +207,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
)); ));
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"spotclean","Cleans map tile under cursor.", "spotclean","Cleans map tile under cursor.",
spotclean,cursor_hotkey spotclean,Gui::cursor_hotkey
)); ));
return CR_OK; return CR_OK;
} }

@ -21,7 +21,6 @@ using namespace std;
#include "df/world.h" #include "df/world.h"
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using namespace df::enums; using namespace df::enums;
using df::global::world; using df::global::world;

@ -10,7 +10,6 @@
using std::vector; using std::vector;
using std::string; using std::string;
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
command_result colonies (Core * c, vector <string> & parameters); command_result colonies (Core * c, vector <string> & parameters);

@ -12,7 +12,6 @@
using std::vector; using std::vector;
using std::string; using std::string;
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using namespace df::enums; using namespace df::enums;
using df::global::world; using df::global::world;

@ -39,7 +39,6 @@ command_result readFlag (Core * c, vector <string> & parameters)
{ {
c->Suspend(); c->Suspend();
Gui * Gui = c->getGui();
// init the map // init the map
if(!Maps::IsValid()) if(!Maps::IsValid())
{ {
@ -49,8 +48,7 @@ command_result readFlag (Core * c, vector <string> & parameters)
} }
int32_t cx, cy, cz; int32_t cx, cy, cz;
Gui->getCursorCoords(cx,cy,cz); if(!Gui::getCursorCoords(cx,cy,cz))
while(cx == -30000)
{ {
c->con.printerr("Cursor is not active.\n"); c->con.printerr("Cursor is not active.\n");
c->Resume(); c->Resume();
@ -106,7 +104,6 @@ command_result writeFlag (Core * c, vector <string> & parameters)
c->Suspend(); c->Suspend();
Gui * Gui = c->getGui();
// init the map // init the map
if(!Maps::IsValid()) if(!Maps::IsValid())
{ {
@ -116,8 +113,7 @@ command_result writeFlag (Core * c, vector <string> & parameters)
} }
int32_t cx, cy, cz; int32_t cx, cy, cz;
Gui->getCursorCoords(cx,cy,cz); if(!Gui::getCursorCoords(cx,cy,cz))
while(cx == -30000)
{ {
c->con.printerr("Cursor is not active.\n"); c->con.printerr("Cursor is not active.\n");
c->Resume(); c->Resume();

@ -24,7 +24,6 @@ using namespace std;
#include <df/creature_raw.h> #include <df/creature_raw.h>
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
command_result catsplosion (Core * c, std::vector <std::string> & parameters); command_result catsplosion (Core * c, std::vector <std::string> & parameters);

@ -9,7 +9,6 @@
using std::vector; using std::vector;
using std::string; using std::string;
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using namespace df::enums; using namespace df::enums;
using df::global::world; using df::global::world;

@ -15,7 +15,7 @@
using std::vector; using std::vector;
using std::string; using std::string;
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
//FIXME: possible race conditions with calling kittens from the IO thread and shutdown from Core. //FIXME: possible race conditions with calling kittens from the IO thread and shutdown from Core.
bool shutdown_flag = false; bool shutdown_flag = false;
bool final_flag = true; bool final_flag = true;
@ -70,19 +70,16 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
} }
if(trackmenu_flg) if(trackmenu_flg)
{ {
DFHack::Gui * g =c->getGui(); if (last_menu != df::global::ui->main.mode)
if (last_menu != *g->df_menu_state)
{ {
last_menu = *g->df_menu_state; last_menu = df::global::ui->main.mode;
c->con.print("Menu: %d\n",last_menu); c->con.print("Menu: %d\n",last_menu);
} }
} }
if(trackpos_flg) if(trackpos_flg)
{ {
DFHack::Gui * g =c->getGui();
g->Start();
int32_t desig_x, desig_y, desig_z; int32_t desig_x, desig_y, desig_z;
g->getDesignationCoords(desig_x,desig_y,desig_z); Gui::getDesignationCoords(desig_x,desig_y,desig_z);
if(desig_x != last_designation[0] || desig_y != last_designation[1] || desig_z != last_designation[2]) if(desig_x != last_designation[0] || desig_y != last_designation[1] || desig_z != last_designation[2])
{ {
last_designation[0] = desig_x; last_designation[0] = desig_x;
@ -91,7 +88,7 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
c->con.print("Designation: %d %d %d\n",desig_x, desig_y, desig_z); c->con.print("Designation: %d %d %d\n",desig_x, desig_y, desig_z);
} }
int mouse_x, mouse_y; int mouse_x, mouse_y;
g->getMousePos(mouse_x,mouse_y); Gui::getMousePos(mouse_x,mouse_y);
if(mouse_x != last_mouse[0] || mouse_y != last_mouse[1]) if(mouse_x != last_mouse[0] || mouse_y != last_mouse[1])
{ {
last_mouse[0] = mouse_x; last_mouse[0] = mouse_x;
@ -111,11 +108,10 @@ command_result trackmenu (Core * c, vector <string> & parameters)
} }
else else
{ {
DFHack::Gui * g =c->getGui(); if(df::global::ui)
if(g->df_menu_state)
{ {
trackmenu_flg = true; trackmenu_flg = true;
last_menu = *g->df_menu_state; last_menu = df::global::ui->main.mode;
c->con.print("Menu: %d\n",last_menu); c->con.print("Menu: %d\n",last_menu);
return CR_OK; return CR_OK;
} }
@ -150,6 +146,7 @@ command_result colormods (Core * c, vector <string> & parameters)
return CR_OK; return CR_OK;
} }
// FIXME: move cursor properly relative to view position
command_result zoom (Core * c, vector <string> & parameters) command_result zoom (Core * c, vector <string> & parameters)
{ {
if(parameters.size() < 3) if(parameters.size() < 3)
@ -159,12 +156,11 @@ command_result zoom (Core * c, vector <string> & parameters)
int z = atoi( parameters[2].c_str()); int z = atoi( parameters[2].c_str());
int xi, yi, zi; int xi, yi, zi;
CoreSuspender cs (c); CoreSuspender cs (c);
Gui * g = c->getGui(); if(Gui::getCursorCoords(xi, yi, zi))
if(g->getCursorCoords(xi, yi, zi))
{ {
g->setCursorCoords(x,y,z); Gui::setCursorCoords(x,y,z);
} }
g->setViewCoords(x,y,z); Gui::setViewCoords(x,y,z);
} }
command_result ktimer (Core * c, vector <string> & parameters) command_result ktimer (Core * c, vector <string> & parameters)

@ -13,7 +13,6 @@
#include "TileTypes.h" #include "TileTypes.h"
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using namespace df::enums; using namespace df::enums;
using df::global::world; using df::global::world;

@ -20,9 +20,6 @@ using namespace std;
#include <df/unit_soul.h> #include <df/unit_soul.h>
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using namespace DFHack::Simple;
using df::global::ui; using df::global::ui;
using df::global::world; using df::global::world;

@ -40,7 +40,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
{ {
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"filltraffic","Flood-fill with selected traffic designation from cursor", "filltraffic","Flood-fill with selected traffic designation from cursor",
filltraffic, cursor_hotkey, filltraffic, Gui::cursor_hotkey,
" Flood-fill selected traffic type from the cursor.\n" " Flood-fill selected traffic type from the cursor.\n"
"Traffic Type Codes:\n" "Traffic Type Codes:\n"
" H: High Traffic\n" " H: High Traffic\n"
@ -115,7 +115,6 @@ command_result filltraffic(Core * c, std::vector<std::string> & params)
} }
} }
Gui * Gui = c->getGui();
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); c->con.printerr("Map is not available!\n");
@ -126,7 +125,7 @@ command_result filltraffic(Core * c, std::vector<std::string> & params)
Maps::getSize(x_max,y_max,z_max); Maps::getSize(x_max,y_max,z_max);
uint32_t tx_max = x_max * 16; uint32_t tx_max = x_max * 16;
uint32_t ty_max = y_max * 16; uint32_t ty_max = y_max * 16;
Gui->getCursorCoords(cx,cy,cz); Gui::getCursorCoords(cx,cy,cz);
while(cx == -30000) while(cx == -30000)
{ {
c->con.printerr("Cursor is not active.\n"); c->con.printerr("Cursor is not active.\n");
@ -276,7 +275,6 @@ command_result setAllMatching(Core * c, checkTile checkProc,
//Initialization. //Initialization.
CoreSuspender suspend(c); CoreSuspender suspend(c);
Gui * Gui = c->getGui();
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); c->con.printerr("Map is not available!\n");

@ -17,7 +17,6 @@
using std::vector; using std::vector;
using std::string; using std::string;
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using namespace df::enums; using namespace df::enums;
using df::global::world; using df::global::world;

@ -29,7 +29,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
{ {
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"follow", "Follow the selected unit until camera control is released", "follow", "Follow the selected unit until camera control is released",
follow, view_unit_hotkey, follow, Gui::view_unit_hotkey,
" Select a unit and run this plugin to make the camera follow it. Moving the camera yourself deactivates the plugin.\n" " Select a unit and run this plugin to make the camera follow it. Moving the camera yourself deactivates the plugin.\n"
)); ));
followedUnit = 0; followedUnit = 0;
@ -69,14 +69,15 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
df::coord &unitPos = followedUnit->pos; df::coord &unitPos = followedUnit->pos;
Gui *gui = c->getGui(); //Get all of the relevant data for determining the size of the map on the window //Get all of the relevant data for determining the size of the map on the window
int32_t x,y,z,w,h,c_x,c_y,c_z; int32_t x,y,z,w,h,c_x,c_y,c_z;
uint8_t menu_width, area_map_width; uint8_t menu_width, area_map_width;
gui->getViewCoords(x,y,z); Gui::getViewCoords(x,y,z);
gui->getWindowSize(w,h); Gui::getWindowSize(w,h);
gui->getMenuWidth(menu_width, area_map_width); Gui::getMenuWidth(menu_width, area_map_width);
gui->getCursorCoords(c_x,c_y,c_z); Gui::getCursorCoords(c_x,c_y,c_z);
// FIXME: is this really needed? does it ever evaluate to 'true'?
if (c_x != -30000 && menu_width == 3) menu_width = 2; //Presence of the cursor means that there's actually a width-2 menu open if (c_x != -30000 && menu_width == 3) menu_width = 2; //Presence of the cursor means that there's actually a width-2 menu open
h -= 2; //account for vertical borders h -= 2; //account for vertical borders
@ -103,20 +104,26 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
return CR_OK; return CR_OK;
} }
//Get map size in tiles so we can prevent the camera from going off the edge
uint32_t x_max, y_max, z_max; uint32_t x_max, y_max, z_max;
Simple::Maps::getSize(x_max, y_max, z_max); //Get map size in tiles so we can prevent the camera from going off the edge Maps::getSize(x_max, y_max, z_max);
x_max *= 16; x_max *= 16;
y_max *= 16; y_max *= 16;
x = unitPos.x + w/2 >= x_max ? x_max-w : (unitPos.x >= w/2 ? unitPos.x - w/2 : 0); //Calculate a new screen position centered on the selected unit //Calculate a new screen position centered on the selected unit
x = unitPos.x + w/2 >= x_max ? x_max-w : (unitPos.x >= w/2 ? unitPos.x - w/2 : 0);
y = unitPos.y + h/2 >= y_max ? y_max-h : (unitPos.y >= h/2 ? unitPos.y - h/2 : 0); y = unitPos.y + h/2 >= y_max ? y_max-h : (unitPos.y >= h/2 ? unitPos.y - h/2 : 0);
z = unitPos.z; z = unitPos.z;
gui->setViewCoords(x, y, z); //Set the new screen position! //Set the new screen position!
Gui::setViewCoords(x, y, z);
if (c_x != -30000 && !world->ReadPauseState()) gui->setCursorCoords(c_x - (prevX-x), c_y - (prevY-y), z); //If, for some reason, the cursor is active and the screen is still moving, move the cursor along with the screen //If, for some reason, the cursor is active and the screen is still moving, move the cursor along with the screen
if (c_x != -30000 && !world->ReadPauseState())
Gui::setCursorCoords(c_x - (prevX-x), c_y - (prevY-y), z);
prevX = x; //Save this round's stuff for next time so we can monitor for changes made by the user //Save this round's stuff for next time so we can monitor for changes made by the user
prevX = x;
prevY = y; prevY = y;
prevZ = z; prevZ = z;
prevMenuWidth = menu_width; prevMenuWidth = menu_width;
@ -136,7 +143,7 @@ command_result follow (Core * c, std::vector <std::string> & parameters)
c->con.print("No longer following previously selected unit.\n"); c->con.print("No longer following previously selected unit.\n");
followedUnit = 0; followedUnit = 0;
} }
followedUnit = getSelectedUnit(c); followedUnit = Gui::getSelectedUnit(c);
if (followedUnit) if (followedUnit)
{ {
std::ostringstream ss; std::ostringstream ss;

@ -23,9 +23,9 @@ DFhackCExport command_result plugin_init (Core *c, std::vector <PluginCommand> &
{ {
if (d_init) { if (d_init) {
commands.push_back(PluginCommand("twaterlvl", "Toggle display of water/magma depth.", commands.push_back(PluginCommand("twaterlvl", "Toggle display of water/magma depth.",
twaterlvl, dwarfmode_hotkey)); twaterlvl, Gui::dwarfmode_hotkey));
commands.push_back(PluginCommand("tidlers", "Toggle display of idlers.", commands.push_back(PluginCommand("tidlers", "Toggle display of idlers.",
tidlers, dwarfmode_hotkey)); tidlers, Gui::dwarfmode_hotkey));
} }
std::cerr << "d_init: " << sizeof(df::d_init) << endl; std::cerr << "d_init: " << sizeof(df::d_init) << endl;
return CR_OK; return CR_OK;

@ -89,7 +89,7 @@ DFhackCExport command_result plugin_init (Core *c, std::vector <PluginCommand> &
commands.push_back( commands.push_back(
PluginCommand( PluginCommand(
"job-duplicate", "Duplicate the selected job in a workshop.", "job-duplicate", "Duplicate the selected job in a workshop.",
job_duplicate, workshop_job_hotkey, job_duplicate, Gui::workshop_job_hotkey,
" - In 'q' mode, when a job is highlighted within a workshop\n" " - In 'q' mode, when a job is highlighted within a workshop\n"
" or furnace building, instantly duplicates the job.\n" " or furnace building, instantly duplicates the job.\n"
) )
@ -108,15 +108,15 @@ DFhackCExport command_result plugin_shutdown ( Core * c )
static bool job_material_hotkey(Core *c, df::viewscreen *top) static bool job_material_hotkey(Core *c, df::viewscreen *top)
{ {
return workshop_job_hotkey(c, top) || return Gui::workshop_job_hotkey(c, top) ||
build_selector_hotkey(c, top); Gui::build_selector_hotkey(c, top);
} }
/* job-material implementation */ /* job-material implementation */
static command_result job_material_in_job(Core *c, MaterialInfo &new_mat) static command_result job_material_in_job(Core *c, MaterialInfo &new_mat)
{ {
df::job *job = getSelectedWorkshopJob(c); df::job *job = Gui::getSelectedWorkshopJob(c);
if (!job) if (!job)
return CR_FAILURE; return CR_FAILURE;
@ -268,7 +268,7 @@ static command_result job_duplicate(Core * c, vector <string> & parameters)
if (!parameters.empty()) if (!parameters.empty())
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
df::job *job = getSelectedWorkshopJob(c); df::job *job = Gui::getSelectedWorkshopJob(c);
if (!job) if (!job)
return CR_FAILURE; return CR_FAILURE;
@ -320,14 +320,14 @@ static command_result job_cmd(Core * c, vector <string> & parameters)
std::string cmd = (parameters.empty() ? "query" : parameters[0]); std::string cmd = (parameters.empty() ? "query" : parameters[0]);
if (cmd == "query" || cmd == "list") if (cmd == "query" || cmd == "list")
{ {
df::job *job = getSelectedJob(c); df::job *job = Gui::getSelectedJob(c);
if (!job) if (!job)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
if (cmd == "query") { if (cmd == "query") {
printJobDetails(c, job); printJobDetails(c, job);
} else { } else {
if (!workshop_job_hotkey(c, c->getTopViewscreen())) if (!Gui::workshop_job_hotkey(c, c->getTopViewscreen()))
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
df::building *selected = world->selected_building; df::building *selected = world->selected_building;
@ -340,7 +340,7 @@ static command_result job_cmd(Core * c, vector <string> & parameters)
if (parameters.size() != 3) if (parameters.size() != 3)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
df::job *job = getSelectedJob(c); df::job *job = Gui::getSelectedJob(c);
df::job_item *item = getJobItem(c, job, parameters[1]); df::job_item *item = getJobItem(c, job, parameters[1]);
if (!item) if (!item)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
@ -384,7 +384,7 @@ static command_result job_cmd(Core * c, vector <string> & parameters)
if (parameters.size() != 3) if (parameters.size() != 3)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
df::job *job = getSelectedJob(c); df::job *job = Gui::getSelectedJob(c);
df::job_item *item = getJobItem(c, job, parameters[1]); df::job_item *item = getJobItem(c, job, parameters[1]);
if (!item) if (!item)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;

@ -224,7 +224,6 @@ command_result df_liquids (Core * c, vector <string> & parameters)
{ {
int32_t x,y,z; int32_t x,y,z;
DFHack::Gui * Position;
for(size_t i = 0; i < parameters.size();i++) for(size_t i = 0; i < parameters.size();i++)
{ {
if(parameters[i] == "help" || parameters[i] == "?") if(parameters[i] == "help" || parameters[i] == "?")
@ -429,7 +428,6 @@ command_result df_liquids (Core * c, vector <string> & parameters)
else if(command.empty()) else if(command.empty())
{ {
CoreSuspender suspend(c); CoreSuspender suspend(c);
Position = c->getGui();
do do
{ {
if (!Maps::IsValid()) if (!Maps::IsValid())
@ -437,7 +435,7 @@ command_result df_liquids (Core * c, vector <string> & parameters)
c->con << "Can't see any DF map loaded." << endl; c->con << "Can't see any DF map loaded." << endl;
break;; break;;
} }
if(!Position->getCursorCoords(x,y,z)) if(!Gui::getCursorCoords(x,y,z))
{ {
c->con << "Can't get cursor coords! Make sure you have a cursor active in DF." << endl; c->con << "Can't get cursor coords! Make sure you have a cursor active in DF." << endl;
break; break;

@ -102,7 +102,6 @@ static command_result immolations (Core * c, do_what what, bool shrubs, bool tre
c->con.printerr("Map is not available!\n"); c->con.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
Gui * Gui = c->getGui();
uint32_t x_max, y_max, z_max; uint32_t x_max, y_max, z_max;
Maps::getSize(x_max, y_max, z_max); Maps::getSize(x_max, y_max, z_max);
MapExtras::MapCache map; MapExtras::MapCache map;
@ -125,7 +124,7 @@ static command_result immolations (Core * c, do_what what, bool shrubs, bool tre
else else
{ {
int32_t x,y,z; int32_t x,y,z;
if(Gui->getCursorCoords(x,y,z)) if(Gui::getCursorCoords(x,y,z))
{ {
vector<df::plant *> * alltrees; vector<df::plant *> * alltrees;
if(Maps::ReadVegetation(x/16,y/16,z,alltrees)) if(Maps::ReadVegetation(x/16,y/16,z,alltrees))
@ -205,9 +204,8 @@ command_result df_grow (Core * c, vector <string> & parameters)
return CR_FAILURE; return CR_FAILURE;
} }
MapExtras::MapCache map; MapExtras::MapCache map;
Gui *Gui = c->getGui();
int32_t x,y,z; int32_t x,y,z;
if(Gui->getCursorCoords(x,y,z)) if(Gui::getCursorCoords(x,y,z))
{ {
vector<df::plant *> * alltrees; vector<df::plant *> * alltrees;
if(Maps::ReadVegetation(x/16,y/16,z,alltrees)) if(Maps::ReadVegetation(x/16,y/16,z,alltrees))

@ -19,20 +19,23 @@ using namespace std;
#include "modules/Gui.h" #include "modules/Gui.h"
#include "modules/Materials.h" #include "modules/Materials.h"
#include "modules/MapCache.h" #include "modules/MapCache.h"
#include "modules/Buildings.h"
#include "MiscUtils.h" #include "MiscUtils.h"
#include "df/world.h" #include "df/world.h"
#include "df/world_raws.h"
#include "df/building_def.h"
using std::vector; using std::vector;
using std::string; using std::string;
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using namespace df::enums; using namespace df::enums;
using df::global::world; using df::global::world;
using df::global::cursor;
command_result df_probe (Core * c, vector <string> & parameters); command_result df_probe (Core * c, vector <string> & parameters);
command_result df_cprobe (Core * c, vector <string> & parameters); command_result df_cprobe (Core * c, vector <string> & parameters);
command_result df_bprobe (Core * c, vector <string> & parameters);
DFHACK_PLUGIN("probe"); DFHACK_PLUGIN("probe");
@ -45,6 +48,9 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
commands.push_back(PluginCommand("cprobe", commands.push_back(PluginCommand("cprobe",
"A creature probe", "A creature probe",
df_cprobe)); df_cprobe));
commands.push_back(PluginCommand("bprobe",
"A simple building probe",
df_bprobe));
return CR_OK; return CR_OK;
} }
@ -57,9 +63,8 @@ command_result df_cprobe (Core * c, vector <string> & parameters)
{ {
Console & con = c->con; Console & con = c->con;
CoreSuspender suspend(c); CoreSuspender suspend(c);
DFHack::Gui *Gui = c->getGui();
int32_t cursorX, cursorY, cursorZ; int32_t cursorX, cursorY, cursorZ;
Gui->getCursorCoords(cursorX,cursorY,cursorZ); Gui::getCursorCoords(cursorX,cursorY,cursorZ);
if(cursorX == -30000) if(cursorX == -30000)
{ {
con.printerr("No cursor; place cursor over creature to probe.\n"); con.printerr("No cursor; place cursor over creature to probe.\n");
@ -94,7 +99,6 @@ command_result df_probe (Core * c, vector <string> & parameters)
CoreSuspender suspend(c); CoreSuspender suspend(c);
DFHack::Gui *Gui = c->getGui();
DFHack::Materials *Materials = c->getMaterials(); DFHack::Materials *Materials = c->getMaterials();
DFHack::VersionInfo* mem = c->vinfo; DFHack::VersionInfo* mem = c->vinfo;
std::vector<t_matglossInorganic> inorganic; std::vector<t_matglossInorganic> inorganic;
@ -111,7 +115,7 @@ command_result df_probe (Core * c, vector <string> & parameters)
Maps::getPosition(regionX,regionY,regionZ); Maps::getPosition(regionX,regionY,regionZ);
int32_t cursorX, cursorY, cursorZ; int32_t cursorX, cursorY, cursorZ;
Gui->getCursorCoords(cursorX,cursorY,cursorZ); Gui::getCursorCoords(cursorX,cursorY,cursorZ);
if(cursorX == -30000) if(cursorX == -30000)
{ {
con.printerr("No cursor; place cursor over tile to probe.\n"); con.printerr("No cursor; place cursor over tile to probe.\n");
@ -273,3 +277,61 @@ command_result df_probe (Core * c, vector <string> & parameters)
con << std::endl; con << std::endl;
return CR_OK; return CR_OK;
} }
command_result df_bprobe (Core * c, vector <string> & parameters)
{
CoreSuspender suspend(c);
if(cursor->x == -30000)
{
c->con.printerr("No cursor; place cursor over tile to probe.\n");
return CR_FAILURE;
}
for (size_t i = 0; i < world->buildings.all.size(); i++)
{
Buildings::t_building building;
if (!Buildings::Read(i, building))
continue;
if (!(building.x1 <= cursor->x && cursor->x <= building.x2 &&
building.y1 <= cursor->y && cursor->y <= building.y2 &&
building.z == cursor->z))
continue;
string name;
building.origin->getName(&name);
c->con.print("Building %i - \"%s\" - type %s", building.origin->id, name.c_str(), ENUM_KEY_STR(building_type, building.type));
switch (building.type)
{
case building_type::Furnace:
c->con.print(", subtype %s", ENUM_KEY_STR(furnace_type, building.furnace_type));
if (building.furnace_type == furnace_type::Custom)
c->con.print(", custom type %i (%s)", building.custom_type, world->raws.buildings.all[building.custom_type]->code.c_str());
break;
case building_type::Workshop:
c->con.print(", subtype %s", ENUM_KEY_STR(workshop_type, building.workshop_type));
if (building.workshop_type == workshop_type::Custom)
c->con.print(", custom type %i (%s)", building.custom_type, world->raws.buildings.all[building.custom_type]->code.c_str());
break;
case building_type::Construction:
c->con.print(", subtype %s", ENUM_KEY_STR(construction_type, building.construction_type));
break;
case building_type::Shop:
c->con.print(", subtype %s", ENUM_KEY_STR(shop_type, building.shop_type));
break;
case building_type::SiegeEngine:
c->con.print(", subtype %s", ENUM_KEY_STR(siegeengine_type, building.siegeengine_type));
break;
case building_type::Trap:
c->con.print(", subtype %s", ENUM_KEY_STR(trap_type, building.trap_type));
break;
default:
if (building.subtype != -1)
c->con.print(", subtype %i", building.subtype);
break;
}
c->con.print("\n");
}
return CR_OK;
}

@ -76,6 +76,18 @@ bool operator>(const matdata & q1, const matdata & q2)
return q1.count > q2.count; return q1.count > q2.count;
} }
template<typename _Tp = matdata >
struct shallower : public binary_function<_Tp, _Tp, bool>
{
bool operator()(const _Tp& top, const _Tp& bottom) const
{
float topavg = (top.lower_z + top.upper_z)/2.0f;
float btmavg = (bottom.lower_z + bottom.upper_z)/2.0f;
return topavg > btmavg;
}
};
typedef std::map<int16_t, matdata> MatMap; typedef std::map<int16_t, matdata> MatMap;
typedef std::vector< pair<int16_t, matdata> > MatSorter; typedef std::vector< pair<int16_t, matdata> > MatSorter;
@ -90,10 +102,10 @@ template<template <typename> class P = std::greater >
struct compare_pair_second struct compare_pair_second
{ {
template<class T1, class T2> template<class T1, class T2>
bool operator()(const std::pair<T1, T2>& left, const std::pair<T1, T2>& right) bool operator()(const std::pair<T1, T2>& left, const std::pair<T1, T2>& right)
{ {
return P<T2>()(left.second, right.second); return P<T2>()(left.second, right.second);
} }
}; };
static void printMatdata(DFHack::Console & con, const matdata &data) static void printMatdata(DFHack::Console & con, const matdata &data)
@ -116,7 +128,7 @@ static int getValue(const df::plant_raw &info)
return info.value; return info.value;
} }
template <typename T> template <typename T, template <typename> class P>
void printMats(DFHack::Console & con, MatMap &mat, std::vector<T*> &materials, bool show_value) void printMats(DFHack::Console & con, MatMap &mat, std::vector<T*> &materials, bool show_value)
{ {
unsigned int total = 0; unsigned int total = 0;
@ -126,7 +138,7 @@ void printMats(DFHack::Console & con, MatMap &mat, std::vector<T*> &materials, b
sorting_vector.push_back(*it); sorting_vector.push_back(*it);
} }
std::sort(sorting_vector.begin(), sorting_vector.end(), std::sort(sorting_vector.begin(), sorting_vector.end(),
compare_pair_second<>()); compare_pair_second<P>());
for (MatSorter::const_iterator it = sorting_vector.begin(); for (MatSorter::const_iterator it = sorting_vector.begin();
it != sorting_vector.end(); ++it) it != sorting_vector.end(); ++it)
{ {
@ -168,13 +180,13 @@ void printVeins(DFHack::Console & con, MatMap &mat_map,
} }
con << "Ores:" << std::endl; con << "Ores:" << std::endl;
printMats(con, ores, world->raws.inorganics, show_value); printMats<df::inorganic_raw, std::greater>(con, ores, world->raws.inorganics, show_value);
con << "Gems:" << std::endl; con << "Gems:" << std::endl;
printMats(con, gems, world->raws.inorganics, show_value); printMats<df::inorganic_raw, std::greater>(con, gems, world->raws.inorganics, show_value);
con << "Other vein stone:" << std::endl; con << "Other vein stone:" << std::endl;
printMats(con, rest, world->raws.inorganics, show_value); printMats<df::inorganic_raw, std::greater>(con, rest, world->raws.inorganics, show_value);
} }
command_result prospector (Core * c, vector <string> & parameters); command_result prospector (Core * c, vector <string> & parameters);
@ -329,7 +341,7 @@ static command_result embark_prospector(DFHack::Core *c, df::viewscreen_choose_s
// Print the report // Print the report
c->con << "Layer materials:" << std::endl; c->con << "Layer materials:" << std::endl;
printMats(c->con, layerMats, world->raws.inorganics, showValue); printMats<df::inorganic_raw, shallower>(c->con, layerMats, world->raws.inorganics, showValue);
if (showHidden) { if (showHidden) {
DFHack::Materials *mats = c->getMaterials(); DFHack::Materials *mats = c->getMaterials();
@ -588,16 +600,16 @@ command_result prospector (DFHack::Core * c, vector <string> & parameters)
} }
con << std::endl << "Layer materials:" << std::endl; con << std::endl << "Layer materials:" << std::endl;
printMats(con, layerMats, world->raws.inorganics, showValue); printMats<df::inorganic_raw, shallower>(con, layerMats, world->raws.inorganics, showValue);
printVeins(con, veinMats, mats, showValue); printVeins(con, veinMats, mats, showValue);
if (showPlants) if (showPlants)
{ {
con << "Shrubs:" << std::endl; con << "Shrubs:" << std::endl;
printMats(con, plantMats, world->raws.plants.all, showValue); printMats<df::plant_raw, std::greater>(con, plantMats, world->raws.plants.all, showValue);
con << "Wood in trees:" << std::endl; con << "Wood in trees:" << std::endl;
printMats(con, treeMats, world->raws.plants.all, showValue); printMats<df::plant_raw, std::greater>(con, treeMats, world->raws.plants.all, showValue);
} }
if (hasAquifer) if (hasAquifer)

@ -120,7 +120,7 @@ static command_result rename(Core * c, vector <string> &parameters)
if (parameters.size() != 2) if (parameters.size() != 2)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
df::unit *unit = getSelectedUnit(c); df::unit *unit = Gui::getSelectedUnit(c);
if (!unit) if (!unit)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
@ -153,7 +153,7 @@ static command_result rename(Core * c, vector <string> &parameters)
if (parameters.size() != 2) if (parameters.size() != 2)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
df::unit *unit = getSelectedUnit(c); df::unit *unit = Gui::getSelectedUnit(c);
if (!unit) if (!unit)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;

@ -120,6 +120,26 @@ command_result nopause (Core * c, std::vector <std::string> & parameters)
return CR_OK; return CR_OK;
} }
void revealAdventure(DFHack::Core * c)
{
for (size_t i = 0; i < world->map.map_blocks.size(); i++)
{
df::map_block *block = world->map.map_blocks[i];
// in 'no-hell'/'safe' mode, don't reveal blocks with hell and adamantine
if (!isSafe(block->map_pos))
continue;
DFHack::designations40d & designations = block->designation;
// for each tile in block
for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
{
// set to revealed
designations[x][y].bits.hidden = 0;
// and visible
designations[x][y].bits.pile = 1;
}
}
c->con.print("Local map revealed.\n");
}
command_result reveal(DFHack::Core * c, std::vector<std::string> & params) command_result reveal(DFHack::Core * c, std::vector<std::string> & params)
{ {
@ -157,16 +177,21 @@ command_result reveal(DFHack::Core * c, std::vector<std::string> & params)
CoreSuspender suspend(c); CoreSuspender suspend(c);
DFHack::World *World =c->getWorld(); DFHack::World *World =c->getWorld();
if (!Maps::IsValid())
{
c->con.printerr("Map is not available!\n");
return CR_FAILURE;
}
t_gamemodes gm; t_gamemodes gm;
World->ReadGameMode(gm); World->ReadGameMode(gm);
if(gm.g_mode != GAMEMODE_DWARF) if(gm.g_mode == GAMEMODE_ADVENTURE)
{ {
con.printerr("Only in fortress mode.\n"); revealAdventure(c);
return CR_FAILURE; return CR_OK;
} }
if (!Maps::IsValid()) if(gm.g_mode != GAMEMODE_DWARF)
{ {
c->con.printerr("Map is not available!\n"); con.printerr("Only in fortress mode.\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -231,6 +256,11 @@ command_result unreveal(DFHack::Core * c, std::vector<std::string> & params)
CoreSuspender suspend(c); CoreSuspender suspend(c);
DFHack::World *World =c->getWorld(); DFHack::World *World =c->getWorld();
if (!Maps::IsValid())
{
c->con.printerr("Map is not available!\n");
return CR_FAILURE;
}
t_gamemodes gm; t_gamemodes gm;
World->ReadGameMode(gm); World->ReadGameMode(gm);
if(gm.g_mode != GAMEMODE_DWARF) if(gm.g_mode != GAMEMODE_DWARF)
@ -238,11 +268,6 @@ command_result unreveal(DFHack::Core * c, std::vector<std::string> & params)
con.printerr("Only in fortress mode.\n"); con.printerr("Only in fortress mode.\n");
return CR_FAILURE; return CR_FAILURE;
} }
if (!Maps::IsValid())
{
c->con.printerr("Map is not available!\n");
return CR_FAILURE;
}
// Sanity check: map size // Sanity check: map size
uint32_t x_max_b, y_max_b, z_max_b; uint32_t x_max_b, y_max_b, z_max_b;
@ -303,7 +328,6 @@ command_result revflood(DFHack::Core * c, std::vector<std::string> & params)
} }
CoreSuspender suspend(c); CoreSuspender suspend(c);
uint32_t x_max,y_max,z_max; uint32_t x_max,y_max,z_max;
Gui * Gui = c->getGui();
World * World = c->getWorld(); World * World = c->getWorld();
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
@ -327,7 +351,7 @@ command_result revflood(DFHack::Core * c, std::vector<std::string> & params)
uint32_t tx_max = x_max * 16; uint32_t tx_max = x_max * 16;
uint32_t ty_max = y_max * 16; uint32_t ty_max = y_max * 16;
Gui->getCursorCoords(cx,cy,cz); Gui::getCursorCoords(cx,cy,cz);
if(cx == -30000) if(cx == -30000)
{ {
c->con.printerr("Cursor is not active. Point the cursor at some empty space you want to be unhidden.\n"); c->con.printerr("Cursor is not active. Point the cursor at some empty space you want to be unhidden.\n");

@ -18,7 +18,6 @@
using namespace std; using namespace std;
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using namespace df::enums; using namespace df::enums;
using df::global::world; using df::global::world;

@ -22,7 +22,6 @@
using std::string; using std::string;
using std::vector; using std::vector;
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using namespace df::enums; using namespace df::enums;
using df::global::world; using df::global::world;

@ -56,7 +56,7 @@ static bool copystock_guard(Core *c, df::viewscreen *top)
{ {
using namespace ui_sidebar_mode; using namespace ui_sidebar_mode;
if (!dwarfmode_hotkey(c,top)) if (!Gui::dwarfmode_hotkey(c,top))
return false; return false;
switch (ui->main.mode) { switch (ui->main.mode) {

@ -1 +1 @@
Subproject commit 58147c3138cddc2e732dd537ca8a78782f196f88 Subproject commit 34183f96b86394895975fb59ae3c4673cd78f502

@ -656,7 +656,6 @@ command_result df_tiletypes (Core * c, vector <string> & parameters)
uint32_t x_max = 0, y_max = 0, z_max = 0; uint32_t x_max = 0, y_max = 0, z_max = 0;
int32_t x = 0, y = 0, z = 0; int32_t x = 0, y = 0, z = 0;
DFHack::Gui *gui;
for(size_t i = 0; i < parameters.size();i++) for(size_t i = 0; i < parameters.size();i++)
{ {
if(parameters[i] == "help" || parameters[i] == "?") if(parameters[i] == "help" || parameters[i] == "?")
@ -769,7 +768,6 @@ command_result df_tiletypes (Core * c, vector <string> & parameters)
} }
CoreSuspender suspend(c); CoreSuspender suspend(c);
gui = c->getGui();
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); c->con.printerr("Map is not available!\n");
@ -777,7 +775,7 @@ command_result df_tiletypes (Core * c, vector <string> & parameters)
} }
Maps::getSize(x_max, y_max, z_max); Maps::getSize(x_max, y_max, z_max);
if (!(gui->Start() && gui->getCursorCoords(x,y,z))) if (!Gui::getCursorCoords(x,y,z))
{ {
c->con.printerr("Can't get cursor coords! Make sure you have a cursor active in DF.\n"); c->con.printerr("Can't get cursor coords! Make sure you have a cursor active in DF.\n");
return CR_FAILURE; return CR_FAILURE;
@ -798,7 +796,7 @@ command_result df_tiletypes (Core * c, vector <string> & parameters)
|| (filter.material > -1 && filter.material != tileMaterial(source)) || (filter.material > -1 && filter.material != tileMaterial(source))
|| (filter.special > -1 && filter.special != tileSpecial(source)) || (filter.special > -1 && filter.special != tileSpecial(source))
|| (filter.variant > -1 && filter.variant != tileVariant(source)) || (filter.variant > -1 && filter.variant != tileVariant(source))
|| (filter.dig > -1 && (filter.dig != 0) != (des.bits.dig != tile_dig_designation::No)) || (filter.dig > -1 && (filter.dig != 0) != (des.bits.dig != tile_dig_designation::No))
) )
{ {
continue; continue;

@ -14,7 +14,6 @@
#include "TileTypes.h" #include "TileTypes.h"
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using namespace df::enums; using namespace df::enums;
using df::global::world; using df::global::world;

@ -29,13 +29,13 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
{ {
commands.clear(); commands.clear();
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"vdig","Dig a whole vein.",vdig,cursor_hotkey, "vdig","Dig a whole vein.",vdig,Gui::cursor_hotkey,
" Designates a whole vein under the cursor for digging.\n" " Designates a whole vein under the cursor for digging.\n"
"Options:\n" "Options:\n"
" x - follow veins through z-levels with stairs.\n" " x - follow veins through z-levels with stairs.\n"
)); ));
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"vdigx","Dig a whole vein, following through z-levels.",vdigx,cursor_hotkey, "vdigx","Dig a whole vein, following through z-levels.",vdigx,Gui::cursor_hotkey,
" Designates a whole vein under the cursor for digging.\n" " Designates a whole vein under the cursor for digging.\n"
" Also follows the vein between z-levels with stairs, like 'vdig x' would.\n" " Also follows the vein between z-levels with stairs, like 'vdig x' would.\n"
)); ));
@ -273,7 +273,6 @@ command_result digcircle (Core * c, vector <string> & parameters)
} }
int32_t cx, cy, cz; int32_t cx, cy, cz;
CoreSuspender suspend(c); CoreSuspender suspend(c);
Gui * gui = c->getGui();
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); c->con.printerr("Map is not available!\n");
@ -284,7 +283,7 @@ command_result digcircle (Core * c, vector <string> & parameters)
Maps::getSize(x_max,y_max,z_max); Maps::getSize(x_max,y_max,z_max);
MapExtras::MapCache MCache; MapExtras::MapCache MCache;
if(!gui->getCursorCoords(cx,cy,cz) || cx == -30000) if(!Gui::getCursorCoords(cx,cy,cz) || cx == -30000)
{ {
c->con.printerr("Can't get the cursor coords...\n"); c->con.printerr("Can't get the cursor coords...\n");
return CR_FAILURE; return CR_FAILURE;
@ -848,7 +847,6 @@ command_result expdig (Core * c, vector <string> & parameters)
return CR_OK; return CR_OK;
} }
CoreSuspender suspend(c); CoreSuspender suspend(c);
Gui * gui = c->getGui();
uint32_t x_max, y_max, z_max; uint32_t x_max, y_max, z_max;
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
@ -857,7 +855,7 @@ command_result expdig (Core * c, vector <string> & parameters)
} }
Maps::getSize(x_max,y_max,z_max); Maps::getSize(x_max,y_max,z_max);
int32_t xzzz,yzzz,z_level; int32_t xzzz,yzzz,z_level;
if(!gui->getViewCoords(xzzz,yzzz,z_level)) if(!Gui::getViewCoords(xzzz,yzzz,z_level))
{ {
c->con.printerr("Can't get view coords...\n"); c->con.printerr("Can't get view coords...\n");
return CR_FAILURE; return CR_FAILURE;
@ -974,7 +972,6 @@ command_result vdig (Core * c, vector <string> & parameters)
Console & con = c->con; Console & con = c->con;
DFHack::Gui * Gui = c->getGui();
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); c->con.printerr("Map is not available!\n");
@ -985,7 +982,7 @@ command_result vdig (Core * c, vector <string> & parameters)
Maps::getSize(x_max,y_max,z_max); Maps::getSize(x_max,y_max,z_max);
uint32_t tx_max = x_max * 16; uint32_t tx_max = x_max * 16;
uint32_t ty_max = y_max * 16; uint32_t ty_max = y_max * 16;
Gui->getCursorCoords(cx,cy,cz); Gui::getCursorCoords(cx,cy,cz);
while(cx == -30000) while(cx == -30000)
{ {
con.printerr("Cursor is not active. Point the cursor at a vein.\n"); con.printerr("Cursor is not active. Point the cursor at a vein.\n");

@ -1232,15 +1232,15 @@ static void update_jobs_by_constraints(Core *c)
if (is_running != ct->is_active) if (is_running != ct->is_active)
{ {
if (is_running && ct->request_resume) if (is_running && ct->request_resume)
showAnnouncement("Resuming production: " + info, 2, false); Gui::showAnnouncement("Resuming production: " + info, 2, false);
else if (!is_running && !ct->request_resume) else if (!is_running && !ct->request_resume)
showAnnouncement("Stopping production: " + info, 3, false); Gui::showAnnouncement("Stopping production: " + info, 3, false);
} }
if (ct->request_resume && !is_running) if (ct->request_resume && !is_running)
{ {
if (!ct->cant_resume_reported) if (!ct->cant_resume_reported)
showAnnouncement("Cannot produce: " + info, 6, true); Gui::showAnnouncement("Cannot produce: " + info, 6, true);
ct->cant_resume_reported = true; ct->cant_resume_reported = true;
} }
else else
@ -1415,11 +1415,11 @@ static command_result workflow_cmd(Core *c, vector <string> & parameters)
df::building *workshop = NULL; df::building *workshop = NULL;
df::job *job = NULL; df::job *job = NULL;
if (dwarfmode_hotkey(c, c->getTopViewscreen()) && if (Gui::dwarfmode_hotkey(c, c->getTopViewscreen()) &&
ui->main.mode == ui_sidebar_mode::QueryBuilding) ui->main.mode == ui_sidebar_mode::QueryBuilding)
{ {
workshop = world->selected_building; workshop = world->selected_building;
job = getSelectedWorkshopJob(c, true); job = Gui::getSelectedWorkshopJob(c, true);
} }
std::string cmd = parameters.empty() ? "list" : parameters[0]; std::string cmd = parameters.empty() ? "list" : parameters[0];

@ -71,50 +71,64 @@ static ParseCxxHandler(func, handler, fixFunc)
y = x; y = x;
z = x; z = x;
EHCookieOffset=0; GSCookieOffset=0; EHCookieOffset=0; GSCookieOffset=0;
if (matchBytes(x,"8B5424088D420C")) // 8B 54 24 08 mov edx, [esp+8]
// 8B 54 24 08 mov edx, [esp+8] if (matchBytes(x,"8B5424088D02"))
// 8D 42 0C lea eax, [edx+0Ch] x = x+6;
// 8D 02 lea eax, [edx]
else if (matchBytes(x,"8B5424088D42"))
x = x+7;
// 8D 42 xx lea eax, [edx+XXh]
else if (matchBytes(x,"8B5424088D82"))
x = x+10;
// 8D 82 xx xx xx xx lea eax, [edx+XXh]
else {
Message("Function at %08X not recognized as exception handler!\n",x);
return;
}
//EH cookie check:
// 8B 4A xx mov ecx, [edx-XXh]
// OR
// 8B 8A xx xx xx xx mov ecx, [edx-XXh]
// 33 C8 xor ecx, eax
// E8 xx xx xx xx call __security_check_cookie
if (matchBytes(x,"8B4A??33C8E8"))
{
//byte argument
EHCookieOffset = (~Byte(x+2)+1)&0xFF;
EHCookieOffset = 12 + EHCookieOffset;
x = x+10;
}
else if (matchBytes(x,"8B8A????????33C8E8"))
{
//dword argument
EHCookieOffset = (~Dword(x+2)+1);
EHCookieOffset = 12 + EHCookieOffset;
x = x+13;
}
if (matchBytes(x,"83C0"))
x = x + 3;
// 8B 4A xx add eax, XXh
if (matchBytes(x,"8B4A??33C8E8"))
{ {
//EH cookie check:
// 8B 4A xx mov ecx, [edx-XXh] // 8B 4A xx mov ecx, [edx-XXh]
// OR
// 8B 8A xx xx xx xx mov ecx, [edx-XXh]
// 33 C8 xor ecx, eax // 33 C8 xor ecx, eax
// E8 xx xx xx xx call __security_check_cookie // E8 xx xx xx xx call __security_check_cookie
x = x+7; GSCookieOffset = (~Byte(x+2)+1)&0xFF;
if (matchBytes(x,"8B4A??33C8E8")) GSCookieOffset = 12 + GSCookieOffset;
{ x = x+10;
//byte argument }
EHCookieOffset = (~Byte(x+2)+1)&0xFF; else if (matchBytes(x,"8B8A????????33C8E8"))
EHCookieOffset = 12 + EHCookieOffset; {
x = x+10; //dword argument
} GSCookieOffset = (~Dword(x+9)+1);
else if (matchBytes(x,"8B8A????????33C8E8")) GSCookieOffset = 12 + GSCookieOffset;
{ x = x+13;
//dword argument
EHCookieOffset = (~Dword(x+2)+1);
EHCookieOffset = 12 + EHCookieOffset;
x = x+13;
}
if (matchBytes(x,"8B4A??33C8E8"))
{
// 8B 4A xx mov ecx, [edx-XXh]
// 33 C8 xor ecx, eax
// E8 xx xx xx xx call __security_check_cookie
GSCookieOffset = (~Byte(x+2)+1)&0xFF;
GSCookieOffset = 12 + GSCookieOffset;
x = x+10;
}
else if (matchBytes(x,"8B8A????????33C8E8"))
{
//dword argument
GSCookieOffset = (~Dword(x+9)+1);
GSCookieOffset = 12 + GSCookieOffset;
x = x+13;
}
//Message("EH3: EH Cookie=%02X, GSCookie=%02X\n",EHCookieOffset, GSCookieOffset);
} }
//Message("EH3: EH Cookie=%02X, GSCookie=%02X\n",EHCookieOffset, GSCookieOffset);
if (Byte(x)==0xB8) { if (Byte(x)==0xB8) {
// 8B 4A xx xx xx mov eax, offset FuncInfo
x = Dword(x+1); x = Dword(x+1);
} }
else { else {

@ -293,6 +293,7 @@ struct _s_RTTIBaseClassDescriptor
DWORD numContainedBases; //number of nested classes following in the array DWORD numContainedBases; //number of nested classes following in the array
struct PMD where; //some displacement info struct PMD where; //some displacement info
DWORD attributes; //usually 0, sometimes 10h DWORD attributes; //usually 0, sometimes 10h
struct _s_RTTIClassHierarchyDescriptor *pClassHierarchyDescriptor; //of this base class
}; };
struct PMD struct PMD
@ -314,6 +315,15 @@ struct PMD
DwordCmt(x+4, "numContainedBases"); DwordCmt(x+4, "numContainedBases");
DwordArrayCmt(x+8, 3, "PMD where"); DwordArrayCmt(x+8, 3, "PMD where");
DwordCmt(x+20, "attributes"); DwordCmt(x+20, "attributes");
OffCmt(x+24, "pClassHierarchyDescriptor");
if(substr(Name(Dword(x+24)),0,5) != "??_R3")
{
// assign dummy name to prevent infinite recursion
MakeName(Dword(x+24),"??_R3"+form("%06x",x)+"@@8");
// a proper name will be assigned shortly
Parse_CHD(Dword(x+24),indent-1);
}
s = Parse_TD(Dword(x), indent+1); s = Parse_TD(Dword(x), indent+1);
//??_R1A@?0A@A@B@@8 = B::`RTTI Base Class Descriptor at (0,-1,0,0)' //??_R1A@?0A@A@B@@8 = B::`RTTI Base Class Descriptor at (0,-1,0,0)'
@ -414,9 +424,11 @@ static Parse_CHD(x, indent)
i=0; i=0;
DumpNestedClass(a, indent, n); DumpNestedClass(a, indent, n);
indent=indent+1; indent=indent+1;
while(i<n) while(i<=n)
{ {
p = Dword(a); p = Dword(a);
if (i==n && p!=0)
break;
//Message(indent_str+" BaseClass[%02d]: %08.8Xh\n", i, p); //Message(indent_str+" BaseClass[%02d]: %08.8Xh\n", i, p);
OffCmt(a, form("BaseClass[%02d]", i)); OffCmt(a, form("BaseClass[%02d]", i));
if (i==0) if (i==0)