From c5fb4c126072b91f44536f6fa859c7b8c2a3504c Mon Sep 17 00:00:00 2001 From: expwnent Date: Sat, 16 Aug 2014 08:45:49 -0400 Subject: [PATCH 1/4] Update hack-wish. --- scripts/gui/hack-wish.lua | 213 ++++++++++++++++---------------------- 1 file changed, 92 insertions(+), 121 deletions(-) diff --git a/scripts/gui/hack-wish.lua b/scripts/gui/hack-wish.lua index e1dc47696..77d163599 100644 --- a/scripts/gui/hack-wish.lua +++ b/scripts/gui/hack-wish.lua @@ -3,6 +3,7 @@ -- author Putnam -- edited by expwnent + function getGenderString(gender) local genderStr if gender==0 then @@ -14,7 +15,7 @@ function getGenderString(gender) end return string.char(40)..genderStr..string.char(41) end - + function getCreatureList() local crList={} for k,cr in ipairs(df.global.world.raws.creatures.alphabetic) do @@ -26,52 +27,52 @@ function getCreatureList() end return crList end - + function getMatFilter(itemtype) - local itemTypes={ - SEEDS=function(mat,parent,typ,idx) - return mat.flags.SEED_MAT - end, - PLANT=function(mat,parent,typ,idx) - return mat.flags.STRUCTURAL_PLANT_MAT - end, - LEAVES=function(mat,parent,typ,idx) - return mat.flags.LEAF_MAT - end, - MEAT=function(mat,parent,typ,idx) - return mat.flags.MEAT - end, - CHEESE=function(mat,parent,typ,idx) - return (mat.flags.CHEESE_PLANT or mat.flags.CHEESE_CREATURE) - end, - LIQUID_MISC=function(mat,parent,typ,idx) - return (mat.flags.LIQUID_MISC_PLANT or mat.flags.LIQUID_MISC_CREATURE or mat.flags.LIQUID_MISC_OTHER) - end, - POWDER_MISC=function(mat,parent,typ,idx) - return (mat.flags.POWDER_MISC_PLANT or mat.flags.POWDER_MISC_CREATURE) - end, - DRINK=function(mat,parent,typ,idx) - return (mat.flags.ALCOHOL_PLANT or mat.flags.ALCOHOL_CREATURE) - end, - GLOB=function(mat,parent,typ,idx) - return (mat.flags.STOCKPILE_GLOB) - end, - WOOD=function(mat,parent,typ,idx) - return (mat.flags.WOOD) - end, - THREAD=function(mat,parent,typ,idx) - return (mat.flags.THREAD_PLANT) - end, - LEATHER=function(mat,parent,typ,idx) - return (mat.flags.LEATHER) - end - } - return itemTypes[df.item_type[itemtype]] or getRestrictiveMatFilter(itemtype) + local itemTypes={ + SEEDS=function(mat,parent,typ,idx) + return mat.flags.SEED_MAT + end, + PLANT=function(mat,parent,typ,idx) + return mat.flags.STRUCTURAL_PLANT_MAT + end, + LEAVES=function(mat,parent,typ,idx) + return mat.flags.LEAF_MAT + end, + MEAT=function(mat,parent,typ,idx) + return mat.flags.MEAT + end, + CHEESE=function(mat,parent,typ,idx) + return (mat.flags.CHEESE_PLANT or mat.flags.CHEESE_CREATURE) + end, + LIQUID_MISC=function(mat,parent,typ,idx) + return (mat.flags.LIQUID_MISC_PLANT or mat.flags.LIQUID_MISC_CREATURE or mat.flags.LIQUID_MISC_OTHER) + end, + POWDER_MISC=function(mat,parent,typ,idx) + return (mat.flags.POWDER_MISC_PLANT or mat.flags.POWDER_MISC_CREATURE) + end, + DRINK=function(mat,parent,typ,idx) + return (mat.flags.ALCOHOL_PLANT or mat.flags.ALCOHOL_CREATURE) + end, + GLOB=function(mat,parent,typ,idx) + return (mat.flags.STOCKPILE_GLOB) + end, + WOOD=function(mat,parent,typ,idx) + return (mat.flags.WOOD) + end, + THREAD=function(mat,parent,typ,idx) + return (mat.flags.THREAD_PLANT) + end, + LEATHER=function(mat,parent,typ,idx) + return (mat.flags.LEATHER) + end + } + return itemTypes[df.item_type[itemtype]] or getRestrictiveMatFilter(itemtype) end - + function getRestrictiveMatFilter(itemType) if not args.veryRestrictive then return nil else - local itemTypes={ + local itemTypes={ WEAPON=function(mat,parent,typ,idx) return (mat.flags.ITEMS_WEAPON or mat.flags.ITEMS_WEAPON_RANGED) end, @@ -97,62 +98,33 @@ function getRestrictiveMatFilter(itemType) BAR=function(mat,parent,typ,idx) return (mat.flags.IS_METAL or mat.flags.SOAP or mat.id==COAL) end + } - return itemTypes[df.item_type[itemType]] + return itemTypes[df.item_type[itemType]] end end - -function createItem(mat,itemType,quality,pos,description) - local item=df[df.item_type.attrs[itemType[1]].classname]:new() - item.id=df.global.item_next_id - df.global.world.items.all:insert('#',item) - df.global.item_next_id=df.global.item_next_id+1 - item:setSubtype(itemType[2]) - item:setMaterial(mat[1]) - item:setMaterialIndex(mat[2]) - if df.item_type[itemType[1]]=='EGG' then - local creature=df.creature_raw.find(mat[1]) - local eggMat={} - eggMat[1]=dfhack.matinfo.find(creature.creature_id..':EGGSHELL') - if eggMat[1] then - eggMat[2]=dfhack.matinfo.find(creature.creature_id..':EGG_WHITE') - eggMat[3]=dfhack.matinfo.find(creature.creature_id..'EGG_YOLK') - for k,v in ipairs(eggMat) do - item.egg_materials.mat_type:insert('#',v.type) - item.egg_materials.mat_index:insert('#',v.index) - end - else - eggMat=dfhack.matinfo.find(creature.creature_id..':MUSCLE') - item.egg_materials.mat_type:insert('#',eggMat.type) - item.egg_materials.mat_index:insert('#',eggMat.index) - end - end - item:categorize(true) - item.flags.removed=true - item:setSharpness(1,0) - item:setQuality(quality-1) + +function createItem(mat,itemType,quality,creator,description) + dfhack.items.createItem(itemType[1], itemType[2], mat[1], mat[2], creator) if df.item_type[itemType[1]]=='SLAB' then item.description=description end - dfhack.items.moveToGround(item,{x=pos.x,y=pos.y,z=pos.z}) end - ---TODO: should this be a function? + function qualityTable() return {{'None'}, - {'-Well-crafted-'}, - {'+Finely-crafted+'}, - {'*Superior*'}, - {string.char(240)..'Exceptional'..string.char(240)}, - {string.char(15)..'Masterwork'..string.char(15)} + {'-Well-crafted-'}, + {'+Finely-crafted+'}, + {'*Superior*'}, + {string.char(240)..'Exceptional'..string.char(240)}, + {string.char(15)..'Masterwork'..string.char(15)} } end - -local script=require('gui/script') -local guimaterials=require('gui.materials') - + +local script=require('gui.script') + function showItemPrompt(text,item_filter,hide_none) - guimaterials.ItemTypeDialog{ + require('gui.materials').ItemTypeDialog{ prompt=text, item_filter=item_filter, hide_none=hide_none, @@ -163,9 +135,9 @@ function showItemPrompt(text,item_filter,hide_none) return script.wait() end - + function showMaterialPrompt(title, prompt, filter, inorganic, creature, plant) --the one included with DFHack doesn't have a filter or the inorganic, creature, plant things available - guimaterials.MaterialDialog{ + require('gui.materials').MaterialDialog{ frame_title = title, prompt = prompt, mat_filter = filter, @@ -179,20 +151,19 @@ function showMaterialPrompt(title, prompt, filter, inorganic, creature, plant) - return script.wait() end - + function usesCreature(itemtype) typesThatUseCreatures={REMAINS=true,FISH=true,FISH_RAW=true,VERMIN=true,PET=true,EGG=true,CORPSE=true,CORPSEPIECE=true} return typesThatUseCreatures[df.item_type[itemtype]] end - + function getCreatureRaceAndCaste(caste) return df.global.world.raws.creatures.list_creature[caste.index],df.global.world.raws.creatures.list_caste[caste.index] end - -function hackWish(posOrUnit) - local pos = df.unit:is_instance(posOrUnit) and posOrUnit.pos or posOrUnit + +function hackWish(unit) script.start(function() - --local amountok, amount + local amountok, amount local matok,mattype,matindex,matFilter local itemok,itemtype,itemsubtype=showItemPrompt('What item do you want?',function(itype) return df.item_type[itype]~='CORPSE' and df.item_type[itype]~='FOOD' end ,true) if not args.notRestrictive then @@ -210,43 +181,43 @@ function hackWish(posOrUnit) local descriptionok descriptionok,description=script.showInputPrompt('Slab','What should the slab say?',COLOR_WHITE) end - --repeat amountok,amount=script.showInputPrompt('Wish','How many do you want? (numbers only!)',COLOR_LIGHTGREEN) until tonumber(amount) - if mattype and itemtype then - --for i=1,tonumber(amount) do - createItem({mattype,matindex},{itemtype,itemsubtype},quality,pos,description) - --end + if args.multi then + repeat amountok,amount=script.showInputPrompt('Wish','How many do you want? (numbers only!)',COLOR_LIGHTGREEN) until tonumber(amount) + if mattype and itemtype then + for i=1,tonumber(amount) do + createItem({mattype,matindex},{itemtype,itemsubtype},quality,unit,description) + end + end + else + if mattype and itemtype then + createItem({mattype,matindex},{itemtype,itemsubtype},quality,unit,description) + end end end) end - + scriptArgs={...} -args={} +validArgs = validArgs or utils.invert({ + 'startup', + 'all', + 'restrictive', + 'unit', + 'multi' +}) -for k,v in ipairs(scriptArgs) do - v=v:lower() - if v=='startup' then args.startup=true end - if v=='all' then args.notRestrictive=true end - if v=='restrictive' then args.veryRestrictive=true end - if v=='unit' then args.unitNum=args[k+1] end - if v=='x' then args.x=args[k+1] end - if v=='y' then args.y=args[k+1] end - if v=='z' then args.z=args[k+1] end -end +utils=require('utils') +args = utils.processArgs({...}, validArgs) + eventful=require('plugins.eventful') -function posIsValid(pos) - return pos.x~=-30000 and pos or false -end - if not args.startup then - local posOrUnit=args.x and {x=args.x,y=args.y,z=args.z} or args.unitNum and df.unit.find(args.unitNum) or posIsValid(df.global.cursor) or dfhack.gui.getSelectedUnit(true) - hackWish(posOrUnit) + local unit=args.unit and df.unit.find(args.unit) or dfhack.gui.getSelectedUnit(true) + hackWish(unit) else - eventful.onReactionComplete.hackWishP=function(reaction,unit,input_items,input_reagents,output_items, call_native) + eventful.onReactionComplete.hackWishP=function(reaction,unit,input_items,input_reagents,output_items,call_native) if not reaction.code:find('DFHACK_WISH') then return nil end hackWish(unit) end -end - +end \ No newline at end of file From 6868cab1fe4aeb15da435956d14c769e4d4e8058 Mon Sep 17 00:00:00 2001 From: Warmist Date: Sun, 3 Aug 2014 15:11:38 +0300 Subject: [PATCH 2/4] Exposed dfhack.jobs.linkIntoWorld. Simplified eventful and gui.dwarfmode for sidebar use/creation. --- library/LuaApi.cpp | 1 + library/lua/gui/dwarfmode.lua | 29 +++++++++++++++++++++++++++-- plugins/building-hacks.cpp | 15 +++++++++++++++ plugins/lua/building-hacks.lua | 4 ++-- plugins/lua/eventful.lua | 21 +++++++++++++++++---- scripts/gui/mod-manager.lua | 18 +++++++++--------- 6 files changed, 71 insertions(+), 17 deletions(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 53f4b08e6..3fd18a8d6 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1339,6 +1339,7 @@ static const LuaWrapper::FunctionReg dfhack_job_module[] = { WRAPM(Job,isSuitableItem), WRAPM(Job,isSuitableMaterial), WRAPM(Job,getName), + WRAPM(Job,linkIntoWorld), WRAPN(is_equal, jobEqual), WRAPN(is_item_equal, jobItemEqual), { NULL, NULL } diff --git a/library/lua/gui/dwarfmode.lua b/library/lua/gui/dwarfmode.lua index 8c537639b..a008bb135 100644 --- a/library/lua/gui/dwarfmode.lua +++ b/library/lua/gui/dwarfmode.lua @@ -383,7 +383,7 @@ MenuOverlay = defclass(MenuOverlay, DwarfOverlay) MenuOverlay.ATTRS { frame_inset = 0, - frame_background = CLEAR_PEN, + frame_background = gui.CLEAR_PEN, } function MenuOverlay:computeFrame(parent_rect) @@ -417,5 +417,30 @@ function MenuOverlay:render(dc) MenuOverlay.super.render(self, dc) end end - +--fakes a "real" workshop sidebar menu, but on exactly selected workshop +WorkshopOverlay = defclass(WorkshopOverlay, MenuOverlay) +WorkshopOverlay.ATTRS={ + workshop=DEFAULT_NIL, +} +function WorkshopOverlay:onInput(keys) + local allowedKeys={ --TODO add options: job management, profile, etc... + "CURSOR_RIGHT","CURSOR_LEFT","CURSOR_UP","CURSOR_DOWN", + "CURSOR_UPRIGHT","CURSOR_UPLEFT","CURSOR_DOWNRIGHT","CURSOR_DOWNLEFT","CURSOR_UP_Z","CURSOR_DOWN_Z","DESTROYBUILDING"} + if keys.LEAVESCREEN then + self:dismiss() + self:sendInputToParent('LEAVESCREEN') + else + for _,name in ipairs(allowedKeys) do + if keys[name] then + self:sendInputToParent(name) + break + end + end + self:inputToSubviews(keys) + end + if df.global.world.selected_building ~= self.workshop then + self:dismiss() + return + end +end return _ENV diff --git a/plugins/building-hacks.cpp b/plugins/building-hacks.cpp index 07beade74..d56215fda 100644 --- a/plugins/building-hacks.cpp +++ b/plugins/building-hacks.cpp @@ -47,6 +47,7 @@ struct workshop_hack_data 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 }; typedef std::map workshops_data_t; workshops_data_t hacked_workshops; @@ -174,6 +175,17 @@ struct work_hook : df::building_workshopst{ return INTERPOSE_NEXT(isUnpowered)(); } + DEFINE_VMETHOD_INTERPOSE(bool, canBeRoomSubset, ()) + { + if(auto def = find_def()) + { + if(def->room_subset==0) + return false; + if(def->room_subset==1) + return true; + } + return INTERPOSE_NEXT(canBeRoomSubset)(); + } DEFINE_VMETHOD_INTERPOSE(void, updateAction, ()) { if(auto def = find_def()) @@ -241,6 +253,7 @@ IMPLEMENT_VMETHOD_INTERPOSE(work_hook, categorize); IMPLEMENT_VMETHOD_INTERPOSE(work_hook, uncategorize); IMPLEMENT_VMETHOD_INTERPOSE(work_hook, canConnectToMachine); 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() @@ -336,6 +349,7 @@ static int addBuilding(lua_State* L) else newDefinition.machine_timing=false; } + newDefinition.room_subset=luaL_optinteger(L,9,-1); hacked_workshops[newDefinition.myType]=newDefinition; return 0; } @@ -354,6 +368,7 @@ static void enable_hooks(bool enable) INTERPOSE_HOOK(work_hook,uncategorize).apply(enable); INTERPOSE_HOOK(work_hook,canConnectToMachine).apply(enable); INTERPOSE_HOOK(work_hook,isUnpowered).apply(enable); + INTERPOSE_HOOK(work_hook,canBeRoomSubset).apply(enable); //update n render INTERPOSE_HOOK(work_hook,updateAction).apply(enable); INTERPOSE_HOOK(work_hook,drawBuilding).apply(enable); diff --git a/plugins/lua/building-hacks.lua b/plugins/lua/building-hacks.lua index e0a5b1010..033a01d5d 100644 --- a/plugins/lua/building-hacks.lua +++ b/plugins/lua/building-hacks.lua @@ -102,8 +102,8 @@ function registerBuilding(args) end frames=processFrames(shop_def,animate.frames) end - - addBuilding(shop_id,fix_impassible,consume,produce,gears,updateSkip,frames,frameLength) + local roomSubset=args.canBeRoomSubset or -1 + addBuilding(shop_id,fix_impassible,consume,produce,gears,updateSkip,frames,frameLength,roomSubset) end return _ENV \ No newline at end of file diff --git a/plugins/lua/eventful.lua b/plugins/lua/eventful.lua index 6e41271ad..91c173e75 100644 --- a/plugins/lua/eventful.lua +++ b/plugins/lua/eventful.lua @@ -98,10 +98,23 @@ function registerReaction(reaction_name,callback) end function registerSidebar(shop_name,callback) - _registeredStuff.customSidebar=_registeredStuff.customSidebar or {} - _registeredStuff.customSidebar[shop_name]=callback - onWorkshopFillSidebarMenu._library=customSidebarsCallback - dfhack.onStateChange.eventful=unregall + if type(callback)=="function" then + _registeredStuff.customSidebar=_registeredStuff.customSidebar or {} + _registeredStuff.customSidebar[shop_name]=callback + onWorkshopFillSidebarMenu._library=customSidebarsCallback + dfhack.onStateChange.eventful=unregall + else + local function drawSidebar( wshop ) + local valid_focus="dwarfmode/QueryBuilding/Some" + if string.sub(dfhack.gui.getCurFocus(),1,#valid_focus)==valid_focus and + wshop:getMaxBuildStage()==wshop:getBuildStage() + then + local sidebar=callback{workshop=wshop} + sidebar:show() + end + end + registerSidebar(shop_name,drawSidebar) + end end function removeNative(shop_name,name) diff --git a/scripts/gui/mod-manager.lua b/scripts/gui/mod-manager.lua index 210109807..a4f503868 100644 --- a/scripts/gui/mod-manager.lua +++ b/scripts/gui/mod-manager.lua @@ -34,7 +34,7 @@ function fileExists(filename) end end if not fileExists(init_file) then - local initFile=io.open(initFileName,"a") + local initFile=io.open(init_file,"a") initFile:close() end function copyFile(from,to) --oh so primitive @@ -52,15 +52,15 @@ function patchInit(initFileName,patch_guard,code) code,patch_guard[2])) initFile:close() end -function patchDofile( initFileName,patch_guard,dofile_list ) - local initFile=io.open(initFileName,"a") - initFile:write(patch_guard[1].."\n") +function patchDofile( luaFileName,patch_guard,dofile_list,mod_path ) + local luaFile=io.open(luaFileName,"a") + luaFile:write(patch_guard[1].."\n") for _,v in ipairs(dofile_list) do - local fixed_path=mod_dir:gsub("\\","/") - initFile:write(string.format("dofile('%s/%s')\n",fixed_path,v)) + local fixed_path=mod_path:gsub("\\","/") + luaFile:write(string.format("dofile('%s/%s')\n",fixed_path,v)) end - initFile:write(patch_guard[2].."\n") - initFile:close() + luaFile:write(patch_guard[2].."\n") + luaFile:close() end function patchFile(file_name,patch_guard,after_string,code) local input_lines=patch_guard[1].."\n"..code.."\n"..patch_guard[2] @@ -294,7 +294,7 @@ function manager:install(trgMod,force) patchInit(init_file,trgMod.guard_init,trgMod.patch_init) end if trgMod.patch_dofile then - patchDofile(init_file,trgMod.guard_init,trgMod.patch_dofile) + patchDofile(init_file,trgMod.guard_init,trgMod.patch_dofile,trgMod.path) end trgMod.installed=true From ee2424c895f359f555cbbf5e1cbb0770c9464a62 Mon Sep 17 00:00:00 2001 From: Warmist Date: Sun, 3 Aug 2014 15:30:22 +0300 Subject: [PATCH 3/4] Doc update --- Lua API.rst | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Lua API.rst b/Lua API.rst index 800b3f011..7283f196f 100644 --- a/Lua API.rst +++ b/Lua API.rst @@ -965,6 +965,12 @@ Job module Compares important fields in the job item structures. +* ``dfhack.job.linkIntoWorld(job,new_id)`` + + Adds job into ``df.global.job_list``, and if new_id + is true, then also sets it's id and increases + ``df.global.job_next_id`` + * ``dfhack.job.listNewlyCreated(first_id)`` Returns the current value of ``df.global.job_next_id``, and @@ -3209,7 +3215,8 @@ Functions 5. ``registerSidebar(shop_name,callback)`` - Enable callback when sidebar for ``shop_name`` is drawn. Usefull for custom workshop views e.g. using gui.dwarfmode lib. + Enable callback when sidebar for ``shop_name`` is drawn. Usefull for custom workshop views e.g. using gui.dwarfmode lib. Also accepts a ``class`` instead of function + as callback. Best used with ``gui.dwarfmode`` class ``WorkshopOverlay``. Examples -------- @@ -3266,7 +3273,8 @@ Functions a. tables of 4 numbers ``{tile,fore,back,bright}`` OR b. empty table (tile not modified) OR c. ``{x= y= + 4 numbers like in first case}``, this generates full frame useful for animations that change little (1-2 tiles) - + 8. canBeRoomSubset -- a flag if this building can be counted in room. 1 means it can, 0 means it can't and -1 default building behaviour + Animate table also might contain: 1. frameLenght -- how many ticks does one frame take OR 2. isMechanical -- a bool that says to try to match to mechanical system (i.e. how gears are turning) From f04b93210adb97b0cf4d6271f8cb4146b48fb2b0 Mon Sep 17 00:00:00 2001 From: Warmist Date: Sun, 3 Aug 2014 16:00:13 +0300 Subject: [PATCH 4/4] Bug fixing. Fixes for "tab" in hacked buildings. --- library/lua/gui/dwarfmode.lua | 9 +++++++-- plugins/lua/eventful.lua | 20 +++++++++++--------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/library/lua/gui/dwarfmode.lua b/library/lua/gui/dwarfmode.lua index a008bb135..ab99dd431 100644 --- a/library/lua/gui/dwarfmode.lua +++ b/library/lua/gui/dwarfmode.lua @@ -423,12 +423,17 @@ WorkshopOverlay.ATTRS={ workshop=DEFAULT_NIL, } function WorkshopOverlay:onInput(keys) - local allowedKeys={ --TODO add options: job management, profile, etc... + local allowedKeys={ --TODO add options: job management, profile, etc... "CURSOR_RIGHT","CURSOR_LEFT","CURSOR_UP","CURSOR_DOWN", - "CURSOR_UPRIGHT","CURSOR_UPLEFT","CURSOR_DOWNRIGHT","CURSOR_DOWNLEFT","CURSOR_UP_Z","CURSOR_DOWN_Z","DESTROYBUILDING"} + "CURSOR_UPRIGHT","CURSOR_UPLEFT","CURSOR_DOWNRIGHT","CURSOR_DOWNLEFT", + "CURSOR_UP_Z","CURSOR_DOWN_Z","DESTROYBUILDING","CHANGETAB"} if keys.LEAVESCREEN then self:dismiss() self:sendInputToParent('LEAVESCREEN') + elseif keys.CHANGETAB then + self:sendInputToParent("CHANGETAB") + self:inputToSubviews(keys) + self:updateLayout() else for _,name in ipairs(allowedKeys) do if keys[name] then diff --git a/plugins/lua/eventful.lua b/plugins/lua/eventful.lua index 91c173e75..f9725ba47 100644 --- a/plugins/lua/eventful.lua +++ b/plugins/lua/eventful.lua @@ -106,11 +106,13 @@ function registerSidebar(shop_name,callback) else local function drawSidebar( wshop ) local valid_focus="dwarfmode/QueryBuilding/Some" - if string.sub(dfhack.gui.getCurFocus(),1,#valid_focus)==valid_focus and - wshop:getMaxBuildStage()==wshop:getBuildStage() - then + if wshop:getMaxBuildStage()==wshop:getBuildStage() then local sidebar=callback{workshop=wshop} - sidebar:show() + if string.sub(dfhack.gui.getCurFocus(),1,#valid_focus)==valid_focus then + sidebar:show() + else + sidebar:show(dfhack.gui.getCurViewscreen(true).parent) + end end end registerSidebar(shop_name,drawSidebar) @@ -139,11 +141,11 @@ function addReactionToShop(reaction_name,shop_name) dfhack.onStateChange.eventful=unregall end local function invertTable(tbl) - local ret={} - for k,v in pairs(tbl) do - ret[v]=k - end - return ret + local ret={} + for k,v in pairs(tbl) do + ret[v]=k + end + return ret end eventType=invertTable{ [0]="TICK",