20
20
#include " df/tile_building_occ.h"
21
21
#include " df/building_drawbuffer.h"
22
22
#include " df/general_ref_creaturest.h" // needed for power information storage
23
+ #include " df/building_def_workshopst.h"
23
24
#include " modules/Buildings.h"
24
25
25
26
#include < map>
@@ -46,19 +47,19 @@ struct graphic_tile //could do just 31x31 and be done, but it's nicer to have fl
46
47
};
47
48
struct workshop_hack_data
48
49
{
49
- int32_t myType;
50
- bool impassible_fix;
50
+ bool impassible_fix = false ;
51
51
// machine stuff
52
+ bool is_machine = false ;
52
53
df::machine_tile_set connections;
53
54
df::power_info powerInfo;
54
55
bool needs_power;
55
56
// animation
56
57
std::vector<std::vector<graphic_tile> > frames;
57
- bool machine_timing; // 6 frames used in vanilla
58
+ bool machine_timing= false ; // 6 frames used in vanilla
58
59
int frame_skip; // e.g. 2 means have to ticks between frames
59
60
// updateCallback:
60
- int skip_updates;
61
- int room_subset; // 0 no, 1 yes, -1 default
61
+ int skip_updates= 0 ;
62
+ int room_subset=- 1 ; // 0 no, 1 yes, -1 default
62
63
};
63
64
typedef std::map<int32_t ,workshop_hack_data> workshops_data_t ;
64
65
workshops_data_t hacked_workshops;
@@ -94,6 +95,7 @@ struct work_hook : df::building_workshopst{
94
95
if (workshop_hack_data* def = find_def ())
95
96
{
96
97
df::general_ref_creaturest* ref = static_cast <df::general_ref_creaturest*>(DFHack::Buildings::getGeneralRef (this , general_ref_type::CREATURE));
98
+ // try getting ref, if not return from definition
97
99
if (ref)
98
100
{
99
101
info->produced = ref->unk_1 ;
@@ -106,7 +108,6 @@ struct work_hook : df::building_workshopst{
106
108
info->consumed = def->powerInfo .consumed ;
107
109
return true ;
108
110
}
109
- // try getting ref, if not return from def
110
111
}
111
112
return false ;
112
113
}
@@ -124,6 +125,7 @@ struct work_hook : df::building_workshopst{
124
125
}
125
126
}
126
127
df::general_ref_creaturest* ref = static_cast <df::general_ref_creaturest*>(DFHack::Buildings::getGeneralRef (this , general_ref_type::CREATURE));
128
+ // if we have a setting then update it, else create a new ref for dynamic power tracking
127
129
if (ref)
128
130
{
129
131
ref->unk_1 = produced;
@@ -149,7 +151,8 @@ struct work_hook : df::building_workshopst{
149
151
150
152
DEFINE_VMETHOD_INTERPOSE (void , getPowerInfo, (df::power_info *info))
151
153
{
152
- if (find_def ())
154
+ auto def = find_def ();
155
+ if (def && def->is_machine )
153
156
{
154
157
df::power_info power;
155
158
get_current_power (info);
@@ -159,7 +162,8 @@ struct work_hook : df::building_workshopst{
159
162
}
160
163
DEFINE_VMETHOD_INTERPOSE (df::machine_info*, getMachineInfo, ())
161
164
{
162
- if (find_def ())
165
+ auto def = find_def ();
166
+ if (def && def->is_machine )
163
167
return &machine;
164
168
165
169
return INTERPOSE_NEXT (getMachineInfo)();
@@ -176,7 +180,8 @@ struct work_hook : df::building_workshopst{
176
180
}
177
181
DEFINE_VMETHOD_INTERPOSE (void , categorize, (bool free))
178
182
{
179
- if (find_def ())
183
+ auto def = find_def ();
184
+ if (def && def->is_machine )
180
185
{
181
186
auto &vec = world->buildings .other [buildings_other_id::ANY_MACHINE];
182
187
insert_into_vector (vec, &df::building::id, (df::building*)this );
@@ -187,7 +192,8 @@ struct work_hook : df::building_workshopst{
187
192
188
193
DEFINE_VMETHOD_INTERPOSE (void , uncategorize, ())
189
194
{
190
- if (find_def ())
195
+ auto def = find_def ();
196
+ if (def && def->is_machine )
191
197
{
192
198
auto &vec = world->buildings .other [buildings_other_id::ANY_MACHINE];
193
199
erase_from_vector (vec, &df::building::id, id);
@@ -197,8 +203,10 @@ struct work_hook : df::building_workshopst{
197
203
}
198
204
DEFINE_VMETHOD_INTERPOSE (bool , canConnectToMachine, (df::machine_tile_set *info))
199
205
{
200
- if (auto def = find_def ())
206
+ auto def = find_def ();
207
+ if (def && def->is_machine )
201
208
{
209
+
202
210
int real_cx = centerx, real_cy = centery;
203
211
bool ok = false ;
204
212
@@ -341,7 +349,26 @@ IMPLEMENT_VMETHOD_INTERPOSE(work_hook, setTriggerState);
341
349
IMPLEMENT_VMETHOD_INTERPOSE (work_hook, drawBuilding);
342
350
343
351
344
-
352
+ int get_workshop_type (lua_State* L,int arg)
353
+ {
354
+ size_t len;
355
+ int is_num;
356
+ int type;
357
+ type=lua_tointegerx (L, arg, &is_num);
358
+ if (is_num)
359
+ {
360
+ return type;
361
+ }
362
+ auto str = lua_tolstring (L, arg, &len);
363
+ const auto & raws = world->raws .buildings .workshops ;
364
+ for (size_t i=0 ;i<raws.size ();i++)
365
+ {
366
+ if (raws[i]->code == str)
367
+ return raws[i]->id ;
368
+ }
369
+ luaL_argerror (L, arg, " expected int or string workshop id" );
370
+ return 0 ;
371
+ }
345
372
void clear_mapping ()
346
373
{
347
374
hacked_workshops.clear ();
@@ -415,58 +442,91 @@ static void loadFrames(lua_State* L,workshop_hack_data& def,int stack_pos)
415
442
416
443
return ;
417
444
}
418
- // arguments: custom type,impassible fix (bool), consumed power, produced power, list of connection points, update skip(0/nil to disable)
419
- // table of frames,frame to tick ratio (-1 for machine control)
420
- static int addBuilding (lua_State* L)
445
+
446
+ // fixImpassible(workshop_type,bool) - changes how impassible tiles work with liquids. False - default behaviour. True - blocks liquids.
447
+ static int fixImpassible (lua_State* L)
448
+ {
449
+ int workshop_type = get_workshop_type (L, 1 );
450
+ bool impassible_setting = lua_toboolean (L, 2 );
451
+
452
+ auto & def = hacked_workshops[workshop_type];
453
+ def.impassible_fix = impassible_setting;
454
+ return 0 ;
455
+ }
456
+ // setMachineInfo(workshop_type,bool needs_power,int power_consumed=0,int power_produced=0,table [x=int,y=int] connection_points) -setups and enables machine (i.e. connected to gears, and co) behaviour of the building
457
+ static int setMachineInfo (lua_State* L)
421
458
{
422
- workshop_hack_data newDefinition;
423
- newDefinition.myType =luaL_checkint (L,1 );
424
- newDefinition.impassible_fix =luaL_checkint (L,2 );
425
- newDefinition.powerInfo .consumed =luaL_checkint (L,3 );
426
- newDefinition.powerInfo .produced =luaL_checkint (L,4 );
427
- newDefinition.needs_power = luaL_optinteger (L, 5 , 1 );
459
+ int workshop_type = get_workshop_type (L, 1 );
460
+ auto & def = hacked_workshops[workshop_type];
461
+ def.is_machine = true ;
462
+
463
+ def.needs_power = lua_toboolean (L, 2 );
464
+ def.powerInfo .consumed = luaL_optinteger (L, 3 ,0 );
465
+ def.powerInfo .produced = luaL_optinteger (L, 4 ,0 );
466
+
467
+
428
468
// table of machine connection points
429
- luaL_checktype (L,6 , LUA_TTABLE);
430
- lua_pushvalue (L,6 );
469
+ luaL_checktype (L, 5 , LUA_TTABLE);
470
+ lua_pushvalue (L, 5 );
431
471
lua_pushnil (L);
432
472
while (lua_next (L, -2 ) != 0 ) {
433
- lua_getfield (L,-1 ," x" );
434
- int x= lua_tonumber (L,-1 );
435
- lua_pop (L,1 );
436
- lua_getfield (L,-1 ," y" );
437
- int y= lua_tonumber (L,-1 );
438
- lua_pop (L,1 );
473
+ lua_getfield (L, -1 , " x" );
474
+ int x = lua_tonumber (L, -1 );
475
+ lua_pop (L, 1 );
476
+ lua_getfield (L, -1 , " y" );
477
+ int y = lua_tonumber (L, -1 );
478
+ lua_pop (L, 1 );
439
479
440
480
df::machine_conn_modes modes;
441
481
modes.whole = -1 ;
442
- newDefinition .connections .can_connect .push_back (modes);// TODO add this too...
443
- newDefinition .connections .tiles .push_back (df::coord (x,y, 0 ));
482
+ def .connections .can_connect .push_back (modes);// TODO add this too...
483
+ def .connections .tiles .push_back (df::coord (x, y, 0 ));
444
484
445
- lua_pop (L,1 );
485
+ lua_pop (L, 1 );
446
486
}
447
- lua_pop (L,1 );
448
- // updates
449
- newDefinition.skip_updates =luaL_optinteger (L,7 ,0 );
487
+ lua_pop (L, 1 );
488
+ return 0 ;
489
+ }
490
+ // setUpdateSkip(workshop_type,int skip_frames) - skips frames to lower onupdate event call rate, 0 to disable
491
+ static int setUpdateSkip (lua_State* L)
492
+ {
493
+ int workshop_type = get_workshop_type (L, 1 );
494
+ auto & def = hacked_workshops[workshop_type];
495
+
496
+ def.skip_updates = luaL_optinteger (L, 2 , 0 );
497
+ return 0 ;
498
+ }
499
+ // setAnimationInfo(workshop_type,table frames, [frame_skip]) - define animation and it's timing. If frame_skip is not set or set to -1, it will use machine timing (i.e. like gears/axels etc)
500
+ static int setAnimationInfo (lua_State* L)
501
+ {
502
+ int workshop_type = get_workshop_type (L, 1 );
503
+ auto & def = hacked_workshops[workshop_type];
450
504
// animation
451
- if (!lua_isnil (L,8 ))
452
- {
453
- loadFrames (L,newDefinition,8 );
454
- newDefinition.frame_skip =luaL_optinteger (L,9 ,-1 );
455
- if (newDefinition.frame_skip ==0 )
456
- newDefinition.frame_skip =1 ;
457
- if (newDefinition.frame_skip <0 )
458
- newDefinition.machine_timing =true ;
459
- else
460
- newDefinition.machine_timing =false ;
461
- }
462
- newDefinition.room_subset =luaL_optinteger (L,10 ,-1 );
463
- hacked_workshops[newDefinition.myType ]=newDefinition;
505
+ loadFrames (L, def, 2 );
506
+ def.frame_skip = luaL_optinteger (L, 3 , -1 );
507
+ if (def.frame_skip == 0 )
508
+ def.frame_skip = 1 ;
509
+ if (def.frame_skip < 0 )
510
+ def.machine_timing = true ;
511
+ else
512
+ def.machine_timing = false ;
513
+ return 0 ;
514
+ }
515
+ // setOwnableBuilding(workshop_type,bool is_ownable)
516
+ static int setOwnableBuilding (lua_State* L)
517
+ {
518
+ int workshop_type = get_workshop_type (L, 1 );
519
+ bool room_subset = lua_toboolean (L, 2 );
520
+
521
+ auto & def = hacked_workshops[workshop_type];
522
+ def.room_subset = room_subset;
464
523
return 0 ;
465
524
}
466
525
static void setPower (df::building_workshopst* workshop, int power_produced, int power_consumed)
467
526
{
468
527
work_hook* ptr = static_cast <work_hook*>(workshop);
469
- if (ptr->find_def ()) // check if it's really hacked workshop
528
+ auto def = ptr->find_def ();
529
+ if (def && def->is_machine ) // check if it's really hacked workshop
470
530
{
471
531
ptr->set_current_power (power_produced, power_consumed);
472
532
}
@@ -477,7 +537,8 @@ static int getPower(lua_State*L)
477
537
work_hook* ptr = static_cast <work_hook*>(workshop);
478
538
if (!ptr)
479
539
return 0 ;
480
- if (ptr->find_def ()) // check if it's really hacked workshop
540
+ auto def = ptr->find_def ();
541
+ if (def && def->is_machine ) // check if it's really hacked workshop
481
542
{
482
543
df::power_info info;
483
544
ptr->get_current_power (&info);
@@ -492,8 +553,13 @@ DFHACK_PLUGIN_LUA_FUNCTIONS{
492
553
DFHACK_LUA_END
493
554
};
494
555
DFHACK_PLUGIN_LUA_COMMANDS{
495
- DFHACK_LUA_COMMAND (addBuilding),
556
+
496
557
DFHACK_LUA_COMMAND (getPower),
558
+ DFHACK_LUA_COMMAND (setOwnableBuilding),
559
+ DFHACK_LUA_COMMAND (setAnimationInfo),
560
+ DFHACK_LUA_COMMAND (setUpdateSkip),
561
+ DFHACK_LUA_COMMAND (setMachineInfo),
562
+ DFHACK_LUA_COMMAND (fixImpassible),
497
563
DFHACK_LUA_END
498
564
};
499
565
static void enable_hooks (bool enable)
0 commit comments