Merge branch 'master' of github.com:peterix/dfhack
commit
c6700585bc
@ -1 +1 @@
|
|||||||
Subproject commit 27216d9a4be418729cb4671371b7309f0af558f1
|
Subproject commit c85e9fb35d3510c5dcc367056cda3237d77a7add
|
@ -0,0 +1,210 @@
|
|||||||
|
/*
|
||||||
|
SDL - Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2009 Sam Lantinga
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Sam Lantinga
|
||||||
|
slouken@libsdl.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Fake - only structs. Shamelessly pilfered from the SDL library.
|
||||||
|
// Needed for processing its event types without polluting our namespaces with C garbage
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "SDL_keyboard.h"
|
||||||
|
|
||||||
|
namespace SDL
|
||||||
|
{
|
||||||
|
enum ButtonState
|
||||||
|
{
|
||||||
|
BTN_RELEASED = 0,
|
||||||
|
BTN_PRESSED = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Event enumerations */
|
||||||
|
enum EventType
|
||||||
|
{
|
||||||
|
ET_NOEVENT = 0, /**< Unused (do not remove) */
|
||||||
|
ET_ACTIVEEVENT, /**< Application loses/gains visibility */
|
||||||
|
ET_KEYDOWN, /**< Keys pressed */
|
||||||
|
ET_KEYUP, /**< Keys released */
|
||||||
|
ET_MOUSEMOTION, /**< Mouse moved */
|
||||||
|
ET_MOUSEBUTTONDOWN, /**< Mouse button pressed */
|
||||||
|
ET_MOUSEBUTTONUP, /**< Mouse button released */
|
||||||
|
ET_JOYAXISMOTION, /**< Joystick axis motion */
|
||||||
|
ET_JOYBALLMOTION, /**< Joystick trackball motion */
|
||||||
|
ET_JOYHATMOTION, /**< Joystick hat position change */
|
||||||
|
ET_JOYBUTTONDOWN, /**< Joystick button pressed */
|
||||||
|
ET_JOYBUTTONUP, /**< Joystick button released */
|
||||||
|
ET_QUIT, /**< User-requested quit */
|
||||||
|
ET_SYSWMEVENT, /**< System specific event */
|
||||||
|
ET_EVENT_RESERVEDA, /**< Reserved for future use.. */
|
||||||
|
ET_EVENT_RESERVEDB, /**< Reserved for future use.. */
|
||||||
|
ET_VIDEORESIZE, /**< User resized video mode */
|
||||||
|
ET_VIDEOEXPOSE, /**< Screen needs to be redrawn */
|
||||||
|
ET_EVENT_RESERVED2, /**< Reserved for future use.. */
|
||||||
|
ET_EVENT_RESERVED3, /**< Reserved for future use.. */
|
||||||
|
ET_EVENT_RESERVED4, /**< Reserved for future use.. */
|
||||||
|
ET_EVENT_RESERVED5, /**< Reserved for future use.. */
|
||||||
|
ET_EVENT_RESERVED6, /**< Reserved for future use.. */
|
||||||
|
ET_EVENT_RESERVED7, /**< Reserved for future use.. */
|
||||||
|
/** Events ET_USEREVENT through ET_MAXEVENTS-1 are for your use */
|
||||||
|
ET_USEREVENT = 24,
|
||||||
|
/** This last event is only for bounding internal arrays
|
||||||
|
* It is the number of bits in the event mask datatype -- Uint32
|
||||||
|
*/
|
||||||
|
ET_NUMEVENTS = 32
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Application visibility event structure */
|
||||||
|
struct ActiveEvent
|
||||||
|
{
|
||||||
|
uint8_t type; /**< ET_ACTIVEEVENT */
|
||||||
|
uint8_t gain; /**< Whether given states were gained or lost (1/0) */
|
||||||
|
uint8_t state; /**< A mask of the focus states */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Keyboard event structure */
|
||||||
|
struct KeyboardEvent
|
||||||
|
{
|
||||||
|
uint8_t type; /**< ET_KEYDOWN or ET_KEYUP */
|
||||||
|
uint8_t which; /**< The keyboard device index */
|
||||||
|
uint8_t state; /**< BTN_PRESSED or BTN_RELEASED */
|
||||||
|
keysym ksym;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Mouse motion event structure */
|
||||||
|
struct MouseMotionEvent
|
||||||
|
{
|
||||||
|
uint8_t type; /**< ET_MOUSEMOTION */
|
||||||
|
uint8_t which; /**< The mouse device index */
|
||||||
|
uint8_t state; /**< The current button state */
|
||||||
|
uint16_t x, y; /**< The X/Y coordinates of the mouse */
|
||||||
|
int16_t xrel; /**< The relative motion in the X direction */
|
||||||
|
int16_t yrel; /**< The relative motion in the Y direction */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Mouse button event structure */
|
||||||
|
struct MouseButtonEvent
|
||||||
|
{
|
||||||
|
uint8_t type; /**< ET_MOUSEBUTTONDOWN or ET_MOUSEBUTTONUP */
|
||||||
|
uint8_t which; /**< The mouse device index */
|
||||||
|
uint8_t button; /**< The mouse button index */
|
||||||
|
uint8_t state; /**< BTN_PRESSED or BTN_RELEASED */
|
||||||
|
uint16_t x, y; /**< The X/Y coordinates of the mouse at press time */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Joystick axis motion event structure */
|
||||||
|
struct JoyAxisEvent
|
||||||
|
{
|
||||||
|
uint8_t type; /**< ET_JOYAXISMOTION */
|
||||||
|
uint8_t which; /**< The joystick device index */
|
||||||
|
uint8_t axis; /**< The joystick axis index */
|
||||||
|
int16_t value; /**< The axis value (range: -32768 to 32767) */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Joystick trackball motion event structure */
|
||||||
|
struct JoyBallEvent
|
||||||
|
{
|
||||||
|
uint8_t type; /**< ET_JOYBALLMOTION */
|
||||||
|
uint8_t which; /**< The joystick device index */
|
||||||
|
uint8_t ball; /**< The joystick trackball index */
|
||||||
|
int16_t xrel; /**< The relative motion in the X direction */
|
||||||
|
int16_t yrel; /**< The relative motion in the Y direction */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Joystick hat position change event structure */
|
||||||
|
struct JoyHatEvent
|
||||||
|
{
|
||||||
|
uint8_t type; /**< ET_JOYHATMOTION */
|
||||||
|
uint8_t which; /**< The joystick device index */
|
||||||
|
uint8_t hat; /**< The joystick hat index */
|
||||||
|
uint8_t value; /**< The hat position value:
|
||||||
|
* SDL_HAT_LEFTUP SDL_HAT_UP SDL_HAT_RIGHTUP
|
||||||
|
* SDL_HAT_LEFT SDL_HAT_CENTERED SDL_HAT_RIGHT
|
||||||
|
* SDL_HAT_LEFTDOWN SDL_HAT_DOWN SDL_HAT_RIGHTDOWN
|
||||||
|
* Note that zero means the POV is centered.
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Joystick button event structure */
|
||||||
|
struct JoyButtonEvent
|
||||||
|
{
|
||||||
|
uint8_t type; /**< ET_JOYBUTTONDOWN or ET_JOYBUTTONUP */
|
||||||
|
uint8_t which; /**< The joystick device index */
|
||||||
|
uint8_t button; /**< The joystick button index */
|
||||||
|
uint8_t state; /**< BTN_PRESSED or BTN_RELEASED */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** The "window resized" event
|
||||||
|
* When you get this event, you are responsible for setting a new video
|
||||||
|
* mode with the new width and height.
|
||||||
|
*/
|
||||||
|
struct ResizeEvent
|
||||||
|
{
|
||||||
|
uint8_t type; /**< ET_VIDEORESIZE */
|
||||||
|
int w; /**< New width */
|
||||||
|
int h; /**< New height */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** The "screen redraw" event */
|
||||||
|
struct ExposeEvent
|
||||||
|
{
|
||||||
|
uint8_t type; /**< ET_VIDEOEXPOSE */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** The "quit requested" event */
|
||||||
|
struct QuitEvent
|
||||||
|
{
|
||||||
|
uint8_t type; /**< ET_QUIT */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A user-defined event type */
|
||||||
|
struct UserEvent
|
||||||
|
{
|
||||||
|
uint8_t type; /**< ETL_USEREVENT through ET_NUMEVENTS-1 */
|
||||||
|
int code; /**< User defined event code */
|
||||||
|
void *data1; /**< User defined data pointer */
|
||||||
|
void *data2; /**< User defined data pointer */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** If you want to use this event, you should include SDL_syswm.h */
|
||||||
|
struct SysWMmsg;
|
||||||
|
struct SysWMEvent
|
||||||
|
{
|
||||||
|
uint8_t type;
|
||||||
|
SysWMmsg *msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** General event structure */
|
||||||
|
union Event
|
||||||
|
{
|
||||||
|
uint8_t type;
|
||||||
|
ActiveEvent active;
|
||||||
|
KeyboardEvent key;
|
||||||
|
MouseMotionEvent motion;
|
||||||
|
MouseButtonEvent button;
|
||||||
|
JoyAxisEvent jaxis;
|
||||||
|
JoyBallEvent jball;
|
||||||
|
JoyHatEvent jhat;
|
||||||
|
JoyButtonEvent jbutton;
|
||||||
|
ResizeEvent resize;
|
||||||
|
ExposeEvent expose;
|
||||||
|
QuitEvent quit;
|
||||||
|
UserEvent user;
|
||||||
|
SysWMEvent syswm;
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
SDL - Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2009 Sam Lantinga
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Sam Lantinga
|
||||||
|
slouken@libsdl.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Fake - only structs. Shamelessly pilfered from the SDL library.
|
||||||
|
// Needed for processing its event types without polluting our namespaces with C garbage
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "SDL_keysym.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace SDL
|
||||||
|
{
|
||||||
|
/** Keysym structure
|
||||||
|
*
|
||||||
|
* - The scancode is hardware dependent, and should not be used by general
|
||||||
|
* applications. If no hardware scancode is available, it will be 0.
|
||||||
|
*
|
||||||
|
* - The 'unicode' translated character is only available when character
|
||||||
|
* translation is enabled by the SDL_EnableUNICODE() API. If non-zero,
|
||||||
|
* this is a UNICODE character corresponding to the keypress. If the
|
||||||
|
* high 9 bits of the character are 0, then this maps to the equivalent
|
||||||
|
* ASCII character:
|
||||||
|
* @code
|
||||||
|
* char ch;
|
||||||
|
* if ( (keysym.unicode & 0xFF80) == 0 ) {
|
||||||
|
* ch = keysym.unicode & 0x7F;
|
||||||
|
* } else {
|
||||||
|
* An international character..
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
typedef struct keysym
|
||||||
|
{
|
||||||
|
uint8_t scancode; /**< hardware specific scancode */
|
||||||
|
Key sym; /**< SDL virtual keysym */
|
||||||
|
Mod mod; /**< current key modifiers */
|
||||||
|
uint16_t unicode; /**< translated character */
|
||||||
|
} keysym;
|
||||||
|
|
||||||
|
/** This is the mask which refers to all hotkey bindings */
|
||||||
|
#define ALL_HOTKEYS 0xFFFFFFFF
|
||||||
|
}
|
@ -0,0 +1,329 @@
|
|||||||
|
/*
|
||||||
|
SDL - Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2009 Sam Lantinga
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Sam Lantinga
|
||||||
|
slouken@libsdl.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Fake - only structs. Shamelessly pilfered from the SDL library.
|
||||||
|
// Needed for processing its event types without polluting our namespaces with C garbage
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace SDL
|
||||||
|
{
|
||||||
|
/** What we really want is a mapping of every raw key on the keyboard.
|
||||||
|
* To support international keyboards, we use the range 0xA1 - 0xFF
|
||||||
|
* as international virtual keycodes. We'll follow in the footsteps of X11...
|
||||||
|
* @brief The names of the keys
|
||||||
|
*/
|
||||||
|
enum Key
|
||||||
|
{
|
||||||
|
/** @name ASCII mapped keysyms
|
||||||
|
* The keyboard syms have been cleverly chosen to map to ASCII
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
K_UNKNOWN = 0,
|
||||||
|
K_FIRST = 0,
|
||||||
|
K_BACKSPACE = 8,
|
||||||
|
K_TAB = 9,
|
||||||
|
K_CLEAR = 12,
|
||||||
|
K_RETURN = 13,
|
||||||
|
K_PAUSE = 19,
|
||||||
|
K_ESCAPE = 27,
|
||||||
|
K_SPACE = 32,
|
||||||
|
K_EXCLAIM = 33,
|
||||||
|
K_QUOTEDBL = 34,
|
||||||
|
K_HASH = 35,
|
||||||
|
K_DOLLAR = 36,
|
||||||
|
K_AMPERSAND = 38,
|
||||||
|
K_QUOTE = 39,
|
||||||
|
K_LEFTPAREN = 40,
|
||||||
|
K_RIGHTPAREN = 41,
|
||||||
|
K_ASTERISK = 42,
|
||||||
|
K_PLUS = 43,
|
||||||
|
K_COMMA = 44,
|
||||||
|
K_MINUS = 45,
|
||||||
|
K_PERIOD = 46,
|
||||||
|
K_SLASH = 47,
|
||||||
|
K_0 = 48,
|
||||||
|
K_1 = 49,
|
||||||
|
K_2 = 50,
|
||||||
|
K_3 = 51,
|
||||||
|
K_4 = 52,
|
||||||
|
K_5 = 53,
|
||||||
|
K_6 = 54,
|
||||||
|
K_7 = 55,
|
||||||
|
K_8 = 56,
|
||||||
|
K_9 = 57,
|
||||||
|
K_COLON = 58,
|
||||||
|
K_SEMICOLON = 59,
|
||||||
|
K_LESS = 60,
|
||||||
|
K_EQUALS = 61,
|
||||||
|
K_GREATER = 62,
|
||||||
|
K_QUESTION = 63,
|
||||||
|
K_AT = 64,
|
||||||
|
/*
|
||||||
|
Skip uppercase letters
|
||||||
|
*/
|
||||||
|
K_LEFTBRACKET = 91,
|
||||||
|
K_BACKSLASH = 92,
|
||||||
|
K_RIGHTBRACKET = 93,
|
||||||
|
K_CARET = 94,
|
||||||
|
K_UNDERSCORE = 95,
|
||||||
|
K_BACKQUOTE = 96,
|
||||||
|
K_a = 97,
|
||||||
|
K_b = 98,
|
||||||
|
K_c = 99,
|
||||||
|
K_d = 100,
|
||||||
|
K_e = 101,
|
||||||
|
K_f = 102,
|
||||||
|
K_g = 103,
|
||||||
|
K_h = 104,
|
||||||
|
K_i = 105,
|
||||||
|
K_j = 106,
|
||||||
|
K_k = 107,
|
||||||
|
K_l = 108,
|
||||||
|
K_m = 109,
|
||||||
|
K_n = 110,
|
||||||
|
K_o = 111,
|
||||||
|
K_p = 112,
|
||||||
|
K_q = 113,
|
||||||
|
K_r = 114,
|
||||||
|
K_s = 115,
|
||||||
|
K_t = 116,
|
||||||
|
K_u = 117,
|
||||||
|
K_v = 118,
|
||||||
|
K_w = 119,
|
||||||
|
K_x = 120,
|
||||||
|
K_y = 121,
|
||||||
|
K_z = 122,
|
||||||
|
K_DELETE = 127,
|
||||||
|
/* End of ASCII mapped keysyms */
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
/** @name International keyboard syms */
|
||||||
|
/*@{*/
|
||||||
|
K_WORLD_0 = 160, /* 0xA0 */
|
||||||
|
K_WORLD_1 = 161,
|
||||||
|
K_WORLD_2 = 162,
|
||||||
|
K_WORLD_3 = 163,
|
||||||
|
K_WORLD_4 = 164,
|
||||||
|
K_WORLD_5 = 165,
|
||||||
|
K_WORLD_6 = 166,
|
||||||
|
K_WORLD_7 = 167,
|
||||||
|
K_WORLD_8 = 168,
|
||||||
|
K_WORLD_9 = 169,
|
||||||
|
K_WORLD_10 = 170,
|
||||||
|
K_WORLD_11 = 171,
|
||||||
|
K_WORLD_12 = 172,
|
||||||
|
K_WORLD_13 = 173,
|
||||||
|
K_WORLD_14 = 174,
|
||||||
|
K_WORLD_15 = 175,
|
||||||
|
K_WORLD_16 = 176,
|
||||||
|
K_WORLD_17 = 177,
|
||||||
|
K_WORLD_18 = 178,
|
||||||
|
K_WORLD_19 = 179,
|
||||||
|
K_WORLD_20 = 180,
|
||||||
|
K_WORLD_21 = 181,
|
||||||
|
K_WORLD_22 = 182,
|
||||||
|
K_WORLD_23 = 183,
|
||||||
|
K_WORLD_24 = 184,
|
||||||
|
K_WORLD_25 = 185,
|
||||||
|
K_WORLD_26 = 186,
|
||||||
|
K_WORLD_27 = 187,
|
||||||
|
K_WORLD_28 = 188,
|
||||||
|
K_WORLD_29 = 189,
|
||||||
|
K_WORLD_30 = 190,
|
||||||
|
K_WORLD_31 = 191,
|
||||||
|
K_WORLD_32 = 192,
|
||||||
|
K_WORLD_33 = 193,
|
||||||
|
K_WORLD_34 = 194,
|
||||||
|
K_WORLD_35 = 195,
|
||||||
|
K_WORLD_36 = 196,
|
||||||
|
K_WORLD_37 = 197,
|
||||||
|
K_WORLD_38 = 198,
|
||||||
|
K_WORLD_39 = 199,
|
||||||
|
K_WORLD_40 = 200,
|
||||||
|
K_WORLD_41 = 201,
|
||||||
|
K_WORLD_42 = 202,
|
||||||
|
K_WORLD_43 = 203,
|
||||||
|
K_WORLD_44 = 204,
|
||||||
|
K_WORLD_45 = 205,
|
||||||
|
K_WORLD_46 = 206,
|
||||||
|
K_WORLD_47 = 207,
|
||||||
|
K_WORLD_48 = 208,
|
||||||
|
K_WORLD_49 = 209,
|
||||||
|
K_WORLD_50 = 210,
|
||||||
|
K_WORLD_51 = 211,
|
||||||
|
K_WORLD_52 = 212,
|
||||||
|
K_WORLD_53 = 213,
|
||||||
|
K_WORLD_54 = 214,
|
||||||
|
K_WORLD_55 = 215,
|
||||||
|
K_WORLD_56 = 216,
|
||||||
|
K_WORLD_57 = 217,
|
||||||
|
K_WORLD_58 = 218,
|
||||||
|
K_WORLD_59 = 219,
|
||||||
|
K_WORLD_60 = 220,
|
||||||
|
K_WORLD_61 = 221,
|
||||||
|
K_WORLD_62 = 222,
|
||||||
|
K_WORLD_63 = 223,
|
||||||
|
K_WORLD_64 = 224,
|
||||||
|
K_WORLD_65 = 225,
|
||||||
|
K_WORLD_66 = 226,
|
||||||
|
K_WORLD_67 = 227,
|
||||||
|
K_WORLD_68 = 228,
|
||||||
|
K_WORLD_69 = 229,
|
||||||
|
K_WORLD_70 = 230,
|
||||||
|
K_WORLD_71 = 231,
|
||||||
|
K_WORLD_72 = 232,
|
||||||
|
K_WORLD_73 = 233,
|
||||||
|
K_WORLD_74 = 234,
|
||||||
|
K_WORLD_75 = 235,
|
||||||
|
K_WORLD_76 = 236,
|
||||||
|
K_WORLD_77 = 237,
|
||||||
|
K_WORLD_78 = 238,
|
||||||
|
K_WORLD_79 = 239,
|
||||||
|
K_WORLD_80 = 240,
|
||||||
|
K_WORLD_81 = 241,
|
||||||
|
K_WORLD_82 = 242,
|
||||||
|
K_WORLD_83 = 243,
|
||||||
|
K_WORLD_84 = 244,
|
||||||
|
K_WORLD_85 = 245,
|
||||||
|
K_WORLD_86 = 246,
|
||||||
|
K_WORLD_87 = 247,
|
||||||
|
K_WORLD_88 = 248,
|
||||||
|
K_WORLD_89 = 249,
|
||||||
|
K_WORLD_90 = 250,
|
||||||
|
K_WORLD_91 = 251,
|
||||||
|
K_WORLD_92 = 252,
|
||||||
|
K_WORLD_93 = 253,
|
||||||
|
K_WORLD_94 = 254,
|
||||||
|
K_WORLD_95 = 255, /* 0xFF */
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
/** @name Numeric keypad */
|
||||||
|
/*@{*/
|
||||||
|
K_KP0 = 256,
|
||||||
|
K_KP1 = 257,
|
||||||
|
K_KP2 = 258,
|
||||||
|
K_KP3 = 259,
|
||||||
|
K_KP4 = 260,
|
||||||
|
K_KP5 = 261,
|
||||||
|
K_KP6 = 262,
|
||||||
|
K_KP7 = 263,
|
||||||
|
K_KP8 = 264,
|
||||||
|
K_KP9 = 265,
|
||||||
|
K_KP_PERIOD = 266,
|
||||||
|
K_KP_DIVIDE = 267,
|
||||||
|
K_KP_MULTIPLY = 268,
|
||||||
|
K_KP_MINUS = 269,
|
||||||
|
K_KP_PLUS = 270,
|
||||||
|
K_KP_ENTER = 271,
|
||||||
|
K_KP_EQUALS = 272,
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
/** @name Arrows + Home/End pad */
|
||||||
|
/*@{*/
|
||||||
|
K_UP = 273,
|
||||||
|
K_DOWN = 274,
|
||||||
|
K_RIGHT = 275,
|
||||||
|
K_LEFT = 276,
|
||||||
|
K_INSERT = 277,
|
||||||
|
K_HOME = 278,
|
||||||
|
K_END = 279,
|
||||||
|
K_PAGEUP = 280,
|
||||||
|
K_PAGEDOWN = 281,
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
/** @name Function keys */
|
||||||
|
/*@{*/
|
||||||
|
K_F1 = 282,
|
||||||
|
K_F2 = 283,
|
||||||
|
K_F3 = 284,
|
||||||
|
K_F4 = 285,
|
||||||
|
K_F5 = 286,
|
||||||
|
K_F6 = 287,
|
||||||
|
K_F7 = 288,
|
||||||
|
K_F8 = 289,
|
||||||
|
K_F9 = 290,
|
||||||
|
K_F10 = 291,
|
||||||
|
K_F11 = 292,
|
||||||
|
K_F12 = 293,
|
||||||
|
K_F13 = 294,
|
||||||
|
K_F14 = 295,
|
||||||
|
K_F15 = 296,
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
/** @name Key state modifier keys */
|
||||||
|
/*@{*/
|
||||||
|
K_NUMLOCK = 300,
|
||||||
|
K_CAPSLOCK = 301,
|
||||||
|
K_SCROLLOCK = 302,
|
||||||
|
K_RSHIFT = 303,
|
||||||
|
K_LSHIFT = 304,
|
||||||
|
K_RCTRL = 305,
|
||||||
|
K_LCTRL = 306,
|
||||||
|
K_RALT = 307,
|
||||||
|
K_LALT = 308,
|
||||||
|
K_RMETA = 309,
|
||||||
|
K_LMETA = 310,
|
||||||
|
K_LSUPER = 311, /**< Left "Windows" key */
|
||||||
|
K_RSUPER = 312, /**< Right "Windows" key */
|
||||||
|
K_MODE = 313, /**< "Alt Gr" key */
|
||||||
|
K_COMPOSE = 314, /**< Multi-key compose key */
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
/** @name Miscellaneous function keys */
|
||||||
|
/*@{*/
|
||||||
|
K_HELP = 315,
|
||||||
|
K_PRINT = 316,
|
||||||
|
K_SYSREQ = 317,
|
||||||
|
K_BREAK = 318,
|
||||||
|
K_MENU = 319,
|
||||||
|
K_POWER = 320, /**< Power Macintosh power key */
|
||||||
|
K_EURO = 321, /**< Some european keyboards */
|
||||||
|
K_UNDO = 322, /**< Atari keyboard has Undo */
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
/* Add any other keys here */
|
||||||
|
|
||||||
|
K_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Enumeration of valid key mods (possibly OR'd together) */
|
||||||
|
enum Mod {
|
||||||
|
KMOD_NONE = 0x0000,
|
||||||
|
KMOD_LSHIFT= 0x0001,
|
||||||
|
KMOD_RSHIFT= 0x0002,
|
||||||
|
KMOD_LCTRL = 0x0040,
|
||||||
|
KMOD_RCTRL = 0x0080,
|
||||||
|
KMOD_LALT = 0x0100,
|
||||||
|
KMOD_RALT = 0x0200,
|
||||||
|
KMOD_LMETA = 0x0400,
|
||||||
|
KMOD_RMETA = 0x0800,
|
||||||
|
KMOD_NUM = 0x1000,
|
||||||
|
KMOD_CAPS = 0x2000,
|
||||||
|
KMOD_MODE = 0x4000,
|
||||||
|
KMOD_RESERVED = 0x8000,
|
||||||
|
KMOD_CTRL = (KMOD_LCTRL|KMOD_RCTRL),
|
||||||
|
KMOD_SHIFT = (KMOD_LSHIFT|KMOD_RSHIFT),
|
||||||
|
KMOD_ALT = (KMOD_LALT|KMOD_RALT),
|
||||||
|
KMOD_META = (KMOD_LMETA|KMOD_RMETA)
|
||||||
|
};
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
Subproject commit 234d0f57a927f306f2052fc2f45d38b3201ddee6
|
Subproject commit c381884664c71adefbec44258a734def2c88dacc
|
@ -1,29 +1,33 @@
|
|||||||
find_package(Ruby)
|
OPTION(DL_RUBY "download libruby from the internet" ON)
|
||||||
if(RUBY_FOUND)
|
IF (DL_RUBY)
|
||||||
|
IF (UNIX)
|
||||||
|
FILE(DOWNLOAD http://cloud.github.com/downloads/jjyg/dfhack/libruby187.tar.gz ${CMAKE_CURRENT_SOURCE_DIR}/libruby187.tar.gz
|
||||||
|
EXPECTED_MD5 eb2adea59911f68e6066966c1352f291)
|
||||||
|
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E tar xzf libruby187.tar.gz
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
FILE(RENAME libruby1.8.so.1.8.7 libruby.so)
|
||||||
|
SET(RUBYLIB libruby.so)
|
||||||
|
ELSE (UNIX)
|
||||||
|
FILE(DOWNLOAD http://cloud.github.com/downloads/jjyg/dfhack/msvcrtruby187.tar.gz ${CMAKE_CURRENT_SOURCE_DIR}/msvcrtruby187.tar.gz
|
||||||
|
EXPECTED_MD5 9f4a1659ac3a5308f32d3a1937bbeeae)
|
||||||
|
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E tar xzf msvcrtruby187.tar.gz
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
FILE(RENAME msvcrt-ruby18.dll libruby.dll)
|
||||||
|
SET(RUBYLIB libruby.dll)
|
||||||
|
ENDIF(UNIX)
|
||||||
|
ENDIF(DL_RUBY)
|
||||||
|
|
||||||
ADD_CUSTOM_COMMAND(
|
ADD_CUSTOM_COMMAND(
|
||||||
OUTPUT ruby-autogen.cpp
|
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/ruby-autogen.rb
|
||||||
COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/codegen.pl ${dfhack_SOURCE_DIR}/library/include/df/codegen.out.xml ${CMAKE_CURRENT_BINARY_DIR}/ruby-autogen.cpp
|
COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/codegen.pl ${dfhack_SOURCE_DIR}/library/include/df/codegen.out.xml ${CMAKE_CURRENT_SOURCE_DIR}/ruby-autogen.rb
|
||||||
DEPENDS ${dfhack_SOURCE_DIR}/library/include/df/codegen.out.xml codegen.pl
|
DEPENDS ${dfhack_SOURCE_DIR}/library/include/df/codegen.out.xml ${CMAKE_CURRENT_SOURCE_DIR}/codegen.pl
|
||||||
|
COMMENT ruby-autogen.rb
|
||||||
)
|
)
|
||||||
ADD_EXECUTABLE(ruby-autogen ruby-autogen.cpp)
|
ADD_CUSTOM_TARGET(ruby-autogen-rb DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/ruby-autogen.rb)
|
||||||
if(CMAKE_COMPILER_IS_GNUCC)
|
|
||||||
set_target_properties (ruby-autogen PROPERTIES COMPILE_FLAGS "-Wno-invalid-offsetof")
|
INCLUDE_DIRECTORIES("${dfhack_SOURCE_DIR}/depends/tthread")
|
||||||
endif(CMAKE_COMPILER_IS_GNUCC)
|
|
||||||
ADD_CUSTOM_COMMAND(
|
|
||||||
OUTPUT ruby-autogen.offsets
|
|
||||||
COMMAND ruby-autogen ${CMAKE_CURRENT_BINARY_DIR}/ruby-autogen.offsets
|
|
||||||
DEPENDS ruby-autogen
|
|
||||||
)
|
|
||||||
ADD_CUSTOM_COMMAND(
|
|
||||||
OUTPUT ruby-autogen.rb
|
|
||||||
COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/codegen.pl ${dfhack_SOURCE_DIR}/library/include/df/codegen.out.xml ${CMAKE_CURRENT_SOURCE_DIR}/ruby-autogen.rb ${CMAKE_CURRENT_BINARY_DIR}/ruby-autogen.offsets ${CMAKE_CURRENT_SOURCE_DIR}/ruby-memstruct.rb
|
|
||||||
DEPENDS ruby-autogen.offsets ruby-memstruct.rb
|
|
||||||
)
|
|
||||||
ADD_CUSTOM_TARGET(ruby-autogen-rb ALL DEPENDS ruby-autogen.rb)
|
|
||||||
include_directories("${dfhack_SOURCE_DIR}/depends/tthread" ${RUBY_INCLUDE_PATH})
|
|
||||||
DFHACK_PLUGIN(ruby ruby.cpp LINK_LIBRARIES dfhack-tinythread)
|
DFHACK_PLUGIN(ruby ruby.cpp LINK_LIBRARIES dfhack-tinythread)
|
||||||
target_link_libraries(ruby ${RUBY_LIBRARY})
|
ADD_DEPENDENCIES(ruby ruby-autogen-rb)
|
||||||
install(FILES ruby.rb ruby-autogen.rb DESTINATION ${DFHACK_LIBRARY_DESTINATION})
|
|
||||||
else(RUBY_FOUND)
|
INSTALL(FILES ruby.rb ruby-autogen.rb ${RUBYLIB} DESTINATION ${DFHACK_LIBRARY_DESTINATION})
|
||||||
MESSAGE(STATUS "Required library (ruby) not found - ruby plugin can't be built.")
|
|
||||||
endif(RUBY_FOUND)
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,747 +0,0 @@
|
|||||||
module DFHack
|
|
||||||
module MemHack
|
|
||||||
INSPECT_SIZE_LIMIT=16384
|
|
||||||
class MemStruct
|
|
||||||
attr_accessor :_memaddr
|
|
||||||
def _at(addr) ; d = dup ; d._memaddr = addr ; d ; end
|
|
||||||
def _get ; self ; end
|
|
||||||
def _cpp_init ; end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Compound < MemStruct
|
|
||||||
class << self
|
|
||||||
attr_accessor :_fields, :_rtti_classname, :_sizeof
|
|
||||||
def field(name, offset)
|
|
||||||
struct = yield
|
|
||||||
return if not struct
|
|
||||||
@_fields ||= []
|
|
||||||
@_fields << [name, offset, struct]
|
|
||||||
define_method(name) { struct._at(@_memaddr+offset)._get }
|
|
||||||
define_method("#{name}=") { |v| struct._at(@_memaddr+offset)._set(v) }
|
|
||||||
end
|
|
||||||
def _fields_ancestors
|
|
||||||
if superclass.respond_to?(:_fields_ancestors)
|
|
||||||
superclass._fields_ancestors + _fields.to_a
|
|
||||||
else
|
|
||||||
_fields.to_a
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def number(bits, signed, initvalue=nil, enum=nil)
|
|
||||||
Number.new(bits, signed, initvalue, enum)
|
|
||||||
end
|
|
||||||
def float
|
|
||||||
Float.new
|
|
||||||
end
|
|
||||||
def bit(shift)
|
|
||||||
BitField.new(shift, 1)
|
|
||||||
end
|
|
||||||
def bits(shift, len, enum=nil)
|
|
||||||
BitField.new(shift, len, enum)
|
|
||||||
end
|
|
||||||
def pointer
|
|
||||||
Pointer.new((yield if block_given?))
|
|
||||||
end
|
|
||||||
def pointer_ary(tglen)
|
|
||||||
PointerAry.new(tglen, yield)
|
|
||||||
end
|
|
||||||
def static_array(len, tglen, indexenum=nil)
|
|
||||||
StaticArray.new(tglen, len, indexenum, yield)
|
|
||||||
end
|
|
||||||
def static_string(len)
|
|
||||||
StaticString.new(len)
|
|
||||||
end
|
|
||||||
|
|
||||||
def stl_vector(tglen=nil)
|
|
||||||
tg = yield if tglen
|
|
||||||
case tglen
|
|
||||||
when 1; StlVector8.new(tg)
|
|
||||||
when 2; StlVector16.new(tg)
|
|
||||||
else StlVector32.new(tg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
def stl_string
|
|
||||||
StlString.new
|
|
||||||
end
|
|
||||||
def stl_bit_vector
|
|
||||||
StlBitVector.new
|
|
||||||
end
|
|
||||||
def stl_deque(tglen)
|
|
||||||
StlDeque.new(tglen, yield)
|
|
||||||
end
|
|
||||||
|
|
||||||
def df_flagarray(indexenum=nil)
|
|
||||||
DfFlagarray.new(indexenum)
|
|
||||||
end
|
|
||||||
def df_array(tglen)
|
|
||||||
DfArray.new(tglen, yield)
|
|
||||||
end
|
|
||||||
def df_linked_list
|
|
||||||
DfLinkedList.new(yield)
|
|
||||||
end
|
|
||||||
|
|
||||||
def global(glob)
|
|
||||||
Global.new(glob)
|
|
||||||
end
|
|
||||||
def compound(name=nil, &b)
|
|
||||||
m = Class.new(Compound)
|
|
||||||
DFHack.const_set(name, m) if name
|
|
||||||
m.instance_eval(&b)
|
|
||||||
m.new
|
|
||||||
end
|
|
||||||
def rtti_classname(n)
|
|
||||||
DFHack.rtti_register(n, self)
|
|
||||||
@_rtti_classname = n
|
|
||||||
end
|
|
||||||
def sizeof(n)
|
|
||||||
@_sizeof = n
|
|
||||||
end
|
|
||||||
|
|
||||||
# allocate a new c++ object, return its ruby wrapper
|
|
||||||
def cpp_new
|
|
||||||
ptr = DFHack.malloc(_sizeof)
|
|
||||||
if _rtti_classname and vt = DFHack.rtti_getvtable(_rtti_classname)
|
|
||||||
DFHack.memory_write_int32(ptr, vt)
|
|
||||||
# TODO call constructor
|
|
||||||
end
|
|
||||||
o = new._at(ptr)
|
|
||||||
o._cpp_init
|
|
||||||
o
|
|
||||||
end
|
|
||||||
end
|
|
||||||
def _cpp_init
|
|
||||||
_fields_ancestors.each { |n, o, s| s._at(@_memaddr+o)._cpp_init }
|
|
||||||
end
|
|
||||||
def _set(h)
|
|
||||||
case h
|
|
||||||
when Hash; h.each { |k, v| send("_#{k}=", v) }
|
|
||||||
when Array; names = _field_names ; raise 'bad size' if names.length != h.length ; names.zip(h).each { |n, a| send("#{n}=", a) }
|
|
||||||
when Compound; _field_names.each { |n| send("#{n}=", h.send(n)) }
|
|
||||||
else raise 'wut?'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
def _fields ; self.class._fields.to_a ; end
|
|
||||||
def _fields_ancestors ; self.class._fields_ancestors.to_a ; end
|
|
||||||
def _field_names ; _fields_ancestors.map { |n, o, s| n } ; end
|
|
||||||
def _rtti_classname ; self.class._rtti_classname ; end
|
|
||||||
def _sizeof ; self.class._sizeof ; end
|
|
||||||
@@inspecting = {} # avoid infinite recursion on mutually-referenced objects
|
|
||||||
def inspect
|
|
||||||
cn = self.class.name.sub(/^DFHack::/, '')
|
|
||||||
cn << ' @' << ('0x%X' % _memaddr) if cn != ''
|
|
||||||
out = "#<#{cn}"
|
|
||||||
return out << ' ...>' if @@inspecting[_memaddr]
|
|
||||||
@@inspecting[_memaddr] = true
|
|
||||||
_fields_ancestors.each { |n, o, s|
|
|
||||||
out << ' ' if out.length != 0 and out[-1, 1] != ' '
|
|
||||||
if out.length > INSPECT_SIZE_LIMIT
|
|
||||||
out << '...'
|
|
||||||
break
|
|
||||||
end
|
|
||||||
out << inspect_field(n, o, s)
|
|
||||||
}
|
|
||||||
out.chomp!(' ')
|
|
||||||
@@inspecting.delete _memaddr
|
|
||||||
out << '>'
|
|
||||||
end
|
|
||||||
def inspect_field(n, o, s)
|
|
||||||
if s.kind_of?(BitField) and s._len == 1
|
|
||||||
send(n) ? n.to_s : ''
|
|
||||||
elsif s.kind_of?(Pointer)
|
|
||||||
"#{n}=#{s._at(@_memaddr+o).inspect}"
|
|
||||||
elsif n == :_whole
|
|
||||||
"_whole=0x#{_whole.to_s(16)}"
|
|
||||||
else
|
|
||||||
v = send(n).inspect
|
|
||||||
"#{n}=#{v}"
|
|
||||||
end
|
|
||||||
rescue
|
|
||||||
"#{n}=ERR(#{$!})"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Enum
|
|
||||||
# number -> symbol
|
|
||||||
def self.enum
|
|
||||||
# ruby weirdness, needed to make the constants 'virtual'
|
|
||||||
@enum ||= const_get(:ENUM)
|
|
||||||
end
|
|
||||||
# symbol -> number
|
|
||||||
def self.nume
|
|
||||||
@nume ||= const_get(:NUME)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.to_i(i)
|
|
||||||
nume[i] || i
|
|
||||||
end
|
|
||||||
def self.to_sym(i)
|
|
||||||
enum[i] || i
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Number < MemStruct
|
|
||||||
attr_accessor :_bits, :_signed, :_initvalue, :_enum
|
|
||||||
def initialize(bits, signed, initvalue, enum)
|
|
||||||
@_bits = bits
|
|
||||||
@_signed = signed
|
|
||||||
@_initvalue = initvalue
|
|
||||||
@_enum = enum
|
|
||||||
end
|
|
||||||
|
|
||||||
def _get
|
|
||||||
v = case @_bits
|
|
||||||
when 32; DFHack.memory_read_int32(@_memaddr)
|
|
||||||
when 16; DFHack.memory_read_int16(@_memaddr)
|
|
||||||
when 8; DFHack.memory_read_int8( @_memaddr)
|
|
||||||
when 64;(DFHack.memory_read_int32(@_memaddr) & 0xffffffff) + (DFHack.memory_read_int32(@_memaddr+4) << 32)
|
|
||||||
end
|
|
||||||
v &= (1 << @_bits) - 1 if not @_signed
|
|
||||||
v = @_enum.to_sym(v) if @_enum
|
|
||||||
v
|
|
||||||
end
|
|
||||||
|
|
||||||
def _set(v)
|
|
||||||
v = @_enum.to_i(v) if @_enum
|
|
||||||
case @_bits
|
|
||||||
when 32; DFHack.memory_write_int32(@_memaddr, v)
|
|
||||||
when 16; DFHack.memory_write_int16(@_memaddr, v)
|
|
||||||
when 8; DFHack.memory_write_int8( @_memaddr, v)
|
|
||||||
when 64; DFHack.memory_write_int32(@_memaddr, v & 0xffffffff) ; DFHack.memory_write_int32(@memaddr+4, v>>32)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def _cpp_init
|
|
||||||
_set(@_initvalue) if @_initvalue
|
|
||||||
end
|
|
||||||
end
|
|
||||||
class Float < MemStruct
|
|
||||||
def _get
|
|
||||||
DFHack.memory_read_float(@_memaddr)
|
|
||||||
end
|
|
||||||
|
|
||||||
def _set(v)
|
|
||||||
DFHack.memory_write_float(@_memaddr, v)
|
|
||||||
end
|
|
||||||
|
|
||||||
def _cpp_init
|
|
||||||
_set(0.0)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
class BitField < MemStruct
|
|
||||||
attr_accessor :_shift, :_len, :_enum
|
|
||||||
def initialize(shift, len, enum=nil)
|
|
||||||
@_shift = shift
|
|
||||||
@_len = len
|
|
||||||
@_enum = enum
|
|
||||||
end
|
|
||||||
def _mask
|
|
||||||
(1 << @_len) - 1
|
|
||||||
end
|
|
||||||
|
|
||||||
def _get
|
|
||||||
v = DFHack.memory_read_int32(@_memaddr) >> @_shift
|
|
||||||
if @_len == 1
|
|
||||||
((v & 1) == 0) ? false : true
|
|
||||||
else
|
|
||||||
v &= _mask
|
|
||||||
v = @_enum.to_sym(v) if @_enum
|
|
||||||
v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def _set(v)
|
|
||||||
if @_len == 1
|
|
||||||
# allow 'bit = 0'
|
|
||||||
v = (v && v != 0 ? 1 : 0)
|
|
||||||
end
|
|
||||||
v = @_enum.to_i(v) if @_enum
|
|
||||||
v = (v & _mask) << @_shift
|
|
||||||
|
|
||||||
ori = DFHack.memory_read_int32(@_memaddr) & 0xffffffff
|
|
||||||
DFHack.memory_write_int32(@_memaddr, ori - (ori & ((-1 & _mask) << @_shift)) + v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Pointer < MemStruct
|
|
||||||
attr_accessor :_tg
|
|
||||||
def initialize(tg)
|
|
||||||
@_tg = tg
|
|
||||||
end
|
|
||||||
|
|
||||||
def _getp
|
|
||||||
DFHack.memory_read_int32(@_memaddr) & 0xffffffff
|
|
||||||
end
|
|
||||||
|
|
||||||
def _get
|
|
||||||
addr = _getp
|
|
||||||
return if addr == 0
|
|
||||||
@_tg._at(addr)._get
|
|
||||||
end
|
|
||||||
|
|
||||||
# XXX shaky...
|
|
||||||
def _set(v)
|
|
||||||
if v.kind_of?(Pointer)
|
|
||||||
DFHack.memory_write_int32(@_memaddr, v._getp)
|
|
||||||
elsif v.kind_of?(MemStruct)
|
|
||||||
DFHack.memory_write_int32(@_memaddr, v._memaddr)
|
|
||||||
else
|
|
||||||
_get._set(v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def inspect
|
|
||||||
ptr = _getp
|
|
||||||
if ptr == 0
|
|
||||||
'NULL'
|
|
||||||
else
|
|
||||||
cn = ''
|
|
||||||
cn = @_tg.class.name.sub(/^DFHack::/, '').sub(/^MemHack::/, '') if @_tg
|
|
||||||
cn = @_tg._glob if cn == 'Global'
|
|
||||||
"#<Pointer #{cn} #{'0x%X' % _getp}>"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
class PointerAry < MemStruct
|
|
||||||
attr_accessor :_tglen, :_tg
|
|
||||||
def initialize(tglen, tg)
|
|
||||||
@_tglen = tglen
|
|
||||||
@_tg = tg
|
|
||||||
end
|
|
||||||
|
|
||||||
def _getp(i=0)
|
|
||||||
delta = (i != 0 ? i*@_tglen : 0)
|
|
||||||
(DFHack.memory_read_int32(@_memaddr) & 0xffffffff) + delta
|
|
||||||
end
|
|
||||||
|
|
||||||
def _get
|
|
||||||
addr = _getp
|
|
||||||
return if addr == 0
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
def [](i)
|
|
||||||
addr = _getp(i)
|
|
||||||
return if addr == 0
|
|
||||||
@_tg._at(addr)._get
|
|
||||||
end
|
|
||||||
def []=(i, v)
|
|
||||||
addr = _getp(i)
|
|
||||||
raise 'null pointer' if addr == 0
|
|
||||||
@_tg._at(addr)._set(v)
|
|
||||||
end
|
|
||||||
|
|
||||||
def inspect ; ptr = _getp ; (ptr == 0) ? 'NULL' : "#<PointerAry #{'0x%X' % ptr}>" ; end
|
|
||||||
end
|
|
||||||
module Enumerable
|
|
||||||
include ::Enumerable
|
|
||||||
attr_accessor :_indexenum
|
|
||||||
def each ; (0...length).each { |i| yield self[i] } ; end
|
|
||||||
def inspect
|
|
||||||
out = '['
|
|
||||||
each_with_index { |e, idx|
|
|
||||||
out << ', ' if out.length > 1
|
|
||||||
if out.length > INSPECT_SIZE_LIMIT
|
|
||||||
out << '...'
|
|
||||||
break
|
|
||||||
end
|
|
||||||
out << "#{_indexenum.to_sym(idx)}=" if _indexenum
|
|
||||||
out << e.inspect
|
|
||||||
}
|
|
||||||
out << ']'
|
|
||||||
end
|
|
||||||
def empty? ; length == 0 ; end
|
|
||||||
def flatten ; map { |e| e.respond_to?(:flatten) ? e.flatten : e }.flatten ; end
|
|
||||||
end
|
|
||||||
class StaticArray < MemStruct
|
|
||||||
attr_accessor :_tglen, :_length, :_indexenum, :_tg
|
|
||||||
def initialize(tglen, length, indexenum, tg)
|
|
||||||
@_tglen = tglen
|
|
||||||
@_length = length
|
|
||||||
@_indexenum = indexenum
|
|
||||||
@_tg = tg
|
|
||||||
end
|
|
||||||
def _set(a)
|
|
||||||
a.each_with_index { |v, i| self[i] = v }
|
|
||||||
end
|
|
||||||
def _cpp_init
|
|
||||||
_length.times { |i| _tgat(i)._cpp_init }
|
|
||||||
end
|
|
||||||
alias length _length
|
|
||||||
alias size _length
|
|
||||||
def _tgat(i)
|
|
||||||
@_tg._at(@_memaddr + i*@_tglen) if i >= 0 and i < @_length
|
|
||||||
end
|
|
||||||
def [](i)
|
|
||||||
i = _indexenum.to_i(i) if _indexenum
|
|
||||||
i += @_length if i < 0
|
|
||||||
_tgat(i)._get
|
|
||||||
end
|
|
||||||
def []=(i, v)
|
|
||||||
i = _indexenum.to_i(i) if _indexenum
|
|
||||||
i += @_length if i < 0
|
|
||||||
_tgat(i)._set(v)
|
|
||||||
end
|
|
||||||
|
|
||||||
include Enumerable
|
|
||||||
end
|
|
||||||
class StaticString < MemStruct
|
|
||||||
attr_accessor :_length
|
|
||||||
def initialize(length)
|
|
||||||
@_length = length
|
|
||||||
end
|
|
||||||
def _get
|
|
||||||
DFHack.memory_read(@_memaddr, @_length)
|
|
||||||
end
|
|
||||||
def _set(v)
|
|
||||||
DFHack.memory_write(@_memaddr, v[0, @_length])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class StlVector32 < MemStruct
|
|
||||||
attr_accessor :_tg
|
|
||||||
def initialize(tg)
|
|
||||||
@_tg = tg
|
|
||||||
end
|
|
||||||
|
|
||||||
def length
|
|
||||||
DFHack.memory_vector32_length(@_memaddr)
|
|
||||||
end
|
|
||||||
def size ; length ; end # alias wouldnt work for subclasses
|
|
||||||
def valueptr_at(idx)
|
|
||||||
DFHack.memory_vector32_ptrat(@_memaddr, idx)
|
|
||||||
end
|
|
||||||
def insert_at(idx, val)
|
|
||||||
DFHack.memory_vector32_insert(@_memaddr, idx, val)
|
|
||||||
end
|
|
||||||
def delete_at(idx)
|
|
||||||
DFHack.memory_vector32_delete(@_memaddr, idx)
|
|
||||||
end
|
|
||||||
|
|
||||||
def _set(v)
|
|
||||||
delete_at(length-1) while length > v.length # match lengthes
|
|
||||||
v.each_with_index { |e, i| self[i] = e } # patch entries
|
|
||||||
end
|
|
||||||
|
|
||||||
def _cpp_init
|
|
||||||
DFHack.memory_vector_init(@_memaddr)
|
|
||||||
end
|
|
||||||
|
|
||||||
def clear
|
|
||||||
delete_at(length-1) while length > 0
|
|
||||||
end
|
|
||||||
def [](idx)
|
|
||||||
idx += length if idx < 0
|
|
||||||
@_tg._at(valueptr_at(idx))._get if idx >= 0 and idx < length
|
|
||||||
end
|
|
||||||
def []=(idx, v)
|
|
||||||
idx += length if idx < 0
|
|
||||||
if idx >= length
|
|
||||||
insert_at(idx, 0)
|
|
||||||
elsif idx < 0
|
|
||||||
raise 'invalid idx'
|
|
||||||
end
|
|
||||||
@_tg._at(valueptr_at(idx))._set(v)
|
|
||||||
end
|
|
||||||
def push(v)
|
|
||||||
self[length] = v
|
|
||||||
self
|
|
||||||
end
|
|
||||||
def <<(v) ; push(v) ; end
|
|
||||||
def pop
|
|
||||||
l = length
|
|
||||||
if l > 0
|
|
||||||
v = self[l-1]
|
|
||||||
delete_at(l-1)
|
|
||||||
end
|
|
||||||
v
|
|
||||||
end
|
|
||||||
|
|
||||||
include Enumerable
|
|
||||||
# do a binary search in an ordered vector for a specific target attribute
|
|
||||||
# ex: world.history.figures.binsearch(unit.hist_figure_id)
|
|
||||||
def binsearch(target, field=:id)
|
|
||||||
o_start = 0
|
|
||||||
o_end = length - 1
|
|
||||||
while o_end >= o_start
|
|
||||||
o_half = o_start + (o_end-o_start)/2
|
|
||||||
obj = self[o_half]
|
|
||||||
oval = obj.send(field)
|
|
||||||
if oval == target
|
|
||||||
return obj
|
|
||||||
elsif oval < target
|
|
||||||
o_start = o_half+1
|
|
||||||
else
|
|
||||||
o_end = o_half-1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
class StlVector16 < StlVector32
|
|
||||||
def length
|
|
||||||
DFHack.memory_vector16_length(@_memaddr)
|
|
||||||
end
|
|
||||||
def valueptr_at(idx)
|
|
||||||
DFHack.memory_vector16_ptrat(@_memaddr, idx)
|
|
||||||
end
|
|
||||||
def insert_at(idx, val)
|
|
||||||
DFHack.memory_vector16_insert(@_memaddr, idx, val)
|
|
||||||
end
|
|
||||||
def delete_at(idx)
|
|
||||||
DFHack.memory_vector16_delete(@_memaddr, idx)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
class StlVector8 < StlVector32
|
|
||||||
def length
|
|
||||||
DFHack.memory_vector8_length(@_memaddr)
|
|
||||||
end
|
|
||||||
def valueptr_at(idx)
|
|
||||||
DFHack.memory_vector8_ptrat(@_memaddr, idx)
|
|
||||||
end
|
|
||||||
def insert_at(idx, val)
|
|
||||||
DFHack.memory_vector8_insert(@_memaddr, idx, val)
|
|
||||||
end
|
|
||||||
def delete_at(idx)
|
|
||||||
DFHack.memory_vector8_delete(@_memaddr, idx)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
class StlBitVector < StlVector32
|
|
||||||
def initialize ; end
|
|
||||||
def length
|
|
||||||
DFHack.memory_vectorbool_length(@_memaddr)
|
|
||||||
end
|
|
||||||
def insert_at(idx, val)
|
|
||||||
DFHack.memory_vectorbool_insert(@_memaddr, idx, val)
|
|
||||||
end
|
|
||||||
def delete_at(idx)
|
|
||||||
DFHack.memory_vectorbool_delete(@_memaddr, idx)
|
|
||||||
end
|
|
||||||
def [](idx)
|
|
||||||
idx += length if idx < 0
|
|
||||||
DFHack.memory_vectorbool_at(@_memaddr, idx) if idx >= 0 and idx < length
|
|
||||||
end
|
|
||||||
def []=(idx, v)
|
|
||||||
idx += length if idx < 0
|
|
||||||
if idx >= length
|
|
||||||
insert_at(idx, v)
|
|
||||||
elsif idx < 0
|
|
||||||
raise 'invalid idx'
|
|
||||||
else
|
|
||||||
DFHack.memory_vectorbool_setat(@_memaddr, idx, v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
class StlString < MemStruct
|
|
||||||
def _get
|
|
||||||
DFHack.memory_read_stlstring(@_memaddr)
|
|
||||||
end
|
|
||||||
|
|
||||||
def _set(v)
|
|
||||||
DFHack.memory_write_stlstring(@_memaddr, v)
|
|
||||||
end
|
|
||||||
|
|
||||||
def _cpp_init
|
|
||||||
DFHack.memory_stlstring_init(@_memaddr)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
class StlDeque < MemStruct
|
|
||||||
attr_accessor :_tglen, :_tg
|
|
||||||
def initialize(tglen, tg)
|
|
||||||
@_tglen = tglen
|
|
||||||
@_tg = tg
|
|
||||||
end
|
|
||||||
# XXX DF uses stl::deque<some_struct>, so to have a C binding we'd need to single-case every
|
|
||||||
# possible struct size, like for StlVector. Just ignore it for now, deque are rare enough.
|
|
||||||
def inspect ; "#<StlDeque>" ; end
|
|
||||||
end
|
|
||||||
|
|
||||||
class DfFlagarray < MemStruct
|
|
||||||
attr_accessor :_indexenum
|
|
||||||
def initialize(indexenum)
|
|
||||||
@_indexenum = indexenum
|
|
||||||
end
|
|
||||||
def length
|
|
||||||
DFHack.memory_bitarray_length(@_memaddr)
|
|
||||||
end
|
|
||||||
# TODO _cpp_init
|
|
||||||
def size ; length ; end
|
|
||||||
def resize(len)
|
|
||||||
DFHack.memory_bitarray_resize(@_memaddr, len)
|
|
||||||
end
|
|
||||||
def [](idx)
|
|
||||||
idx = _indexenum.to_i(idx) if _indexenum
|
|
||||||
idx += length if idx < 0
|
|
||||||
DFHack.memory_bitarray_isset(@_memaddr, idx) if idx >= 0 and idx < length
|
|
||||||
end
|
|
||||||
def []=(idx, v)
|
|
||||||
idx = _indexenum.to_i(idx) if _indexenum
|
|
||||||
idx += length if idx < 0
|
|
||||||
if idx >= length or idx < 0
|
|
||||||
raise 'invalid idx'
|
|
||||||
else
|
|
||||||
DFHack.memory_bitarray_set(@_memaddr, idx, v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
include Enumerable
|
|
||||||
end
|
|
||||||
class DfArray < Compound
|
|
||||||
attr_accessor :_tglen, :_tg
|
|
||||||
def initialize(tglen, tg)
|
|
||||||
@_tglen = tglen
|
|
||||||
@_tg = tg
|
|
||||||
end
|
|
||||||
|
|
||||||
field(:_ptr, 0) { number 32, false }
|
|
||||||
field(:_length, 4) { number 16, false }
|
|
||||||
|
|
||||||
def length ; _length ; end
|
|
||||||
def size ; _length ; end
|
|
||||||
# TODO _cpp_init
|
|
||||||
def _tgat(i)
|
|
||||||
@_tg._at(_ptr + i*@_tglen) if i >= 0 and i < _length
|
|
||||||
end
|
|
||||||
def [](i)
|
|
||||||
i += _length if i < 0
|
|
||||||
_tgat(i)._get
|
|
||||||
end
|
|
||||||
def []=(i, v)
|
|
||||||
i += _length if i < 0
|
|
||||||
_tgat(i)._set(v)
|
|
||||||
end
|
|
||||||
def _set(a)
|
|
||||||
a.each_with_index { |v, i| self[i] = v }
|
|
||||||
end
|
|
||||||
|
|
||||||
include Enumerable
|
|
||||||
end
|
|
||||||
class DfLinkedList < Compound
|
|
||||||
attr_accessor :_tg
|
|
||||||
def initialize(tg)
|
|
||||||
@_tg = tg
|
|
||||||
end
|
|
||||||
|
|
||||||
field(:_ptr, 0) { number 32, false }
|
|
||||||
field(:_prev, 4) { number 32, false }
|
|
||||||
field(:_next, 8) { number 32, false }
|
|
||||||
|
|
||||||
def item
|
|
||||||
# With the current xml structure, currently _tg designate
|
|
||||||
# the type of the 'next' and 'prev' fields, not 'item'.
|
|
||||||
# List head has item == NULL, so we can safely return nil.
|
|
||||||
|
|
||||||
#addr = _ptr
|
|
||||||
#return if addr == 0
|
|
||||||
#@_tg._at(addr)._get
|
|
||||||
end
|
|
||||||
|
|
||||||
def item=(v)
|
|
||||||
#addr = _ptr
|
|
||||||
#raise 'null pointer' if addr == 0
|
|
||||||
#@_tg.at(addr)._set(v)
|
|
||||||
raise 'null pointer'
|
|
||||||
end
|
|
||||||
|
|
||||||
def prev
|
|
||||||
addr = _prev
|
|
||||||
return if addr == 0
|
|
||||||
@_tg._at(addr)._get
|
|
||||||
end
|
|
||||||
|
|
||||||
def next
|
|
||||||
addr = _next
|
|
||||||
return if addr == 0
|
|
||||||
@_tg._at(addr)._get
|
|
||||||
end
|
|
||||||
|
|
||||||
include Enumerable
|
|
||||||
def each
|
|
||||||
o = self
|
|
||||||
while o
|
|
||||||
yield o.item if o.item
|
|
||||||
o = o.next
|
|
||||||
end
|
|
||||||
end
|
|
||||||
def inspect ; "#<DfLinkedList #{item.inspect} prev=#{'0x%X' % _prev} next=#{'0x%X' % _next}>" ; end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Global < MemStruct
|
|
||||||
attr_accessor :_glob
|
|
||||||
def initialize(glob)
|
|
||||||
@_glob = glob
|
|
||||||
end
|
|
||||||
def _at(addr)
|
|
||||||
g = DFHack.const_get(@_glob)
|
|
||||||
g = DFHack.rtti_getclassat(g, addr)
|
|
||||||
g.new._at(addr)
|
|
||||||
end
|
|
||||||
def inspect ; "#<#{@_glob}>" ; end
|
|
||||||
end
|
|
||||||
end # module MemHack
|
|
||||||
|
|
||||||
|
|
||||||
# cpp rtti name -> rb class
|
|
||||||
@rtti_n2c = {}
|
|
||||||
@rtti_c2n = {}
|
|
||||||
|
|
||||||
# cpp rtti name -> vtable ptr
|
|
||||||
@rtti_n2v = {}
|
|
||||||
@rtti_v2n = {}
|
|
||||||
|
|
||||||
def self.rtti_n2c ; @rtti_n2c ; end
|
|
||||||
def self.rtti_c2n ; @rtti_c2n ; end
|
|
||||||
def self.rtti_n2v ; @rtti_n2v ; end
|
|
||||||
def self.rtti_v2n ; @rtti_v2n ; end
|
|
||||||
|
|
||||||
# register a ruby class with a cpp rtti class name
|
|
||||||
def self.rtti_register(cppname, cls)
|
|
||||||
@rtti_n2c[cppname] = cls
|
|
||||||
@rtti_c2n[cls] = cppname
|
|
||||||
end
|
|
||||||
|
|
||||||
# return the ruby class to use for the cpp object at address if rtti info is available
|
|
||||||
def self.rtti_getclassat(cls, addr)
|
|
||||||
if addr != 0 and @rtti_c2n[cls]
|
|
||||||
# rtti info exist for class => cpp object has a vtable
|
|
||||||
@rtti_n2c[rtti_readclassname(get_vtable_ptr(addr))] || cls
|
|
||||||
else
|
|
||||||
cls
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# try to read the rtti classname from an object vtable pointer
|
|
||||||
def self.rtti_readclassname(vptr)
|
|
||||||
unless n = @rtti_v2n[vptr]
|
|
||||||
n = @rtti_v2n[vptr] = get_rtti_classname(vptr).to_sym
|
|
||||||
@rtti_n2v[n] = vptr
|
|
||||||
end
|
|
||||||
n
|
|
||||||
end
|
|
||||||
|
|
||||||
# return the vtable pointer from the cpp rtti name
|
|
||||||
def self.rtti_getvtable(cppname)
|
|
||||||
unless v = @rtti_n2v[cppname]
|
|
||||||
v = get_vtable(cppname.to_s)
|
|
||||||
@rtti_n2v[cppname] = v
|
|
||||||
@rtti_v2n[v] = cppname if v != 0
|
|
||||||
end
|
|
||||||
v if v != 0
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.vmethod_call(obj, voff, a0=0, a1=0, a2=0, a3=0, a4=0)
|
|
||||||
vmethod_do_call(obj._memaddr, voff, vmethod_arg(a0), vmethod_arg(a1), vmethod_arg(a2), vmethod_arg(a3))
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.vmethod_arg(arg)
|
|
||||||
case arg
|
|
||||||
when nil, false; 0
|
|
||||||
when true; 1
|
|
||||||
when Integer; arg
|
|
||||||
#when String; [arg].pack('p').unpack('L')[0] # raw pointer to buffer
|
|
||||||
when MemHack::Compound; arg._memaddr
|
|
||||||
else raise "bad vmethod arg #{arg.class}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
@ -1 +1 @@
|
|||||||
Subproject commit 37a823541538023b9f3d0d1e8039cf32851de68d
|
Subproject commit 17b653665567a5f1df628217820f76bb0b9c70a5
|
@ -0,0 +1,16 @@
|
|||||||
|
-- Deletes ALL items not held by units, buildings or jobs.
|
||||||
|
--
|
||||||
|
-- Intended solely for lag investigation.
|
||||||
|
|
||||||
|
local count = 0
|
||||||
|
|
||||||
|
for _,v in ipairs(df.global.world.items.all) do
|
||||||
|
if not (v.flags.in_building or v.flags.construction or v.flags.in_job
|
||||||
|
or dfhack.items.getGeneralRef(v,df.general_ref_type.UNIT_HOLDER)) then
|
||||||
|
count = count + 1
|
||||||
|
v.flags.forbid = true
|
||||||
|
v.flags.garbage_collect = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print('Deletion requested: '..count)
|
@ -0,0 +1,29 @@
|
|||||||
|
-- Remove uninteresting dead units from the unit list.
|
||||||
|
|
||||||
|
local units = df.global.world.units.active
|
||||||
|
local dwarf_race = df.global.ui.race_id
|
||||||
|
local dwarf_civ = df.global.ui.civ_id
|
||||||
|
local count = 0
|
||||||
|
|
||||||
|
for i=#units-1,0,-1 do
|
||||||
|
local unit = units[i]
|
||||||
|
local flags1 = unit.flags1
|
||||||
|
local flags2 = unit.flags2
|
||||||
|
if flags1.dead and unit.race ~= dwarf_race then
|
||||||
|
local remove = false
|
||||||
|
if flags2.slaughter then
|
||||||
|
remove = true
|
||||||
|
elseif not unit.name.has_name then
|
||||||
|
remove = true
|
||||||
|
elseif unit.civ_id ~= dwarf_civ and
|
||||||
|
not (flags1.merchant or flags1.diplomat) then
|
||||||
|
remove = true
|
||||||
|
end
|
||||||
|
if remove then
|
||||||
|
count = count + 1
|
||||||
|
units:erase(i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print('Units removed from active: '..count)
|
@ -0,0 +1,24 @@
|
|||||||
|
-- Makes fat dwarves non-fat.
|
||||||
|
--
|
||||||
|
-- See for more info:
|
||||||
|
-- http://www.bay12games.com/dwarves/mantisbt/view.php?id=5971
|
||||||
|
|
||||||
|
local num_fat = 0
|
||||||
|
local num_lagging = 0
|
||||||
|
|
||||||
|
for _,v in ipairs(df.global.world.units.all) do
|
||||||
|
local fat = v.counters2.stored_fat
|
||||||
|
if fat > 850000 then
|
||||||
|
v.counters2.stored_fat = 500000
|
||||||
|
if v.race == df.global.ui.race_id then
|
||||||
|
print(fat,dfhack.TranslateName(dfhack.units.getVisibleName(v)))
|
||||||
|
num_fat = num_fat + 1
|
||||||
|
if fat > 999990 then
|
||||||
|
num_lagging = num_lagging + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print("Fat dwarves cured: "..num_fat)
|
||||||
|
print("Lag sources: "..num_lagging)
|
@ -0,0 +1,49 @@
|
|||||||
|
-- Reset item temperature to the value of their tile.
|
||||||
|
|
||||||
|
local count = 0
|
||||||
|
local types = {}
|
||||||
|
|
||||||
|
local function update_temp(item,btemp)
|
||||||
|
if item.temperature ~= btemp then
|
||||||
|
count = count + 1
|
||||||
|
local tid = item:getType()
|
||||||
|
types[tid] = (types[tid] or 0) + 1
|
||||||
|
end
|
||||||
|
item.temperature = btemp
|
||||||
|
item.temperature_fraction = 0
|
||||||
|
|
||||||
|
if item.contaminants then
|
||||||
|
for _,c in ipairs(item.contaminants) do
|
||||||
|
c.temperature = btemp
|
||||||
|
c.temperature_fraction = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _,sub in ipairs(dfhack.items.getContainedItems(item)) do
|
||||||
|
update_temp(sub,btemp)
|
||||||
|
end
|
||||||
|
|
||||||
|
item:checkTemperatureDamage()
|
||||||
|
end
|
||||||
|
|
||||||
|
local last_frame = df.global.world.frame_counter-1
|
||||||
|
|
||||||
|
for _,item in ipairs(df.global.world.items.all) do
|
||||||
|
if item.flags.on_ground and df.item_actual:is_instance(item) and
|
||||||
|
item.temp_updated_frame == last_frame then
|
||||||
|
local pos = item.pos
|
||||||
|
local block = dfhack.maps.getTileBlock(pos)
|
||||||
|
if block then
|
||||||
|
update_temp(item, block.temperature_1[pos.x%16][pos.y%16])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print('Items updated: '..count)
|
||||||
|
|
||||||
|
local tlist = {}
|
||||||
|
for k,_ in pairs(types) do tlist[#tlist+1] = k end
|
||||||
|
table.sort(tlist, function(a,b) return types[a] > types[b] end)
|
||||||
|
for _,k in ipairs(tlist) do
|
||||||
|
print(' '..df.item_type[k]..':', types[k])
|
||||||
|
end
|
Loading…
Reference in New Issue