1717#include " modules/World.h"
1818
1919DFHACK_PLUGIN (" design" );
20- DFHACK_PLUGIN_IS_ENABLED (is_enabled);
2120using DFHack::color_value;
2221
2322REQUIRE_GLOBAL (window_x);
@@ -27,36 +26,37 @@ REQUIRE_GLOBAL(plotinfo);
2726using namespace DFHack ;
2827using namespace df ::enums;
2928
30- enum ConfigValues {
31- CONFIG_IS_ENABLED = 0 ,
32- };
33-
3429namespace DFHack {
35- DBG_DECLARE (pathable , log, DebugCategory::LINFO );
30+ DBG_DECLARE (design , log, DebugCategory::LINFO );
3631}
3732
38- DFhackCExport command_result plugin_init (color_ostream &out, std::vector<PluginCommand> &commands) {
33+ DFhackCExport command_result plugin_init (color_ostream &out,
34+ std::vector<PluginCommand> &commands) {
3935 return CR_OK ;
4036}
4137
42- DFhackCExport command_result plugin_shutdown (color_ostream &out) {
38+ std::map<uint32_t , Screen::Pen> PENS ;
39+
40+ DFhackCExport command_result plugin_onstatechange (color_ostream &out, state_change_event event) {
41+ if (event == DFHack::SC_WORLD_UNLOADED ) {
42+ DEBUG (log,out).print (" clearing PENS\n " );
43+ PENS .clear ();
44+ }
4345 return CR_OK ;
4446}
4547
46- std::map<uint32_t , Screen::Pen> PENS ;
47-
4848struct DrawingPoint {
49- uint32_t penKey = 0 ;
50- std::pair<int , int > cursor_coords;
49+ uint32_t penKey = 0 ;
50+ std::pair<int , int > cursor_coords;
5151
52- DrawingPoint () : penKey(0 ), cursor_coords({-1 , -1 }) {}
52+ DrawingPoint () : penKey(0 ), cursor_coords({-1 , -1 }) {}
5353};
5454
5555typedef std::map<int , std::map<int , DrawingPoint>> ShapeMap;
5656ShapeMap arr;
5757
5858bool has_point (int x, int y) {
59- return arr.count (x) != 0 && arr.at (x).count (y) != 0 ;
59+ return arr.count (x) != 0 && arr.at (x).count (y) != 0 ;
6060};
6161
6262// Key tuple is N, W, E, S
@@ -81,188 +81,187 @@ std::map<DirectionKey, std::pair<int, int>> CURSORS_MAP = {
8181};
8282
8383enum PenMask {
84- North = 0 ,
85- South,
86- East,
87- West,
88- DragPoint,
89- MouseOver,
90- InShape,
91- ExtraPoint,
92- NumFlags
84+ North = 0 ,
85+ South,
86+ East,
87+ West,
88+ DragPoint,
89+ MouseOver,
90+ InShape,
91+ ExtraPoint,
92+ NumFlags
9393};
9494
9595uint32_t gen_pen_key (bool n, bool s, bool e, bool w, bool is_drag_point,
9696 bool is_mouse_over, bool inshape, bool extra_point) {
97- std::bitset<static_cast <size_t >(PenMask::NumFlags)> ret;
98- ret[PenMask::North] = n;
99- ret[PenMask::South] = s;
100- ret[PenMask::East] = e;
101- ret[PenMask::West] = w;
102- ret[PenMask::DragPoint] = is_drag_point;
103- ret[PenMask::MouseOver] = is_mouse_over;
104- ret[PenMask::InShape] = inshape;
105- ret[PenMask::ExtraPoint] = extra_point;
106-
107- return ret.to_ulong ();
97+ std::bitset<static_cast <size_t >(PenMask::NumFlags)> ret;
98+ ret[PenMask::North] = n;
99+ ret[PenMask::South] = s;
100+ ret[PenMask::East] = e;
101+ ret[PenMask::West] = w;
102+ ret[PenMask::DragPoint] = is_drag_point;
103+ ret[PenMask::MouseOver] = is_mouse_over;
104+ ret[PenMask::InShape] = inshape;
105+ ret[PenMask::ExtraPoint] = extra_point;
106+
107+ return ret.to_ulong ();
108108}
109109
110110Screen::Pen make_pen (const std::pair<int , int > &direction, bool is_drag_point,
111111 bool is_mouse_over, bool inshape, bool extra_point) {
112- color_value color = COLOR_GREEN ;
113- int ycursor_mod = 0 ;
114-
115- if (!extra_point) {
116- if (is_drag_point) {
117- color = COLOR_CYAN ;
118- ycursor_mod += 6 ;
119- if (is_mouse_over) {
120- color = COLOR_MAGENTA ;
121- ycursor_mod += 3 ;
122- }
123- }
124- } else {
125- ycursor_mod += 15 ;
126- color = COLOR_LIGHTRED ;
112+ color_value color = COLOR_GREEN ;
113+ int ycursor_mod = 0 ;
114+
115+ if (!extra_point) {
116+ if (is_drag_point) {
117+ color = COLOR_CYAN ;
118+ ycursor_mod += 6 ;
119+ if (is_mouse_over) {
120+ color = COLOR_MAGENTA ;
121+ ycursor_mod += 3 ;
122+ }
123+ }
124+ } else {
125+ ycursor_mod += 15 ;
126+ color = COLOR_LIGHTRED ;
127127
128- if (is_mouse_over) {
129- color = COLOR_RED ;
130- ycursor_mod += 3 ;
128+ if (is_mouse_over) {
129+ color = COLOR_RED ;
130+ ycursor_mod += 3 ;
131+ }
131132 }
132- }
133-
134- Screen::Pen pen;
135- pen.ch = inshape ? ' X' : ' o' ;
136- pen.fg = color;
137- int selected_tile_texpos = 0 ;
138- Screen::findGraphicsTile (" CURSORS" , direction.first ,
139- direction.second + ycursor_mod,
140- &selected_tile_texpos);
141- pen.tile = selected_tile_texpos;
142-
143- return pen;
133+
134+ Screen::Pen pen;
135+ pen.ch = inshape ? ' X' : ' o' ;
136+ pen.fg = color;
137+ int selected_tile_texpos = 0 ;
138+ Screen::findGraphicsTile (" CURSORS" , direction.first ,
139+ direction.second + ycursor_mod,
140+ &selected_tile_texpos);
141+ pen.tile = selected_tile_texpos;
142+
143+ return pen;
144144}
145145
146146Screen::Pen get_pen (int x, int y, ShapeMap &arr, const std::string &type = " " ) {
147- bool n = false , w = false , e = false , s = false ;
148- if (has_point (x, y)) {
149- if (y == 0 || !has_point (x, y - 1 )) n = true ;
150- if (x == 0 || !has_point (x - 1 , y)) w = true ;
151- if (!has_point (x + 1 , y)) e = true ; // TODO check map size
152- if (!has_point (x, y + 1 )) s = true ; // TODO check map size
153- }
154-
155- bool is_drag_point = type == " drag_point" ;
156- bool is_extra = type == " extra_point" ;
157- bool is_in_shape = has_point (x, y);
158- auto mouse_pos = Gui::getMousePos ();
159- bool mouse_over = mouse_pos.x == x && mouse_pos.y == y;
160-
161- uint32_t pen_key =
162- gen_pen_key (n, s, e, w, is_drag_point, mouse_over, is_in_shape, is_extra);
163-
164- if (CURSORS_MAP .count ({n, w, e, s}) > 0 && has_point (x,y)) {
165- arr[x][y].cursor_coords = CURSORS_MAP .at ({n, w, e, s});
166- }
167-
168- if (PENS .find (pen_key) == PENS .end ()) {
169- std::pair<int , int > cursor{-1 , -1 };
170-
171- if (type != " " ) {
172- return make_pen (CURSORS_MAP .at ({n, w, e, s}), is_drag_point, mouse_over,
173- is_in_shape, is_extra);
147+ bool n = false , w = false , e = false , s = false ;
148+ if (has_point (x, y)) {
149+ if (y == 0 || !has_point (x, y - 1 )) n = true ;
150+ if (x == 0 || !has_point (x - 1 , y)) w = true ;
151+ if (!has_point (x + 1 , y)) e = true ; // TODO check map size
152+ if (!has_point (x, y + 1 )) s = true ; // TODO check map size
153+ }
154+
155+ bool is_drag_point = type == " drag_point" ;
156+ bool is_extra = type == " extra_point" ;
157+ bool is_in_shape = has_point (x, y);
158+ auto mouse_pos = Gui::getMousePos ();
159+ bool mouse_over = mouse_pos.x == x && mouse_pos.y == y;
160+
161+ uint32_t pen_key = gen_pen_key (n, s, e, w, is_drag_point, mouse_over,
162+ is_in_shape, is_extra);
163+
164+ if (CURSORS_MAP .count ({n, w, e, s}) > 0 && has_point (x, y)) {
165+ arr[x][y].cursor_coords = CURSORS_MAP .at ({n, w, e, s});
174166 }
175167
176- if (CURSORS_MAP .count ({n, w, e, s}) > 0 ) {
177- PENS .emplace (pen_key,
178- make_pen (CURSORS_MAP .at ({n, w, e, s}), is_drag_point,
179- mouse_over, is_in_shape, is_extra));
180- if (type == " " && has_point (x,y)) {
181- arr[x][y].penKey = pen_key;
182- }
168+ if (PENS .find (pen_key) == PENS .end ()) {
169+ std::pair<int , int > cursor{-1 , -1 };
170+
171+ if (type != " " ) {
172+ return make_pen (CURSORS_MAP .at ({n, w, e, s}), is_drag_point,
173+ mouse_over, is_in_shape, is_extra);
174+ }
175+
176+ if (CURSORS_MAP .count ({n, w, e, s}) > 0 ) {
177+ PENS .emplace (pen_key,
178+ make_pen (CURSORS_MAP .at ({n, w, e, s}), is_drag_point,
179+ mouse_over, is_in_shape, is_extra));
180+ if (type == " " && has_point (x, y)) {
181+ arr[x][y].penKey = pen_key;
182+ }
183+ }
183184 }
184- }
185185
186- // DEBUG(status).print("not cached lmao\n");
187- return PENS .at (pen_key);
186+ return PENS .at (pen_key);
188187}
189188
190189static int design_load_shape (lua_State *L) {
191- if (lua_istable (L, -1 )) {
192- lua_pushnil (L);
193- while (lua_next (L, -2 ) != 0 ) {
194- int x = lua_tointeger (L, -2 );
195-
196- if (lua_istable (L, -1 )) {
190+ if (lua_istable (L, -1 )) {
197191 lua_pushnil (L);
198192 while (lua_next (L, -2 ) != 0 ) {
199- int y = lua_tointeger (L, -2 );
200- bool value = lua_toboolean (L, -1 );
201-
202- if (value) {
203- arr[x][y] = DrawingPoint ();
204- }
205- lua_pop (L, 1 );
193+ int x = lua_tointeger (L, -2 );
194+
195+ if (lua_istable (L, -1 )) {
196+ lua_pushnil (L);
197+ while (lua_next (L, -2 ) != 0 ) {
198+ int y = lua_tointeger (L, -2 );
199+ bool value = lua_toboolean (L, -1 );
200+
201+ if (value) {
202+ arr[x][y] = DrawingPoint ();
203+ }
204+ lua_pop (L, 1 );
205+ }
206+ }
207+ lua_pop (L, 1 );
206208 }
207- }
208- lua_pop (L, 1 );
209209 }
210- }
211210
212- return 0 ;
211+ return 0 ;
213212}
214213
215214static int design_clear_shape (lua_State *L) {
216- arr.clear ();
215+ arr.clear ();
217216
218- return 0 ;
217+ return 0 ;
219218}
220219
221220static int design_draw_shape (lua_State *L) {
222- if (arr.size () == 0 ) {
223- design_load_shape (L);
224- }
225-
226- for (auto x : arr) {
227- for (auto y : x.second ) {
228- Screen::Pen cur_tile = Screen::readTile (x.first , y.first , true );
229- Screen::Pen pen = get_pen (x.first , y.first , arr);
230- cur_tile.tile = pen.tile ;
231- Screen::paintTile (cur_tile, x.first - *window_x, y.first - *window_y,
232- true );
221+ if (arr.size () == 0 ) {
222+ design_load_shape (L);
223+ }
224+
225+ for (auto x : arr) {
226+ for (auto y : x.second ) {
227+ Screen::Pen cur_tile = Screen::readTile (x.first , y.first , true );
228+ Screen::Pen pen = get_pen (x.first , y.first , arr);
229+ cur_tile.tile = pen.tile ;
230+ Screen::paintTile (cur_tile, x.first - *window_x,
231+ y.first - *window_y, true );
232+ }
233233 }
234- }
235234
236- return 0 ;
235+ return 0 ;
237236}
238237
239238static int design_draw_points (lua_State *L) {
240- if (lua_istable (L, -1 )) {
241- const char *str;
242- lua_rawgeti (L, -1 , 2 );
243- str = lua_tostring (L, -1 );
244- lua_pop (L, 1 );
245-
246- lua_rawgeti (L, -1 , 1 );
247- int n = luaL_len (L, -1 );
248- for (int i = 1 ; i <= n; i++) {
249- lua_rawgeti (L, -1 , i);
250- int x, y;
251- lua_getfield (L, -1 , " y" );
252- y = lua_tointeger (L, -1 );
253- lua_getfield (L, -2 , " x" );
254- x = lua_tointeger (L, -1 );
255- lua_pop (L, 3 );
256-
257- Screen::Pen cur_tile = Screen::readTile (x, y, true );
258- Screen::Pen pen = get_pen (x, y, arr, str);
259- cur_tile.tile = pen.tile ;
260- Screen::paintTile (cur_tile, x - *window_x, y - *window_y, true );
239+ if (lua_istable (L, -1 )) {
240+ const char *str;
241+ lua_rawgeti (L, -1 , 2 );
242+ str = lua_tostring (L, -1 );
243+ lua_pop (L, 1 );
244+
245+ lua_rawgeti (L, -1 , 1 );
246+ int n = luaL_len (L, -1 );
247+ for (int i = 1 ; i <= n; i++) {
248+ lua_rawgeti (L, -1 , i);
249+ int x, y;
250+ lua_getfield (L, -1 , " y" );
251+ y = lua_tointeger (L, -1 );
252+ lua_getfield (L, -2 , " x" );
253+ x = lua_tointeger (L, -1 );
254+ lua_pop (L, 3 );
255+
256+ Screen::Pen cur_tile = Screen::readTile (x, y, true );
257+ Screen::Pen pen = get_pen (x, y, arr, str);
258+ cur_tile.tile = pen.tile ;
259+ Screen::paintTile (cur_tile, x - *window_x, y - *window_y, true );
260+ }
261+ lua_pop (L, 1 );
261262 }
262- lua_pop (L, 1 );
263- }
264263
265- return 0 ;
264+ return 0 ;
266265}
267266
268267DFHACK_PLUGIN_LUA_COMMANDS {DFHACK_LUA_COMMAND (design_draw_shape),
0 commit comments