local _ENV = mkmodule('plugins.building-hacks') --[[ from native: addBuilding(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)) getPower(bld) -- 2 or 0 returns, produced and consumed setPower(bld,produced, consumed) from here: registerBuilding{ name -- custom workshop id e.g. SOAPMAKER << required! fix_impassible -- make impassible tiles impassible to liquids too consume -- how much machine power is needed to work produce -- how much machine power is produced gears -- a table or {x=?,y=?} of connection points for machines action -- a table of number (how much ticks to skip) and a function which gets called on shop update animate -- a table of frames -- a table of tables of 4 numbers (tile,fore,back,bright) OR empty table (tile not modified) OR {x= y= + 4 numbers like in first case} -- this generates full frame even, usefull for animations that change little (1-2 tiles) frameLenght -- how many ticks does one frame take OR isMechanical -- a bool that says to try to match to mechanical system (i.e. how gears are turning) } ]] _registeredStuff={} local function unregall(state) if state==SC_WORLD_UNLOADED then onUpdateAction._library=nil dfhack.onStateChange.building_hacks= nil _registeredStuff={} end end local function onUpdateLocal(workshop) local f=_registeredStuff[workshop:getCustomType()] if f then f(workshop) end end local function findCustomWorkshop(name) local raws=df.global.world.raws.buildings.all for k,v in ipairs(raws) do if v.code==name then return v end end end local function registerUpdateAction(shopId,callback) _registeredStuff[shopId]=callback onUpdateAction._library=onUpdateLocal dfhack.onStateChange.building_hacks=unregall end local function generateFrame(tiles,w,h) local mTiles={} for k,v in ipairs(tiles) do mTiles[v.x]=mTiles[v.x] or {} mTiles[v.x][v.y]=v end local ret={} for ty=0,h-1 do for tx=0,w-1 do if mTiles[tx] and mTiles[tx][ty] then table.insert(ret,mTiles[tx][ty]) -- leaves x and y in but who cares else table.insert(ret,{}) end end end return ret end local function processFrames(shop_def,frames) local w,h=shop_def.dim_x,shop_def.dim_y for frame_id,frame in ipairs(frames) do if frame[1].x~=nil then frames[frame_id]=generateFrame(frame,w,h) end end return frames end function registerBuilding(args) local shop_def=findCustomWorkshop(args.name) local shop_id=shop_def.id local fix_impassible if args.fix_impassible then fix_impassible=1 else fix_impassible=0 end local consume=args.consume or 0 local produce=args.produce or 0 local needs_power=args.needs_power or 1 local gears=args.gears or {} local action=args.action --could be nil local updateSkip=0 if action~=nil then updateSkip=action[1] registerUpdateAction(shop_id,action[2]) end local animate=args.animate local frameLength=1 local frames if animate~=nil then frameLength=animate.frameLength if animate.isMechanical then frameLength=-1 end frames=processFrames(shop_def,animate.frames) end local roomSubset=args.canBeRoomSubset or -1 addBuilding(shop_id,fix_impassible,consume,produce,needs_power,gears,updateSkip,frames,frameLength,roomSubset) end return _ENV