Skip to content

Commit

Permalink
big refactor and api cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
warmist committed Mar 24, 2024
1 parent e6045b5 commit 0391bfc
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 128 deletions.
168 changes: 117 additions & 51 deletions plugins/building-hacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "df/tile_building_occ.h"
#include "df/building_drawbuffer.h"
#include "df/general_ref_creaturest.h" // needed for power information storage
#include "df/building_def_workshopst.h"
#include "modules/Buildings.h"

#include <map>
Expand All @@ -46,19 +47,19 @@ struct graphic_tile //could do just 31x31 and be done, but it's nicer to have fl
};
struct workshop_hack_data
{
int32_t myType;
bool impassible_fix;
bool impassible_fix = false;
//machine stuff
bool is_machine = false;
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
bool machine_timing=false; //6 frames used in vanilla
int frame_skip; // e.g. 2 means have to ticks between frames
//updateCallback:
int skip_updates;
int room_subset; //0 no, 1 yes, -1 default
int skip_updates=0;
int room_subset=-1; //0 no, 1 yes, -1 default
};
typedef std::map<int32_t,workshop_hack_data> workshops_data_t;
workshops_data_t hacked_workshops;
Expand Down Expand Up @@ -94,6 +95,7 @@ struct work_hook : df::building_workshopst{
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));
//try getting ref, if not return from definition
if (ref)
{
info->produced = ref->unk_1;
Expand All @@ -106,7 +108,6 @@ struct work_hook : df::building_workshopst{
info->consumed = def->powerInfo.consumed;
return true;
}
//try getting ref, if not return from def
}
return false;
}
Expand All @@ -124,6 +125,7 @@ struct work_hook : df::building_workshopst{
}
}
df::general_ref_creaturest* ref = static_cast<df::general_ref_creaturest*>(DFHack::Buildings::getGeneralRef(this, general_ref_type::CREATURE));
//if we have a setting then update it, else create a new ref for dynamic power tracking
if (ref)
{
ref->unk_1 = produced;
Expand All @@ -149,7 +151,8 @@ struct work_hook : df::building_workshopst{

DEFINE_VMETHOD_INTERPOSE(void, getPowerInfo, (df::power_info *info))
{
if (find_def())
auto def = find_def();
if (def && def->is_machine)
{
df::power_info power;
get_current_power(info);
Expand All @@ -159,7 +162,8 @@ struct work_hook : df::building_workshopst{
}
DEFINE_VMETHOD_INTERPOSE(df::machine_info*, getMachineInfo, ())
{
if (find_def())
auto def = find_def();
if (def && def->is_machine)
return &machine;

return INTERPOSE_NEXT(getMachineInfo)();
Expand All @@ -176,7 +180,8 @@ struct work_hook : df::building_workshopst{
}
DEFINE_VMETHOD_INTERPOSE(void, categorize, (bool free))
{
if (find_def())
auto def = find_def();
if (def && def->is_machine)
{
auto &vec = world->buildings.other[buildings_other_id::ANY_MACHINE];
insert_into_vector(vec, &df::building::id, (df::building*)this);
Expand All @@ -187,7 +192,8 @@ struct work_hook : df::building_workshopst{

DEFINE_VMETHOD_INTERPOSE(void, uncategorize, ())
{
if (find_def())
auto def = find_def();
if (def && def->is_machine)
{
auto &vec = world->buildings.other[buildings_other_id::ANY_MACHINE];
erase_from_vector(vec, &df::building::id, id);
Expand All @@ -197,8 +203,10 @@ struct work_hook : df::building_workshopst{
}
DEFINE_VMETHOD_INTERPOSE(bool, canConnectToMachine, (df::machine_tile_set *info))
{
if (auto def = find_def())
auto def = find_def();
if (def && def->is_machine)
{

int real_cx = centerx, real_cy = centery;
bool ok = false;

Expand Down Expand Up @@ -341,7 +349,26 @@ IMPLEMENT_VMETHOD_INTERPOSE(work_hook, setTriggerState);
IMPLEMENT_VMETHOD_INTERPOSE(work_hook, drawBuilding);



int get_workshop_type(lua_State* L,int arg)
{
size_t len;
int is_num;
int type;
type=lua_tointegerx(L, arg, &is_num);
if (is_num)
{
return type;
}
auto str = lua_tolstring(L, arg, &len);
const auto& raws = world->raws.buildings.workshops;
for(size_t i=0;i<raws.size();i++)
{
if (raws[i]->code == str)
return raws[i]->id;
}
luaL_argerror(L, arg, "expected int or string workshop id");
return 0;
}
void clear_mapping()
{
hacked_workshops.clear();
Expand Down Expand Up @@ -415,58 +442,91 @@ static void loadFrames(lua_State* L,workshop_hack_data& def,int stack_pos)

return ;
}
//arguments: custom type,impassible fix (bool), consumed power, produced power, list of connection points, update skip(0/nil to disable)
// table of frames,frame to tick ratio (-1 for machine control)
static int addBuilding(lua_State* L)

//fixImpassible(workshop_type,bool) - changes how impassible tiles work with liquids. False - default behaviour. True - blocks liquids.
static int fixImpassible(lua_State* L)
{
int workshop_type = get_workshop_type(L, 1);
bool impassible_setting = lua_toboolean(L, 2);

Check failure on line 451 in plugins/building-hacks.cpp

View workflow job for this annotation

GitHub Actions / lint / lint

Contains trailing whitespace: lines 451, 466-467, 495, 556
auto& def = hacked_workshops[workshop_type];
def.impassible_fix = impassible_setting;
return 0;
}
//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
static int setMachineInfo(lua_State* L)
{
workshop_hack_data newDefinition;
newDefinition.myType=luaL_checkint(L,1);
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);
int workshop_type = get_workshop_type(L, 1);
auto& def = hacked_workshops[workshop_type];
def.is_machine = true;

def.needs_power = lua_toboolean(L, 2);
def.powerInfo.consumed = luaL_optinteger(L, 3,0);
def.powerInfo.produced = luaL_optinteger(L, 4,0);


//table of machine connection points
luaL_checktype(L,6,LUA_TTABLE);
lua_pushvalue(L,6);
luaL_checktype(L, 5, LUA_TTABLE);
lua_pushvalue(L, 5);
lua_pushnil(L);
while (lua_next(L, -2) != 0) {
lua_getfield(L,-1,"x");
int x=lua_tonumber(L,-1);
lua_pop(L,1);
lua_getfield(L,-1,"y");
int y=lua_tonumber(L,-1);
lua_pop(L,1);
lua_getfield(L, -1, "x");
int x = lua_tonumber(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "y");
int y = lua_tonumber(L, -1);
lua_pop(L, 1);

df::machine_conn_modes modes;
modes.whole = -1;
newDefinition.connections.can_connect.push_back(modes);//TODO add this too...
newDefinition.connections.tiles.push_back(df::coord(x,y,0));
def.connections.can_connect.push_back(modes);//TODO add this too...
def.connections.tiles.push_back(df::coord(x, y, 0));

lua_pop(L,1);
lua_pop(L, 1);
}
lua_pop(L,1);
//updates
newDefinition.skip_updates=luaL_optinteger(L,7,0);
lua_pop(L, 1);
return 0;
}
//setUpdateSkip(workshop_type,int skip_frames) - skips frames to lower onupdate event call rate, 0 to disable
static int setUpdateSkip(lua_State* L)
{
int workshop_type = get_workshop_type(L, 1);
auto& def = hacked_workshops[workshop_type];

def.skip_updates = luaL_optinteger(L, 2, 0);
return 0;
}
//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)
static int setAnimationInfo(lua_State* L)
{
int workshop_type = get_workshop_type(L, 1);
auto& def = hacked_workshops[workshop_type];
//animation
if(!lua_isnil(L,8))
{
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)
newDefinition.machine_timing=true;
else
newDefinition.machine_timing=false;
}
newDefinition.room_subset=luaL_optinteger(L,10,-1);
hacked_workshops[newDefinition.myType]=newDefinition;
loadFrames(L, def, 2);
def.frame_skip = luaL_optinteger(L, 3, -1);
if (def.frame_skip == 0)
def.frame_skip = 1;
if (def.frame_skip < 0)
def.machine_timing = true;
else
def.machine_timing = false;
return 0;
}
//setOwnableBuilding(workshop_type,bool is_ownable)
static int setOwnableBuilding(lua_State* L)
{
int workshop_type = get_workshop_type(L, 1);
bool room_subset = lua_toboolean(L, 2);

auto& def = hacked_workshops[workshop_type];
def.room_subset = room_subset;
return 0;
}
static void setPower(df::building_workshopst* workshop, int power_produced, int power_consumed)
{
work_hook* ptr = static_cast<work_hook*>(workshop);
if (ptr->find_def()) // check if it's really hacked workshop
auto def = ptr->find_def();
if (def && def->is_machine) // check if it's really hacked workshop
{
ptr->set_current_power(power_produced, power_consumed);
}
Expand All @@ -477,7 +537,8 @@ static int getPower(lua_State*L)
work_hook* ptr = static_cast<work_hook*>(workshop);
if (!ptr)
return 0;
if (ptr->find_def()) // check if it's really hacked workshop
auto def = ptr->find_def();
if (def && def->is_machine) // check if it's really hacked workshop
{
df::power_info info;
ptr->get_current_power(&info);
Expand All @@ -492,8 +553,13 @@ DFHACK_PLUGIN_LUA_FUNCTIONS{
DFHACK_LUA_END
};
DFHACK_PLUGIN_LUA_COMMANDS{
DFHACK_LUA_COMMAND(addBuilding),

DFHACK_LUA_COMMAND(getPower),
DFHACK_LUA_COMMAND(setOwnableBuilding),
DFHACK_LUA_COMMAND(setAnimationInfo),
DFHACK_LUA_COMMAND(setUpdateSkip),
DFHACK_LUA_COMMAND(setMachineInfo),
DFHACK_LUA_COMMAND(fixImpassible),
DFHACK_LUA_END
};
static void enable_hooks(bool enable)
Expand Down
Loading

0 comments on commit 0391bfc

Please sign in to comment.