Merge branch 'develop' into tweak-confirm-embark

develop
lethosor 2014-06-10 12:43:03 -04:00
commit 69c9353196
7 changed files with 180 additions and 14 deletions

@ -7,6 +7,7 @@ DFHack future
- support for multiple raw/init.d/*.lua init scripts in one save. - support for multiple raw/init.d/*.lua init scripts in one save.
- eventful now has a more friendly way of making custom sidebars - eventful now has a more friendly way of making custom sidebars
- new plugin: building-hacks. Allows to add custom functionality and/or animations to buildings. - new plugin: building-hacks. Allows to add custom functionality and/or animations to buildings.
- on Linux and OSX the console now supports moving the cursor back and forward by a whole word.
New scripts: New scripts:
- gui/mod-manager: allows installing/uninstalling mods into df from df/mods directory. - gui/mod-manager: allows installing/uninstalling mods into df from df/mods directory.
@ -28,6 +29,7 @@ DFHack future
New plugins: New plugins:
- rendermax: replace the renderer with something else. Most interesting is "rendermax light"- a lighting engine for df. - rendermax: replace the renderer with something else. Most interesting is "rendermax light"- a lighting engine for df.
- stockflow (by eswald): queues manager jobs of the configured type based on the state of a stockpile.
Misc improvements: Misc improvements:
- digfort: improved csv parsing, add start() comment handling - digfort: improved csv parsing, add start() comment handling

@ -305,6 +305,33 @@ namespace DFHack
} }
/// beep. maybe? /// beep. maybe?
//void beep (void); //void beep (void);
void back_word()
{
if (raw_cursor == 0)
return;
raw_cursor--;
while (raw_cursor > 0 && !isalnum(raw_buffer[raw_cursor]))
raw_cursor--;
while (raw_cursor > 0 && isalnum(raw_buffer[raw_cursor]))
raw_cursor--;
if (!isalnum(raw_buffer[raw_cursor]) && raw_cursor != 0)
raw_cursor++;
prompt_refresh();
}
void forward_word()
{
int len = raw_buffer.size();
if (raw_cursor == len)
return;
raw_cursor++;
while (raw_cursor <= len && !isalnum(raw_buffer[raw_cursor]))
raw_cursor++;
while (raw_cursor <= len && isalnum(raw_buffer[raw_cursor]))
raw_cursor++;
if (raw_cursor > len)
raw_cursor = len;
prompt_refresh();
}
/// A simple line edit (raw mode) /// A simple line edit (raw mode)
int lineedit(const std::string& prompt, std::string& output, recursive_mutex * lock, CommandHistory & ch) int lineedit(const std::string& prompt, std::string& output, recursive_mutex * lock, CommandHistory & ch)
{ {
@ -478,14 +505,27 @@ namespace DFHack
break; break;
case 27: // escape sequence case 27: // escape sequence
lock->unlock(); lock->unlock();
if(!read_char(seq[0]) || !read_char(seq[1])) if (!read_char(seq[0]))
{ {
lock->lock(); lock->lock();
return -2; return -2;
} }
lock->lock(); lock->lock();
if(seq[0] == '[') if (seq[0] == 'b')
{ {
back_word();
}
else if (seq[0] == 'f')
{
forward_word();
}
else if(seq[0] == '[')
{
if (!read_char(seq[1]))
{
lock->lock();
return -2;
}
if (seq[1] == 'D') if (seq[1] == 'D')
{ {
left_arrow: left_arrow:
@ -545,6 +585,7 @@ namespace DFHack
else if (seq[1] > '0' && seq[1] < '7') else if (seq[1] > '0' && seq[1] < '7')
{ {
// extended escape // extended escape
unsigned char seq3[3];
lock->unlock(); lock->unlock();
if(!read_char(seq2)) if(!read_char(seq2))
{ {
@ -561,6 +602,24 @@ namespace DFHack
prompt_refresh(); prompt_refresh();
} }
} }
if (!read_char(seq3[0]) || !read_char(seq3[1]))
{
lock->lock();
return -2;
}
if (seq2 == ';')
{
// Format: esc [ n ; n DIRECTION
// Ignore first character (second "n")
if (seq3[1] == 'C')
{
forward_word();
}
else if (seq3[1] == 'D')
{
back_word();
}
}
} }
} }
break; break;

@ -307,6 +307,33 @@ namespace DFHack
} }
/// beep. maybe? /// beep. maybe?
//void beep (void); //void beep (void);
void back_word()
{
if (raw_cursor == 0)
return;
raw_cursor--;
while (raw_cursor > 0 && !isalnum(raw_buffer[raw_cursor]))
raw_cursor--;
while (raw_cursor > 0 && isalnum(raw_buffer[raw_cursor]))
raw_cursor--;
if (!isalnum(raw_buffer[raw_cursor]) && raw_cursor != 0)
raw_cursor++;
prompt_refresh();
}
void forward_word()
{
int len = raw_buffer.size();
if (raw_cursor == len)
return;
raw_cursor++;
while (raw_cursor <= len && !isalnum(raw_buffer[raw_cursor]))
raw_cursor++;
while (raw_cursor <= len && isalnum(raw_buffer[raw_cursor]))
raw_cursor++;
if (raw_cursor > len)
raw_cursor = len;
prompt_refresh();
}
/// A simple line edit (raw mode) /// A simple line edit (raw mode)
int lineedit(const std::string& prompt, std::string& output, recursive_mutex * lock, CommandHistory & ch) int lineedit(const std::string& prompt, std::string& output, recursive_mutex * lock, CommandHistory & ch)
{ {
@ -480,14 +507,27 @@ namespace DFHack
break; break;
case 27: // escape sequence case 27: // escape sequence
lock->unlock(); lock->unlock();
if(!read_char(seq[0]) || !read_char(seq[1])) if (!read_char(seq[0]))
{ {
lock->lock(); lock->lock();
return -2; return -2;
} }
lock->lock(); lock->lock();
if(seq[0] == '[') if (seq[0] == 'b')
{ {
back_word();
}
else if (seq[0] == 'f')
{
forward_word();
}
else if(seq[0] == '[')
{
if (!read_char(seq[1]))
{
lock->lock();
return -2;
}
if (seq[1] == 'D') if (seq[1] == 'D')
{ {
left_arrow: left_arrow:
@ -547,6 +587,7 @@ namespace DFHack
else if (seq[1] > '0' && seq[1] < '7') else if (seq[1] > '0' && seq[1] < '7')
{ {
// extended escape // extended escape
unsigned char seq3[3];
lock->unlock(); lock->unlock();
if(!read_char(seq2)) if(!read_char(seq2))
{ {
@ -563,6 +604,24 @@ namespace DFHack
prompt_refresh(); prompt_refresh();
} }
} }
if (!read_char(seq3[0]) || !read_char(seq3[1]))
{
lock->lock();
return -2;
}
if (seq2 == ';')
{
// Format: esc [ n ; n DIRECTION
// Ignore first character (second "n")
if (seq3[1] == 'C')
{
forward_word();
}
else if (seq3[1] == 'D')
{
back_word();
}
}
} }
} }
break; break;

@ -42,12 +42,16 @@ namespace DFHack
struct my_hack : df::someclass { struct my_hack : df::someclass {
typedef df::someclass interpose_base; typedef df::someclass interpose_base;
DEFINE_VMETHOD_INTERPOSE(void, foo, (int arg)) { // You may define additional methods here, but NOT non-static fields
DEFINE_VMETHOD_INTERPOSE(int, foo, (int arg)) {
// If needed by the code, claim the suspend lock. // If needed by the code, claim the suspend lock.
// DO NOT USE THE USUAL CoreSuspender, OR IT WILL DEADLOCK! // DO NOT USE THE USUAL CoreSuspender, OR IT WILL DEADLOCK!
// CoreSuspendClaimer suspend; // CoreSuspendClaimer suspend;
... ...
INTERPOSE_NEXT(foo)(arg) // call the original ... this->field ... // access fields of the df::someclass object
...
int orig_retval = INTERPOSE_NEXT(foo)(arg); // call the original method
... ...
} }
}; };

@ -1 +1 @@
Subproject commit 93f89c7c56f366ac8f68e883c9f853a76e12f00a Subproject commit 851f52d5e9eae6fc81adadd10e53bd2cc42bfd21

@ -126,7 +126,7 @@ int getCreatedMetalBars (int32_t idx)
return 0; return 0;
} }
void selectWord (const df::world_raws::T_language::T_word_table &table, int32_t &word, df::enum_field<df::part_of_speech,int16_t> &part, int mode) void selectWord (const df::language_word_table &table, int32_t &word, df::enum_field<df::part_of_speech,int16_t> &part, int mode)
{ {
if (table.parts[mode].size()) if (table.parts[mode].size())
{ {
@ -142,7 +142,7 @@ void selectWord (const df::world_raws::T_language::T_word_table &table, int32_t
} }
} }
void generateName(df::language_name &output, int language, int mode, const df::world_raws::T_language::T_word_table &table1, const df::world_raws::T_language::T_word_table &table2) void generateName(df::language_name &output, int language, int mode, const df::language_word_table &table1, const df::language_word_table &table2)
{ {
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
{ {

@ -1,8 +1,29 @@
-- a graphical mod manager for df
local gui=require 'gui' local gui=require 'gui'
local widgets=require 'gui.widgets' local widgets=require 'gui.widgets'
local entity_file=dfhack.getDFPath().."/raw/objects/entity_default.txt" local entity_file=dfhack.getDFPath().."/raw/objects/entity_default.txt"
local init_file=dfhack.getDFPath().."/raw/init.lua" local init_file=dfhack.getDFPath().."/raw/init.lua"
local mod_dir=dfhack.getDFPath().."/hack/mods"
--[[ mod format: lua script that defines:
name - a name that is displayed in list
author - mod author, also displayed
description - mod description
OPTIONAL:
raws_list - a list (table) of file names that need to be copied over to df raws
patch_entity - a chunk of text to patch entity TODO: add settings to which entities to add
patch_init - a chunk of lua to add to lua init
patch_dofile - a list (table) of files to add to lua init as "dofile"
patch_files - a table of files to patch:
filename - a filename (in raws folder) to patch
patch - what to add
after - a string after which to insert
MORE OPTIONAL:
guard - a token that is used in raw files to find editions and remove them on uninstall
guard_init - a token for lua file
[pre|post]_(un)install - callback functions. Can trigger more complicated behavior
]]
function fileExists(filename) function fileExists(filename)
local file=io.open(filename,"rb") local file=io.open(filename,"rb")
if file==nil then if file==nil then
@ -12,6 +33,10 @@ function fileExists(filename)
return true return true
end end
end end
if not fileExists(init_file) then
local initFile=io.open(initFileName,"a")
initFile:close()
end
function copyFile(from,to) --oh so primitive function copyFile(from,to) --oh so primitive
local filefrom=io.open(from,"rb") local filefrom=io.open(from,"rb")
local fileto=io.open(to,"w+b") local fileto=io.open(to,"w+b")
@ -27,6 +52,16 @@ function patchInit(initFileName,patch_guard,code)
code,patch_guard[2])) code,patch_guard[2]))
initFile:close() initFile:close()
end end
function patchDofile( initFileName,patch_guard,dofile_list )
local initFile=io.open(initFileName,"a")
initFile: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))
end
initFile:write(patch_guard[2].."\n")
initFile:close()
end
function patchFile(file_name,patch_guard,after_string,code) function patchFile(file_name,patch_guard,after_string,code)
local input_lines=patch_guard[1].."\n"..code.."\n"..patch_guard[2] local input_lines=patch_guard[1].."\n"..code.."\n"..patch_guard[2]
@ -109,15 +144,19 @@ manager=defclass(manager,gui.FramedScreen)
function manager:init(args) function manager:init(args)
self.mods={} self.mods={}
local mods=self.mods local mods=self.mods
local mlist=dfhack.internal.getDir("mods") local mlist=dfhack.internal.getDir(mod_dir)
if #mlist==0 then
qerror("Mod directory not found! Are you sure it is in:"..mod_dir)
end
for k,v in ipairs(mlist) do for k,v in ipairs(mlist) do
if v~="." and v~=".." then if v~="." and v~=".." then
local f,modData=pcall(dofile,"mods/".. v .. "/init.lua") local f,modData=pcall(dofile,mod_dir.."/".. v .. "/init.lua")
if f then if f then
mods[modData.name]=modData mods[modData.name]=modData
modData.guard=modData.guard or {">>"..modData.name.." patch","<<End "..modData.name.." patch"} modData.guard=modData.guard or {">>"..modData.name.." patch","<<End "..modData.name.." patch"}
modData.guard_init={"--"..modData.guard[1],"--"..modData.guard[2]} modData.guard_init={"--"..modData.guard[1],"--"..modData.guard[2]}
modData.path=dfhack.getDFPath()..'/mods/'..v..'/' modData.path=mod_dir.."/"..v..'/'
end end
end end
end end
@ -254,7 +293,9 @@ function manager:install(trgMod,force)
if trgMod.patch_init then if trgMod.patch_init then
patchInit(init_file,trgMod.guard_init,trgMod.patch_init) patchInit(init_file,trgMod.guard_init,trgMod.patch_init)
end end
if trgMod.patch_dofile then
patchDofile(init_file,trgMod.guard_init,trgMod.patch_dofile)
end
trgMod.installed=true trgMod.installed=true
if trgMod.post_install then if trgMod.post_install then
@ -281,9 +322,10 @@ function manager:uninstall(trgMod)
unPatchFile(dfhack.getDFPath().."/raw/objects/"..v.filename,trgMod.guard) unPatchFile(dfhack.getDFPath().."/raw/objects/"..v.filename,trgMod.guard)
end end
end end
if trgMod.patch_init then if trgMod.patch_init or trgMod.patch_dofile then
unPatchFile(init_file,trgMod.guard_init) unPatchFile(init_file,trgMod.guard_init)
end end
trgMod.installed=false trgMod.installed=false
if trgMod.post_uninstall then if trgMod.post_uninstall then
trgMod.post_uninstall(args) trgMod.post_uninstall(args)