@ -19,6 +19,8 @@
# include "df/coord.h"
# include "df/tile_building_occ.h"
# include "df/building_drawbuffer.h"
# include "df/general_ref_creaturest.h" // needed for power information storage
# include "modules/Buildings.h"
# include <map>
@ -42,6 +44,7 @@ struct workshop_hack_data
//machine stuff
df : : machine_tile_set connections ;
df : : power_info powerInfo ;
bool needs_power ;
//animation
std : : vector < std : : vector < graphic_tile > > frames ;
bool machine_timing ; //6 frames used in vanilla
@ -60,6 +63,7 @@ DFHACK_PLUGIN_LUA_EVENTS {
DFHACK_LUA_EVENT ( onUpdateAction ) ,
DFHACK_LUA_END
} ;
struct work_hook : df : : building_workshopst {
typedef df : : building_workshopst interpose_base ;
@ -77,6 +81,54 @@ struct work_hook : df::building_workshopst{
{
return getBuildStage ( ) > = getMaxBuildStage ( ) ;
}
bool get_current_power ( df : : power_info * info )
{
if ( workshop_hack_data * def = find_def ( ) )
{
df : : general_ref_creaturest * ref = static_cast < df : : general_ref_creaturest * > ( DFHack : : Buildings : : getGeneralRef ( this , general_ref_type : : CREATURE ) ) ;
if ( ref )
{
info - > produced = ref - > anon_1 ;
info - > consumed = ref - > anon_2 ;
return true ;
}
else
{
info - > produced = def - > powerInfo . produced ;
info - > consumed = def - > powerInfo . consumed ;
return true ;
}
//try getting ref, if not return from def
}
return false ;
}
void set_current_power ( int produced , int consumed )
{
if ( machine . machine_id ! = - 1 ) //if connected to machine, update the machine network production
{
df : : machine * target_machine = df : : machine : : find ( machine . machine_id ) ;
if ( target_machine )
{
df : : power_info old_power ;
get_current_power ( & old_power ) ;
target_machine - > min_power + = consumed - old_power . consumed ;
target_machine - > cur_power + = produced - old_power . produced ;
}
}
df : : general_ref_creaturest * ref = static_cast < df : : general_ref_creaturest * > ( DFHack : : Buildings : : getGeneralRef ( this , general_ref_type : : CREATURE ) ) ;
if ( ref )
{
ref - > anon_1 = produced ;
ref - > anon_2 = consumed ;
}
else
{
ref = df : : allocate < df : : general_ref_creaturest > ( ) ;
ref - > anon_1 = produced ;
ref - > anon_2 = consumed ;
general_refs . push_back ( ref ) ;
}
}
DEFINE_VMETHOD_INTERPOSE ( uint32_t , getImpassableOccupancy , ( ) )
{
if ( auto def = find_def ( ) )
@ -89,13 +141,12 @@ struct work_hook : df::building_workshopst{
DEFINE_VMETHOD_INTERPOSE ( void , getPowerInfo , ( df : : power_info * info ) )
{
if ( auto def = find_def ( ) )
{
info - > produced = def - > powerInfo . produced ;
info - > consumed = def - > powerInfo . consumed ;
return ;
}
if ( auto def = find_def ( ) )
{
df : : power_info power ;
get_current_power ( info ) ;
return ;
}
INTERPOSE_NEXT ( getPowerInfo ) ( info ) ;
}
DEFINE_VMETHOD_INTERPOSE ( df : : machine_info * , getMachineInfo , ( ) )
@ -108,7 +159,9 @@ struct work_hook : df::building_workshopst{
DEFINE_VMETHOD_INTERPOSE ( bool , isPowerSource , ( ) )
{
workshop_hack_data * def = find_def ( ) ;
if ( def & & def - > powerInfo . produced > 0 )
df : : power_info power ;
get_current_power ( & power ) ;
if ( def & & power . produced > 0 )
return true ;
return INTERPOSE_NEXT ( isPowerSource ) ( ) ;
@ -164,7 +217,11 @@ struct work_hook : df::building_workshopst{
{
if ( auto def = find_def ( ) )
{
if ( def - > powerInfo . consumed = = 0 )
if ( ! def - > needs_power )
return false ;
df : : power_info power ;
get_current_power ( & power ) ;
if ( power . consumed = = 0 )
return false ;
if ( machine . machine_id = = - 1 )
return true ;
@ -257,6 +314,9 @@ IMPLEMENT_VMETHOD_INTERPOSE(work_hook, isUnpowered);
IMPLEMENT_VMETHOD_INTERPOSE ( work_hook , canBeRoomSubset ) ;
IMPLEMENT_VMETHOD_INTERPOSE ( work_hook , updateAction ) ;
IMPLEMENT_VMETHOD_INTERPOSE ( work_hook , drawBuilding ) ;
void clear_mapping ( )
{
hacked_workshops . clear ( ) ;
@ -318,9 +378,10 @@ static int addBuilding(lua_State* L)
newDefinition . impassible_fix = luaL_checkint ( L , 2 ) ;
newDefinition . powerInfo . consumed = luaL_checkint ( L , 3 ) ;
newDefinition . powerInfo . produced = luaL_checkint ( L , 4 ) ;
newDefinition . needs_power = luaL_optinteger ( L , 5 , 1 ) ;
//table of machine connection points
luaL_checktype ( L , 5 , LUA_TTABLE ) ;
lua_pushvalue ( L , 5 ) ;
luaL_checktype ( L , 6 , LUA_TTABLE ) ;
lua_pushvalue ( L , 6 ) ;
lua_pushnil ( L ) ;
while ( lua_next ( L , - 2 ) ! = 0 ) {
lua_getfield ( L , - 1 , " x " ) ;
@ -337,12 +398,12 @@ static int addBuilding(lua_State* L)
}
lua_pop ( L , 1 ) ;
//updates
newDefinition . skip_updates = luaL_optinteger ( L , 6 , 0 ) ;
newDefinition . skip_updates = luaL_optinteger ( L , 7 , 0 ) ;
//animation
if ( ! lua_isnil ( L , 7 ) )
if ( ! lua_isnil ( L , 8 ) )
{
loadFrames ( L , newDefinition , 7 ) ;
newDefinition . frame_skip = luaL_optinteger ( L , 8 , - 1 ) ;
loadFrames ( L , newDefinition , 8 ) ;
newDefinition . frame_skip = luaL_optinteger ( L , 9 , - 1 ) ;
if ( newDefinition . frame_skip = = 0 )
newDefinition . frame_skip = 1 ;
if ( newDefinition . frame_skip < 0 )
@ -350,12 +411,41 @@ static int addBuilding(lua_State* L)
else
newDefinition . machine_timing = false ;
}
newDefinition . room_subset = luaL_optinteger ( L , 9 , - 1 ) ;
newDefinition . room_subset = luaL_optinteger ( L , 10 , - 1 ) ;
hacked_workshops [ newDefinition . myType ] = newDefinition ;
return 0 ;
}
static void setPower ( df : : building_workshopst * workshop , int power_produced , int power_consumed )
{
work_hook * ptr = static_cast < work_hook * > ( workshop ) ;
if ( workshop_hack_data * def = ptr - > find_def ( ) ) //check if it's really hacked workshop
{
ptr - > set_current_power ( power_produced , power_consumed ) ;
}
}
static int getPower ( lua_State * L )
{
auto workshop = Lua : : CheckDFObject < df : : building_workshopst > ( L , 1 ) ;
work_hook * ptr = static_cast < work_hook * > ( workshop ) ;
if ( ! ptr )
return 0 ;
if ( workshop_hack_data * def = ptr - > find_def ( ) ) //check if it's really hacked workshop
{
df : : power_info info ;
ptr - > get_current_power ( & info ) ;
lua_pushinteger ( L , info . produced ) ;
lua_pushinteger ( L , info . consumed ) ;
return 2 ;
}
return 0 ;
}
DFHACK_PLUGIN_LUA_FUNCTIONS {
DFHACK_LUA_FUNCTION ( setPower ) ,
DFHACK_LUA_END
} ;
DFHACK_PLUGIN_LUA_COMMANDS {
DFHACK_LUA_COMMAND ( addBuilding ) ,
DFHACK_LUA_COMMAND ( getPower ) ,
DFHACK_LUA_END
} ;
static void enable_hooks ( bool enable )