2020#include " df/tile_building_occ.h"
2121#include " df/building_drawbuffer.h"
2222#include " df/general_ref_creaturest.h" // needed for power information storage
23+ #include " df/building_def_workshopst.h"
2324#include " modules/Buildings.h"
2425
2526#include < map>
@@ -46,19 +47,19 @@ struct graphic_tile //could do just 31x31 and be done, but it's nicer to have fl
4647};
4748struct workshop_hack_data
4849{
49- int32_t myType;
50- bool impassible_fix;
50+ bool impassible_fix = false ;
5151 // machine stuff
52+ bool is_machine = false ;
5253 df::machine_tile_set connections;
5354 df::power_info powerInfo;
5455 bool needs_power;
5556 // animation
5657 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
5859 int frame_skip; // e.g. 2 means have to ticks between frames
5960 // 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
6263};
6364typedef std::map<int32_t ,workshop_hack_data> workshops_data_t ;
6465workshops_data_t hacked_workshops;
@@ -94,6 +95,7 @@ struct work_hook : df::building_workshopst{
9495 if (workshop_hack_data* def = find_def ())
9596 {
9697 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
9799 if (ref)
98100 {
99101 info->produced = ref->unk_1 ;
@@ -106,7 +108,6 @@ struct work_hook : df::building_workshopst{
106108 info->consumed = def->powerInfo .consumed ;
107109 return true ;
108110 }
109- // try getting ref, if not return from def
110111 }
111112 return false ;
112113 }
@@ -124,6 +125,7 @@ struct work_hook : df::building_workshopst{
124125 }
125126 }
126127 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
127129 if (ref)
128130 {
129131 ref->unk_1 = produced;
@@ -149,7 +151,8 @@ struct work_hook : df::building_workshopst{
149151
150152 DEFINE_VMETHOD_INTERPOSE (void , getPowerInfo, (df::power_info *info))
151153 {
152- if (find_def ())
154+ auto def = find_def ();
155+ if (def && def->is_machine )
153156 {
154157 df::power_info power;
155158 get_current_power (info);
@@ -159,7 +162,8 @@ struct work_hook : df::building_workshopst{
159162 }
160163 DEFINE_VMETHOD_INTERPOSE (df::machine_info*, getMachineInfo, ())
161164 {
162- if (find_def ())
165+ auto def = find_def ();
166+ if (def && def->is_machine )
163167 return &machine;
164168
165169 return INTERPOSE_NEXT (getMachineInfo)();
@@ -176,7 +180,8 @@ struct work_hook : df::building_workshopst{
176180 }
177181 DEFINE_VMETHOD_INTERPOSE (void , categorize, (bool free))
178182 {
179- if (find_def ())
183+ auto def = find_def ();
184+ if (def && def->is_machine )
180185 {
181186 auto &vec = world->buildings .other [buildings_other_id::ANY_MACHINE];
182187 insert_into_vector (vec, &df::building::id, (df::building*)this );
@@ -187,7 +192,8 @@ struct work_hook : df::building_workshopst{
187192
188193 DEFINE_VMETHOD_INTERPOSE (void , uncategorize, ())
189194 {
190- if (find_def ())
195+ auto def = find_def ();
196+ if (def && def->is_machine )
191197 {
192198 auto &vec = world->buildings .other [buildings_other_id::ANY_MACHINE];
193199 erase_from_vector (vec, &df::building::id, id);
@@ -197,8 +203,10 @@ struct work_hook : df::building_workshopst{
197203 }
198204 DEFINE_VMETHOD_INTERPOSE (bool , canConnectToMachine, (df::machine_tile_set *info))
199205 {
200- if (auto def = find_def ())
206+ auto def = find_def ();
207+ if (def && def->is_machine )
201208 {
209+
202210 int real_cx = centerx, real_cy = centery;
203211 bool ok = false ;
204212
@@ -341,7 +349,26 @@ IMPLEMENT_VMETHOD_INTERPOSE(work_hook, setTriggerState);
341349IMPLEMENT_VMETHOD_INTERPOSE (work_hook, drawBuilding);
342350
343351
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+ }
345372void clear_mapping ()
346373{
347374 hacked_workshops.clear ();
@@ -415,58 +442,91 @@ static void loadFrames(lua_State* L,workshop_hack_data& def,int stack_pos)
415442
416443 return ;
417444}
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)
421458{
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+
428468 // 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 );
431471 lua_pushnil (L);
432472 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 );
439479
440480 df::machine_conn_modes modes;
441481 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 ));
444484
445- lua_pop (L,1 );
485+ lua_pop (L, 1 );
446486 }
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];
450504 // 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;
464523 return 0 ;
465524}
466525static void setPower (df::building_workshopst* workshop, int power_produced, int power_consumed)
467526{
468527 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
470530 {
471531 ptr->set_current_power (power_produced, power_consumed);
472532 }
@@ -477,7 +537,8 @@ static int getPower(lua_State*L)
477537 work_hook* ptr = static_cast <work_hook*>(workshop);
478538 if (!ptr)
479539 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
481542 {
482543 df::power_info info;
483544 ptr->get_current_power (&info);
@@ -492,8 +553,13 @@ DFHACK_PLUGIN_LUA_FUNCTIONS{
492553 DFHACK_LUA_END
493554};
494555DFHACK_PLUGIN_LUA_COMMANDS{
495- DFHACK_LUA_COMMAND (addBuilding),
556+
496557 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),
497563 DFHACK_LUA_END
498564};
499565static void enable_hooks (bool enable)
0 commit comments