diff --git a/Lua API.rst b/Lua API.rst index 6c769f004..0c03aa4f9 100644 --- a/Lua API.rst +++ b/Lua API.rst @@ -1768,6 +1768,10 @@ and are only documented here for completeness: The oldval, newval or delta arguments may be used to specify additional constraints. Returns: *found_index*, or *nil* if end reached. +* ``dfhack.internal.getDir(path)`` + + List files in a directory. + Returns: *file_names* or empty table if not found. Core interpreter context ======================== diff --git a/NEWS b/NEWS index f18ee8e67..9cb7ab18e 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ DFHack future Internals: - support for calling a lua function via a protobuf request (demonstrated by dfhack-run --lua). + - Lua API for listing files in directory. Needed for mod-manager. + New scripts: + - gui/mod-manager: allows installing/uninstalling mods into df from df/mods directory. New commands: - move the 'grow', 'extirpate' and 'immolate' commands as 'plant' subcommands diff --git a/Readme.rst b/Readme.rst index 9af33e759..6207b916f 100644 --- a/Readme.rst +++ b/Readme.rst @@ -2382,6 +2382,11 @@ dfhack commands. Useful for hotkeys. Example:: multicmd locate-ore iron ; digv +mod-manager +=========== +This mod script allows installing/removing mod that change/add multiple +files in df with one click of a button. + ======================= In-game interface tools ======================= diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 435360964..b63e58dbf 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -2202,7 +2202,21 @@ static int internal_diffscan(lua_State *L) lua_pushnil(L); return 1; } - +static int internal_getDir(lua_State *L) +{ + luaL_checktype(L,1,LUA_TSTRING); + std::string dir=lua_tostring(L,1); + std::vector files; + DFHack::getdir(dir,files); + lua_newtable(L); + for(int i=0;i>"..modData.name.." patch","<" + end +end +function manager:formAuthor() + return self.selected.author or "" +end +function manager:selectMod(idx,choice) + self.selected=choice.data + if self.subviews.info then + self.subviews.info:setText(self:formDescription()) + self:updateLayout() + end +end +function manager:updateState() + for k,v in pairs(self.mods) do + v.installed=checkInstalled(v) + end +end +function manager:installCurrent() + self:install(self.selected) +end +function manager:uninstallCurrent() + self:uninstall(self.selected) +end +function manager:install(trgMod,force) + + if trgMod==nil then + qerror 'Mod does not exist' + end + if not force then + local isInstalled,file=checkInstalled(trgMod) -- maybe load from .installed? + if isInstalled then + qerror("Mod already installed. File:"..file) + end + end + print("installing:"..trgMod.name) + if trgMod.pre_install then + trgMod.pre_install(args) + end + if trgMod.raws_list then + for k,v in pairs(trgMod.raws_list) do + copyFile(trgMod.path..v,dfhack.getDFPath().."/raw/objects/"..v) + end + end + if trgMod.patch_entity then + local entity_target="[ENTITY:MOUNTAIN]" --TODO configure + patchFile(entity_file,trgMod.guard,entity_target,trgMod.patch_entity) + end + if trgMod.patch_files then + for k,v in pairs(trgMod.patch_files) do + patchFile(dfhack.getDFPath().."/raw/objects/"..v.filename,trgMod.guard,v.after,v.patch) + end + end + if trgMod.patch_init then + patchInit(init_file,trgMod.guard_init,trgMod.patch_init) + end + + trgMod.installed=true + + if trgMod.post_install then + trgMod.post_install(self) + end + print("done") +end +function manager:uninstall(trgMod) + print("Uninstalling:"..trgMod.name) + if trgMod.pre_uninstall then + trgMod.pre_uninstall(args) + end + + if trgMod.raws_list then + for k,v in pairs(trgMod.raws_list) do + os.remove(dfhack.getDFPath().."/raw/objects/"..v) + end + end + if trgMod.patch_entity then + unPatchFile(entity_file,trgMod.guard) + end + if trgMod.patch_files then + for k,v in pairs(trgMod.patch_files) do + unPatchFile(dfhack.getDFPath().."/raw/objects/"..v.filename,trgMod.guard) + end + end + if trgMod.patch_init then + unPatchFile(init_file,trgMod.guard_init) + end + trgMod.installed=false + if trgMod.post_uninstall then + trgMod.post_uninstall(args) + end + print("done") +end +function manager:onInput(keys) + + if keys.LEAVESCREEN then + self:dismiss() + else + self:inputToSubviews(keys) + end + +end +if dfhack.gui.getCurFocus()~='title' then + qerror("Can only be used in title screen") +end +local m=manager{} +m:show() \ No newline at end of file