diff --git a/library/VersionInfo.cpp b/library/VersionInfo.cpp index e0da4ca96..c90654580 100644 --- a/library/VersionInfo.cpp +++ b/library/VersionInfo.cpp @@ -598,7 +598,48 @@ void OffsetGroup::setInvalid(INVAL_TYPE invalidity) (*iter4).second->setInvalid(invalidity); } } - +std::vector OffsetGroup::getKeys() const +{ + std::vector ret; + OffsetKey K; + K.keytype=IS_ADDRESS; + for(uint32_Iter iter = OGd->addresses.begin(); iter != OGd->addresses.end(); iter++) + { + K.key=iter->first; + K.inval=iter->second.first; + ret.push_back(K); + } + K.keytype=IS_OFFSET; + for(int32_Iter iter = OGd->offsets.begin(); iter != OGd->offsets.end(); iter++) + { + K.key=iter->first; + K.inval=iter->second.first; + ret.push_back(K); + } + K.keytype=IS_HEX_VAL; + for(uint32_Iter iter = OGd->hexvals.begin(); iter != OGd->hexvals.end(); iter++) + { + K.key=iter->first; + K.inval=iter->second.first; + ret.push_back(K); + } + K.keytype=IS_STRING; + for(strings_Iter iter = OGd->strings.begin(); iter != OGd->strings.end(); iter++) + { + K.key=iter->first; + K.inval=iter->second.first; + ret.push_back(K); + } + K.keytype=IS_GROUP; + K.inval=IS_VALID; + for(groups_Iter iter = OGd->groups.begin(); iter != OGd->groups.end(); iter++) + { + K.key=iter->first; + + ret.push_back(K); + } + return ret; +} /* * Private data */ diff --git a/library/include/dfhack/VersionInfo.h b/library/include/dfhack/VersionInfo.h index dc084eaae..9d13c5dab 100644 --- a/library/include/dfhack/VersionInfo.h +++ b/library/include/dfhack/VersionInfo.h @@ -52,7 +52,20 @@ namespace DFHack IS_INVALID, IS_VALID }; - + enum KEY_TYPE + { + IS_OFFSET, + IS_ADDRESS, + IS_HEX_VAL, + IS_STRING, + IS_GROUP + }; + struct OffsetKey + { + std::string key; + INVAL_TYPE inval; + KEY_TYPE keytype; + }; /* * Offset Group */ @@ -96,6 +109,8 @@ namespace DFHack std::string getFullName(); OffsetGroup * getParent(); void setInvalid(INVAL_TYPE arg1); + + std::vector getKeys() const; }; /* diff --git a/plugins/Dfusion/CMakeLists.txt b/plugins/Dfusion/CMakeLists.txt index 7b6724dde..8ac2e79e9 100644 --- a/plugins/Dfusion/CMakeLists.txt +++ b/plugins/Dfusion/CMakeLists.txt @@ -7,6 +7,9 @@ set( ${dfhack_SOURCE_DIR}/library/depends/tthread/tinythread.cpp ${DFUSION_CPPS} ) -DFHACK_PLUGIN(dfusion ${DFUSION_CPPS_ALL} LINK_LIBRARIES lua) +FILE(GLOB DFUSION_HS include/*) +SET_SOURCE_FILES_PROPERTIES( ${DFUSION_HS} PROPERTIES HEADER_FILE_ONLY TRUE ) +DFHACK_PLUGIN(dfusion ${DFUSION_CPPS_ALL} ${DFUSION_HS} LINK_LIBRARIES lua) + # installs into DF root install(DIRECTORY luafiles/ DESTINATION dfusion) diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp index 7aa4aba84..cbe84aef9 100644 --- a/plugins/Dfusion/dfusion.cpp +++ b/plugins/Dfusion/dfusion.cpp @@ -18,6 +18,7 @@ #include "lua_Misc.h" #include "lua_VersionInfo.h" #include "functioncall.h" +#include "lua_FunctionCall.h" using std::vector; using std::string; @@ -45,6 +46,8 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector lua::RegisterHexsearch(st); lua::RegisterMisc(st); lua::RegisterVersionInfo(st); + lua::RegisterFunctionCall(st); + #ifdef LINUX_BUILD st.push(1); st.setglobal("LINUX"); @@ -53,7 +56,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector st.setglobal("WINDOWS"); #endif - commands.push_back(PluginCommand("dfusion","Init dfusion system. Use 'dfusion thready' to spawn a different thread.",dfusion)); + commands.push_back(PluginCommand("dfusion","Init dfusion system. Use 'dfusion init' to run dfusion in init mode (not interactive).",dfusion)); commands.push_back(PluginCommand("lua", "Run interactive interpreter. Use 'lua ' to run instead.",lua_run)); mymutex=new tthread::mutex; @@ -171,13 +174,18 @@ void RunDfusion(void *p) } DFhackCExport command_result dfusion (Core * c, vector & parameters) { - if(thread_dfusion==0) - thread_dfusion=new tthread::thread(RunDfusion,c); - if(parameters[0]!="thready") + if(parameters[0]=="init") { - thread_dfusion->join(); - delete thread_dfusion; - thread_dfusion=0; + lua::state s=lua::glua::Get(); + s.push(1); + s.setglobal("INIT"); + } + else + { + lua::state s=lua::glua::Get(); + s.push(); + s.setglobal("INIT"); } + RunDfusion(c); return CR_OK; } diff --git a/plugins/Dfusion/include/lua_FunctionCall.h b/plugins/Dfusion/include/lua_FunctionCall.h new file mode 100644 index 000000000..bc1af5685 --- /dev/null +++ b/plugins/Dfusion/include/lua_FunctionCall.h @@ -0,0 +1,14 @@ +#ifndef LUA_FUNCTIONCALL__H +#define LUA_FUNCTIONCALL__H + +#include "luamain.h" +#include "functioncall.h" + +namespace lua +{ + + +void RegisterFunctionCall(lua::state &st); + +} +#endif \ No newline at end of file diff --git a/plugins/Dfusion/include/lua_VersionInfo.h b/plugins/Dfusion/include/lua_VersionInfo.h index 26cdc96db..e221eff04 100644 --- a/plugins/Dfusion/include/lua_VersionInfo.h +++ b/plugins/Dfusion/include/lua_VersionInfo.h @@ -28,6 +28,7 @@ public: int getName(lua_State *L); int getFullName(lua_State *L); int getParent(lua_State *L); + int getKeys(lua_State *L); DEF_LUNE(OffsetGroup); }; diff --git a/plugins/Dfusion/luafiles/common.lua b/plugins/Dfusion/luafiles/common.lua index 610b5f598..98043f463 100644 --- a/plugins/Dfusion/luafiles/common.lua +++ b/plugins/Dfusion/luafiles/common.lua @@ -3,6 +3,11 @@ STD_STRING=0 DWORD=1 WORD=2 BYTE=3 +function printd(...) + if DEBUG then + print(...) + end +end function GetTextRegion() if __TEXT ~=nil then --Chache this, not going to change. return __TEXT @@ -324,7 +329,7 @@ function findVectors() local loc1,loc2 loc1=engine.peekd(v+2) loc2=engine.peekd(v+8) - print(string.format("%x - %x=%x",loc1,loc2,loc1-loc2)) + --print(string.format("%x - %x=%x",loc1,loc2,loc1-loc2)) if(loc1-loc2==4) then if T[loc1-4]~=nil then T[loc1-4]=T[loc1-4]+1 diff --git a/plugins/Dfusion/luafiles/embark/init.lua b/plugins/Dfusion/luafiles/embark/init.lua new file mode 100644 index 000000000..477e0255a --- /dev/null +++ b/plugins/Dfusion/luafiles/embark/init.lua @@ -0,0 +1,71 @@ +function MakeTable(modpos,modsize,names) + count=0 + castes={} + --print("Making table") + for _,line in pairs(names) do + --print("Line:"..line) + tpos=string.find(line,":") + if tpos~=nil then + --print("Was line:"..line) + table.insert(castes,tonumber(string.sub(line,tpos+1))) + line=string.sub(line,1,tpos-1) + --print("IS line:"..line) + else + table.insert(castes,-1) + end + if RaceTable[line] == nil then + error("Failure, "..line.." not found!") + end + engine.pokew(modpos+modsize+count*2,RaceTable[line]) -- add race + count = count + 1 + end + i=0 + for _,caste in pairs(castes) do + + engine.pokew(modpos+modsize+count*2+i*2,caste) -- add caste + i= i+1 + end + + engine.poked(stoff,count) + return count +end +function embark(names) + RaceTable=RaceTable or BuildNameTable() + mypos=engine.getmod('Embark') + stoff=offsets.getEx('StartDwarfs') + if mypos then --if mod already loaded + print("Mod already loaded @:"..mypos.." just updating") + modpos=mypos + _,modsize=engine.loadobj('dfusion/embark/embark.o') + + count=MakeTable(modpos,modsize,names) --just remake tables + else + + tofind=VersionInfo.getGroup("Creatures"):getAddress("current_race")--offsets.getEx('CurrentRace') + + loc=offsets.find(stoff,0xa1,DWORD_,tofind) + + print("found:"..loc) + + if((loc~=0)and(loc-stoff<1000)) then + modpos,modsize=engine.loadmod('dfusion/embark/embark.o','Embark',256) + count=MakeTable(modpos,modsize,names) + engine.poked(modpos+0x18,modpos+modsize) --fix array start for race + engine.poked(modpos+0x08,modpos+modsize+count*2) --fix array start for caste + print("sucess loading mod @:"..modpos) + -- build race vector after module. + + + --finaly poke in the call! + engine.pokeb(loc,0x6a) + engine.pokeb(loc+1,0xFF) + engine.pokeb(loc+2,0xe8) + engine.poked(loc+3,modpos-loc-7) + --engine.pokeb(loc+5,0x90) + SetExecute(modpos) + else + error("did not find patch location, failing...") + end + + end +end \ No newline at end of file diff --git a/plugins/Dfusion/luafiles/embark/plugin.lua b/plugins/Dfusion/luafiles/embark/plugin.lua index db65da78c..039000656 100644 --- a/plugins/Dfusion/luafiles/embark/plugin.lua +++ b/plugins/Dfusion/luafiles/embark/plugin.lua @@ -1,74 +1,4 @@ -function MakeTable(modpos,modsize,names) - count=0 - castes={} - --print("Making table") - for _,line in pairs(names) do - --print("Line:"..line) - tpos=string.find(line,":") - if tpos~=nil then - --print("Was line:"..line) - table.insert(castes,tonumber(string.sub(line,tpos+1))) - line=string.sub(line,1,tpos-1) - --print("IS line:"..line) - else - table.insert(castes,-1) - end - if RaceTable[line] == nil then - error("Failure, "..line.." not found!") - end - engine.pokew(modpos+modsize+count*2,RaceTable[line]) -- add race - count = count + 1 - end - i=0 - for _,caste in pairs(castes) do - - engine.pokew(modpos+modsize+count*2+i*2,caste) -- add caste - i= i+1 - end - - engine.poked(stoff,count) - return count -end -function embark(names) - RaceTable=RaceTable or BuildNameTable() - mypos=engine.getmod('Embark') - stoff=offsets.getEx('StartDwarfs') - if mypos then --if mod already loaded - print("Mod already loaded @:"..mypos.." just updating") - modpos=mypos - _,modsize=engine.loadobj('dfusion/embark/embark.o') - - count=MakeTable(modpos,modsize,names) --just remake tables - else - - tofind=VersionInfo.getGroup("Creatures"):getAddress("current_race")--offsets.getEx('CurrentRace') - loc=offsets.find(stoff,0xa1,DWORD_,tofind) - - print("found:"..loc) - - if((loc~=0)and(loc-stoff<1000)) then - modpos,modsize=engine.loadmod('dfusion/embark/embark.o','Embark',256) - count=MakeTable(modpos,modsize,names) - engine.poked(modpos+0x18,modpos+modsize) --fix array start for race - engine.poked(modpos+0x08,modpos+modsize+count*2) --fix array start for caste - print("sucess loading mod @:"..modpos) - -- build race vector after module. - - - --finaly poke in the call! - engine.pokeb(loc,0x6a) - engine.pokeb(loc+1,0xFF) - engine.pokeb(loc+2,0xe8) - engine.poked(loc+3,modpos-loc-7) - --engine.pokeb(loc+5,0x90) - SetExecute(modpos) - else - error("did not find patch location, failing...") - end - - end -end if not(FILE)then names=ParseNames("dfusion/embark/races.txt")--io.open("plugins/embark/races.txt"):lines() embark(names) diff --git a/plugins/Dfusion/luafiles/friendship_civ/compile.bat b/plugins/Dfusion/luafiles/friendship_civ/compile.bat new file mode 100644 index 000000000..64d4d4440 --- /dev/null +++ b/plugins/Dfusion/luafiles/friendship_civ/compile.bat @@ -0,0 +1 @@ +as -anl --32 -o friendship_c.o friendship_c.asm \ No newline at end of file diff --git a/plugins/Dfusion/luafiles/friendship_civ/friendship_c.asm b/plugins/Dfusion/luafiles/friendship_civ/friendship_c.asm new file mode 100644 index 000000000..b2b49ee78 --- /dev/null +++ b/plugins/Dfusion/luafiles/friendship_civ/friendship_c.asm @@ -0,0 +1,41 @@ +.intel_syntax +eaxpart: +push eax +push ecx +jmp compare +ecxpart: +push eax +push ecx +mov eax,ecx + +compare: +push ebx +mov ebx,0xDEADBEEF #write a pointer to the list of allowed civs +mov ecx,2000 #write a number of allowed civs +loop1: +cmp [ebx+ecx*4],eax +jnz endok +dec ecx +cmp ecx ,-1 +jnz loop1 + +pop ebx + +jmp fail + +endok: +pop ebx + +cmp eax,eax +jmp endfinal +fail: + +xor ecx,ecx +xor eax,eax +inc eax +cmp eax,ebx +endfinal: + +pop ecx +pop eax +ret \ No newline at end of file diff --git a/plugins/Dfusion/luafiles/friendship_civ/friendship_c.o b/plugins/Dfusion/luafiles/friendship_civ/friendship_c.o new file mode 100644 index 000000000..d85134682 Binary files /dev/null and b/plugins/Dfusion/luafiles/friendship_civ/friendship_c.o differ diff --git a/plugins/Dfusion/luafiles/friendship_civ/init.lua b/plugins/Dfusion/luafiles/friendship_civ/init.lua new file mode 100644 index 000000000..5390829de --- /dev/null +++ b/plugins/Dfusion/luafiles/friendship_civ/init.lua @@ -0,0 +1,89 @@ +friendship_civ={} +function friendship_civ.init() + friendship_civ.count=0x0f + friendship_civ.firsttime=true + local mypos=engine.getmod("Friendship_civ") + local modpos=0 + if mypos then + modpos=mypos + _,modsize=engine.loadobj("dfusion/friendship_civ/friendship_c.o") + _=nil + friendship_civ.firsttime=false + else + modpos,modsize=engine.loadmod("dfusion/friendship_civ/friendship_c.o","Friendship_civ",1024) + print(string.format("Loaded module @:%x",modpos)) + end + friendship_civ.modpos=modpos + friendship_civ.modsize=modsize +end +function friendship_civ.install(civs) + friendship_civ.init() + local count=0 + for _,v in pairs(civs) do + engine.poked(friendship_civ.modpos+friendship_civ.modsize+count*4,v) -- for some reason it compiled strangely + -- cmp word[ebx+ecx*2],ax -> cmp word[ebx+ecx*2+2],ax + count = count + 1 + end + engine.poked(friendship_civ.modpos+0x0a,friendship_civ.modpos+friendship_civ.modsize) -- set ptr to civ ids + engine.poked(friendship_civ.modpos+friendship_civ.count,count-1) -- set count of civs + SetExecute(friendship_civ.modpos) + + if(friendship_civ.firsttime) then + friendship_civ.patch() + end +end +function friendship_civ.getcivs() + if(friendship_civ.firsttime==nil)then + return nil + end + friendship_civ.init() + local count=engine.peekd(friendship_civ.modpos+friendship_civ.count)+1 + local ret={} + for i=0, count-1 do + table.insert(ret,engine.peekd(friendship_civ.modpos+friendship_civ.modsize+i*4)) + end + return ret +end +function friendship_civ.addciv(civ) --if called with nil add current civ :) + if civ==nil then + local cciv=engine.peekd(VersionInfo.getGroup("Creatures"):getAddress("current_civ")) + friendship_civ.install({cciv}) + return + end + local oldcivs=friendship_civ.getcivs() + oldcivs=oldcivs or {} + if type(civ)=="table" then + for k,v in ipairs(civ) do + table.insert(oldcivs,v) + end + else + table.insert(oldcivs,civ) + end + friendship_civ.install(oldcivs) +end +function friendship_civ.patch_call(off,iseax) + local calltrg=friendship_civ.modpos + if not iseax then + calltrg=calltrg+4 + end + engine.pokeb(off,0xe8) --this is a call + engine.poked(off+1,calltrg-off-5) --offset to call to (relative) + engine.pokeb(off+5,0x90) --nop +end +function friendship_civ.patch() + --UpdateRanges() + local civloc= VersionInfo.getGroup("Creatures"):getAddress("current_civ") + local pos1=offsets.findall(0,0x3B,0x05,DWORD_,civloc) --eax + for k,v in pairs(pos1) do print(string.format("%d %x",k,v)) end + local pos2=offsets.findall(0,0x3B,0x0D,DWORD_,civloc) --ecx + for k,v in pairs(pos2) do print(string.format("%d %x",k,v)) end + + for k,v in pairs(pos1) do + print(string.format("Patching eax compare %d: %x",k,v)) + friendship_civ.patch_call(v,true) + end + for k,v in pairs(pos2) do + print(string.format("Patching ecx compare %d: %x",k,v)) + friendship_civ.patch_call(v,false) + end +end diff --git a/plugins/Dfusion/luafiles/friendship_civ/plugin.lua b/plugins/Dfusion/luafiles/friendship_civ/plugin.lua new file mode 100644 index 000000000..12f334fcf --- /dev/null +++ b/plugins/Dfusion/luafiles/friendship_civ/plugin.lua @@ -0,0 +1,57 @@ +fc_ui={} +fc_ui.menu=MakeMenu() +function fc_ui.get() + local mycivs=friendship_civ.getcivs() + if mycivs~= nil then + print(" Currently friendly civs:") + for k,v in pairs(mycivs) do + print(string.format("%d. %d",k,v)) + end + else + print(" Plugin no yet activated.") + end +end +function fc_ui.add() + print("Type in civ id to add (leave empty to add current, q cancels):") + local r + while r==nil and r~='q' do + r=io.stdin:read() + if r=="" then + r=nil + break + end + if r~='q' then r=tonumber(r) else + return + end + end + friendship_civ.addciv(r) +end +function fc_ui.remove() + local mycivs=friendship_civ.getcivs() + if mycivs~= nil then + print(" Currently friendly civs:") + for k,v in pairs(mycivs) do + print(string.format("%d. %d",k,v)) + end + else + print(" Plugin no yet activated, nothing to remove.") + return + end + print("Type in civ id to remove( q cancels):") + local r + while r==nil and r~='q' do + r=io.stdin:read() + if r~='q' then + r=tonumber(r) + if r>#mycivs then r=nil end + else + return + end + end + table.remove(mycivs,r) + friendship_civ.install(mycivs) +end +fc_ui.menu:add("Add civ",fc_ui.add) +fc_ui.menu:add("Get civs",fc_ui.get) +fc_ui.menu:add("Remove civ",fc_ui.remove) +fc_ui.menu:display() \ No newline at end of file diff --git a/plugins/Dfusion/luafiles/init.lua b/plugins/Dfusion/luafiles/init.lua index 427682e45..5adb9abe3 100644 --- a/plugins/Dfusion/luafiles/init.lua +++ b/plugins/Dfusion/luafiles/init.lua @@ -43,12 +43,14 @@ function mainmenu(t1) end end dofile("dfusion/common.lua") +dofile("dfusion/utils.lua") unlockDF() plugins={} table.insert(plugins,{"simple_embark","A simple embark dwarf count editor"}) table.insert(plugins,{"items","A collection of item hacking tools"}) table.insert(plugins,{"offsets","Find all offsets"}) table.insert(plugins,{"friendship","Multi race fort enabler"}) +table.insert(plugins,{"friendship_civ","Multi civ fort enabler"}) table.insert(plugins,{"embark","Multi race embark"}) table.insert(plugins,{"adv_tools","some tools for (mainly) advneturer hacking"}) table.insert(plugins,{"tools","some misc tools"}) @@ -56,6 +58,14 @@ table.insert(plugins,{"triggers","a function calling plug (discontinued...)"}) table.insert(plugins,{"migrants","multi race imigrations"}) table.insert(plugins,{"onfunction","run lua on some df function"}) loadall(plugins) +dofile_silent("dfusion/initcustom.lua") + +print("Locating saves...") +local str=engine.peekstr(0x1447A40+offsets.base()) +print("Current region:"..str) +str="data/save/"..str.."/dfusion/init.lua" +dofile_silent(str) + if not INIT then mainmenu(plugins) end diff --git a/plugins/Dfusion/luafiles/migrants/init.lua b/plugins/Dfusion/luafiles/migrants/init.lua new file mode 100644 index 000000000..85463fe7e --- /dev/null +++ b/plugins/Dfusion/luafiles/migrants/init.lua @@ -0,0 +1,61 @@ +--install part +function migrants(names) +RaceTable=RaceTable or BuildNameTable() +mypos=engine.getmod("Migrants") +if mypos then + print("Migrant mod is running already @:"..mypos) + modpos=mypos + _,modsize=engine.loadobj("dfusion/migrants/migrants.o") + count=0 + for _,v in pairs(names) do + if RaceTable[v] == nil then + print("Failure, "..v.." not found!") + break --maybe some indication of failure? and cleanup? + end + engine.pokew(modpos+modsize+count*2+4,RaceTable[v]) + count = count + 1 + end + seedpos=modpos+modsize + engine.poked(seedpos,math.random(1234567)) -- seed the generator :) + engine.poked(modpos+0x1c,count) --max size for div + +else + modpos,modsize=engine.loadmod("dfusion/migrants/migrants.o","Migrants") + print(string.format("Loaded module @:%x",modpos)) + count=0 + for _,v in pairs(names) do + if RaceTable[v] == nil then + print("Failure, "..v.." not found!") + break --maybe some indication of failure? and cleanup? + end + engine.pokew(modpos+modsize+count*2+4,RaceTable[v]) + + count = count + 1 + end + + seedpos=modpos+modsize + engine.poked(modpos+0x04,seedpos) + engine.poked(modpos+0x15,seedpos) + + engine.poked(seedpos,math.random(1234567)) -- seed the generator :) + engine.poked(modpos+0x1c,count) --max size for div + + engine.poked(modpos+0x26,seedpos+4) --start of array + + --patch part + --pos=62873C+DF + -- pattern: A1,DWORD_,"CURRENTRACE",56,89,ANYBYTE,ANYBYTE,34,e8 + pos=offsets.find(offsets.base(),0xa1,DWORD_,offsets.getEx("CurrentRace"),0x56,0x89,ANYBYTE,ANYBYTE,0x34,0xe8) + function pokeCall(off) + engine.pokeb(off,0xe8) + engine.poked(off+1,modpos-off-5) + end + if pos~=0 then + print(string.format("Found @:%x",pos)) + pokeCall(pos) + else + print("Not found patch location!!!") + end + end + +end \ No newline at end of file diff --git a/plugins/Dfusion/luafiles/migrants/plugin.lua b/plugins/Dfusion/luafiles/migrants/plugin.lua index 0e1e46160..651e4900c 100644 --- a/plugins/Dfusion/luafiles/migrants/plugin.lua +++ b/plugins/Dfusion/luafiles/migrants/plugin.lua @@ -1,64 +1,4 @@ ---install part -function migrants(names) -RaceTable=RaceTable or BuildNameTable() -mypos=engine.getmod("Migrants") -if mypos then - print("Migrant mod is running already @:"..mypos) - modpos=mypos - _,modsize=engine.loadobj("dfusion/migrants/migrants.o") - count=0 - for _,v in pairs(names) do - if RaceTable[v] == nil then - print("Failure, "..v.." not found!") - break --maybe some indication of failure? and cleanup? - end - engine.pokew(modpos+modsize+count*2+4,RaceTable[v]) - count = count + 1 - end - seedpos=modpos+modsize - engine.poked(seedpos,math.random(1234567)) -- seed the generator :) - engine.poked(modpos+0x1c,count) --max size for div - -else - modpos,modsize=engine.loadmod("dfusion/migrants/migrants.o","Migrants") - print(string.format("Loaded module @:%x",modpos)) - count=0 - for _,v in pairs(names) do - if RaceTable[v] == nil then - print("Failure, "..v.." not found!") - break --maybe some indication of failure? and cleanup? - end - engine.pokew(modpos+modsize+count*2+4,RaceTable[v]) - - count = count + 1 - end - seedpos=modpos+modsize - engine.poked(modpos+0x04,seedpos) - engine.poked(modpos+0x15,seedpos) - - engine.poked(seedpos,math.random(1234567)) -- seed the generator :) - engine.poked(modpos+0x1c,count) --max size for div - - engine.poked(modpos+0x26,seedpos+4) --start of array - - --patch part - --pos=62873C+DF - -- pattern: A1,DWORD_,"CURRENTRACE",56,89,ANYBYTE,ANYBYTE,34,e8 - pos=offsets.find(offsets.base(),0xa1,DWORD_,offsets.getEx("CurrentRace"),0x56,0x89,ANYBYTE,ANYBYTE,0x34,0xe8) - function pokeCall(off) - engine.pokeb(off,0xe8) - engine.poked(off+1,modpos-off-5) - end - if pos~=0 then - print(string.format("Found @:%x",pos)) - pokeCall(pos) - else - print("Not found patch location!!!") - end - end - -end if not(FILE) then names=ParseNames("dfusion/migrants/races.txt")--io.open("plugins/migrants/races.txt"):lines() migrants(names) diff --git a/plugins/Dfusion/luafiles/onfunction/locations.lua b/plugins/Dfusion/luafiles/onfunction/locations.lua index 677771392..57043b7a3 100644 --- a/plugins/Dfusion/luafiles/onfunction/locations.lua +++ b/plugins/Dfusion/luafiles/onfunction/locations.lua @@ -7,6 +7,7 @@ if WINDOWS then --windows function defintions onfunction.AddFunction(0x3d4301+offsets.base(),"Make_Item",{item_type="esp"}) onfunction.AddFunction(0x5af826+offsets.base(),"Hurt",{target="esi",attacker={off=0x74,rtype=DWORD,reg="esp"}}) onfunction.AddFunction(0x3D5886+offsets.base(),"Flip",{building="esi"}) + onfunction.AddFunction(0x35E340+offsets.base(),"ItemCreate") else --linux onfunction.AddFunction(0x899befe+offsets.base(),"Move") -- found out by attaching watch... onfunction.AddFunction(0x850eecd+offsets.base(),"Die",{creature="ebx"}) -- same diff --git a/plugins/Dfusion/luafiles/patterns.lua b/plugins/Dfusion/luafiles/patterns.lua index 1d15741eb..c9f0e8c37 100644 --- a/plugins/Dfusion/luafiles/patterns.lua +++ b/plugins/Dfusion/luafiles/patterns.lua @@ -195,7 +195,7 @@ ptr_CrGloss.castes={off=296,rtype=ptr_vector} ptr_CrCaste={} ptr_CrCaste.name={off=0,rtype=ptt_dfstring} -ptr_CrCaste.flags_ptr={off=0x524,rtype=DWORD} --size 17? +ptr_CrCaste.flags_ptr={off=0x5A0,rtype=DWORD} --size 17? --[=[ Flags: 57 - is sentient (allows setting labours) diff --git a/plugins/Dfusion/luafiles/tools/init.lua b/plugins/Dfusion/luafiles/tools/init.lua new file mode 100644 index 000000000..b6720d2b7 --- /dev/null +++ b/plugins/Dfusion/luafiles/tools/init.lua @@ -0,0 +1,497 @@ +tools={} +tools.menu=MakeMenu() +function tools.setrace() + RaceTable=RaceTable or BuildNameTable() --slow.If loaded don't load again + print("Your current race is:"..GetRaceToken(engine.peekw(offsets.getEx('CurrentRace')))) + print("Type new race's token name in full caps:") + repeat + entry=io.stdin:read() + id=RaceTable[entry] + until id~=nil + engine.pokew(offsets.getEx('CurrentRace'),id) +end +tools.menu:add("Set current race",tools.setrace) +function tools.GiveSentience(names) --TODO make pattern... + RaceTable=RaceTable or BuildNameTable() --slow.If loaded don't load again + if names ==nil then + ids={} + print("Type race's token name in full caps to give sentience to:") + repeat + entry=io.stdin:read() + id=RaceTable[entry] + until id~=nil + table.insert(ids,id) + else + ids={} + for _,name in pairs(names) do + id=RaceTable[name] + table.insert(ids,id) + end + end + for _,id in pairs(ids) do + local off=offsets.getEx('CreatureGloss') + local races=engine.peek(off,ptr_vector) + --print("Vector start:"..off) + + off=races:getval(id) + print(string.format("race location:%x",off)) + local castes=engine.peek(off,ptr_CrGloss.castes) + print(string.format("Caste count:%i",castes:size())) + local flagPattern=ptt_dfflag.new(17) + for i =0,castes:size()-1 do + local offCaste=castes:getval(i) + print("Caste name:"..engine.peek(offCaste,ptr_CrCaste.name):getval().."...") + local flagoffset=engine.peek(offCaste,ptr_CrCaste.flags_ptr) + local flags=engine.peek(flagoffset,flagPattern) + --print(string.format("%x",flagoffset)) + if flags:get(57) then + print("\tis sentient.") + else + print("\tnon sentient. Allocating IQ...") + flags:set(57,1) + engine.poke(flagoffset,flagPattern,flags) + end + end + end +end +tools.menu:add("Give Sentience",tools.GiveSentience) +function tools.embark() + off=offsets.find(0,0x66, 0x83, 0x7F ,0x1A ,0xFF,0x74,0x04) + if off~=0 then + engine.pokeb(off+5,0x90) + engine.pokeb(off+6,0x90) + print("Found and patched") + else + print("not found") + end +end +tools.menu:add("Embark anywhere",tools.embark) +function tools.getlegendsid(croff) + local vec=engine.peek(croff,ptr_Creature.legends) + if vec:size()==0 then + return 0 + end + for i =0,vector:size()-1 do + --if engine.peekd(vec:getval(i))~=0 then + -- print(string.format("%x",engine.peekd(vec:getval(i))-offsets.base())) + --end + if(engine.peekd(vec:getval(i))==offsets.getEx("vtableLegends")) then --easy to get.. just copy from player's-base + return engine.peekd(vec:getval(i)+4) + end + end + return 0 +end +function tools.getCreatureId(vector) + + tnames={} + rnames={} + --[[print("vector1 size:"..vector:size()) + print("vector2 size:"..vector2:size())]]-- + for i=0,vector:size()-1 do + --print(string.format("%x",vector:getval(i))) + + local name=engine.peek(vector:getval(i),ptt_dfstring):getval() + local lid= tools.getlegendsid(vector:getval(i)) + if lid ~=0 then + print(i..")*Creature Name:"..name.." race="..engine.peekw(vector:getval(i)+ptr_Creature.race.off).." legendid="..lid) + else + print(i..") Creature Name:"..name.." race="..engine.peekw(vector:getval(i)+ptr_Creature.race.off)) + end + if name ~="" and name~=nil then + tnames[i]=name + rnames[name]=i + end + end + print("=====================================") + print("type in name or number:") + r=io.stdin:read() + if tonumber(r) ==nil then + indx=rnames[r] + if indx==nil then return end + else + r=tonumber(r) + if rLOVE), q to quit:") + names={} + repeat + w=io.stdin:read(); + + if rwords[w]~=nil then + table.insert(names,w) + print("--added--") + end + + until w=='q' + end + + tnames={} + for _,v in pairs(names) do + if rwords[v] ~=nil then + table.insert(tnames,rwords[v]) --get word numbers + end + end + + local offsites=engine.peekd(offsets.getEx("SiteData"))+0x120 + snames={" pfort"," dfort"," cave","mohall","forest","hamlet","imploc"," lair"," fort"," camp"} + vector=engine.peek(offsites,ptr_vector) + print("Number of sites:"..vector:size()) + print("List of hits:") + for i =0,vector:size()-1 do + off=vector:getval(i) + + good=true + r="" + hits=0 + sname=engine.peek(off,ptr_site.name) + for k=0,6 do + vnum=sname[k]--engine.peekd(off+0x38+k*4) + tgood=false + + if vnum~=0xFFFFFFFF then + --print(string.format("%x",vnum)) + if names[vnum]~=nil then + r=r..names[vnum].." " + end + for _,v in pairs(tnames) do + if vnum==v then + tgood=true + --print("Match") + hits=hits+1 + break + end + end + if not tgood then + good=false + end + end + end + + if(good) and (hits>0)then + --if true then + --print("=====================") + typ=engine.peek(off,ptr_site.type)--engine.peekw(off+0x78) + flg=engine.peekd(engine.peek(off,ptr_site.flagptr)) + --flg=engine.peekd(off+224) + --flg2=engine.peekw(off) + --tv=engine.peek(off+0x84,ptr_vector) + --tv2=engine.peek(off+0xA4,ptr_vector) + + print(string.format("%d)%s off=%x type=%s\t flags=%x",i,r,off,snames[typ+1],flg)) + + if i%100==99 then + r=io.stdin:read() + end + + end + end + print("Type which to change (q cancels):") + repeat + r=io.stdin:read() + n=tonumber(r) + if(r=='q') then return end + until n~=nil + return vector:getval(n) +end +function tools.changesite(names) + off=tools.getsite(names) + snames={"Mountain halls (yours)","Dark fort","Cave","Mountain hall (NPC)","Forest retreat","Hamlet","Important location","Lair","Fort","Camp"} + + print("Type in the site type (q cancels):") + for k,v in pairs(snames) do + print((k-1).."->"..v) + end + repeat + r=io.stdin:read() + n2=tonumber(r) + if(r=='q') then return end + until n2~=nil + --off=vector:getval(n) + print(string.format("%x->%d",off,n2)) + engine.poke(off,ptr_site.type,n2) +end +function tools.changeflags(names) + myflag_pattern=ptt_dfflag.new(3*8) + off=tools.getsite(names) + offflgs=engine.peek(off,ptr_site.flagptr) + q='' + print(string.format("Site offset %x flags offset %x",off,offflgs)) + repeat + print("flags:") + + --off=vector:getval(n) + flg=engine.peek(offflgs,myflag_pattern) + r="" + for i=0,3*8-1 do + if flg:get(i)==1 then + r=r.."x" + else + r=r.."o" + end + if i%8==7 then + print(i-7 .."->"..r) + r="" + end + end + print("Type number to flip, or 'q' to quit.") + q=io.stdin:read() + n2=tonumber(q) + if n2~=nil then + + flg:flip(n2) + engine.poke(offflgs,myflag_pattern,flg) + end + until q=='q' +end +function tools.hostilate() + vector=engine.peek(offsets.getEx("CreatureVec"),ptr_vector) + id=engine.peekd(offsets.getEx("CreaturePtr")) + print(string.format("Vec:%d cr:%d",vector:size(),id)) + off=vector:getval(id) + crciv=engine.peek(off,ptr_Creature.civ) + print("Creatures civ:"..crciv) + curciv=engine.peekd(offsets.getEx("CurrentRace")-12) + print("My civ:"..curciv) + if curciv==crciv then + print("Friendly-making enemy") + engine.poke(off,ptr_Creature.civ,-1) + flg=engine.peek(off,ptr_Creature.flags) + flg:set(17,0) + print("flag 51:"..tostring(flg:get(51))) + engine.poke(off,ptr_Creature.flags,flg) + else + print("Enemy- making friendly") + engine.poke(off,ptr_Creature.civ,curciv) + flg=engine.peek(off,ptr_Creature.flags) + flg:set(17,1) + flg:set(19,0) + engine.poke(off,ptr_Creature.flags,flg) + end +end +function tools.mouseBlock() + local xs,ys,zs + xs,ys,zs=getxyz() + xs=math.floor(xs/16) + ys=math.floor(ys/16) + print("Mouse block is:"..xs.." "..ys.." "..zs) +end +function tools.protectsite() + local mapoffset=offsets.getEx("WorldData")--0x131C128+offsets.base() + local x=engine.peek(mapoffset+24,DWORD) + local y=engine.peek(mapoffset+28,DWORD) + local z=engine.peek(mapoffset+32,DWORD) + --vec=engine.peek(mapoffset,ptr_vector) + + print("Blocks loaded:"..x.." "..y.." "..z) + print("Select type:") + print("1. All (SLOW)") + print("2. range (x0 x1 y0 y1 z0 z1)") + print("3. One block around pointer") + print("anything else- quit") + q=io.stdin:read() + n2=tonumber(q) + if n2==nil then return end + if n2>3 or n2<1 then return end + local xs,xe,ys,ye,zs,ze + if n2==1 then + xs=0 + xe=x-1 + ys=0 + ye=y-1 + zs=0 + ze=z-1 + elseif n2==2 then + print("enter x0:") + xs=tonumber(io.stdin:read()) + print("enter x1:") + xe=tonumber(io.stdin:read()) + print("enter y0:") + ys=tonumber(io.stdin:read()) + print("enter y1:") + ye=tonumber(io.stdin:read()) + print("enter z0:") + zs=tonumber(io.stdin:read()) + print("enter z1:") + ze=tonumber(io.stdin:read()) + function clamp(t,vmin,vmax) + if t> vmax then return vmax end + if t< vmin then return vmin end + return t + end + xs=clamp(xs,0,x-1) + ys=clamp(ys,0,y-1) + zs=clamp(zs,0,z-1) + xe=clamp(xe,xs,x-1) + ye=clamp(ye,ys,y-1) + ze=clamp(ze,zs,z-1) + else + xs,ys,zs=getxyz() + xs=math.floor(xs/16) + ys=math.floor(ys/16) + xe=xs + ye=ys + ze=zs + end + local xblocks=engine.peek(mapoffset,DWORD) + local flg=bit.lshift(1,14) + for xx=xs,xe do + local yblocks=engine.peek(xblocks+xx*4,DWORD) + for yy=ys,ye do + local zblocks=engine.peek(yblocks+yy*4,DWORD) + for zz=zs,ze do + + + + local myblock=engine.peek(zblocks+zz*4,DWORD) + if myblock~=0 then + for i=0,255 do + local ff=engine.peek(myblock+0x67c+i*4,DWORD) + ff=bit.bor(ff,flg) --set 14 flag to 1 + engine.poke(myblock+0x67c+i*4,DWORD,ff) + end + end + end + print("Blocks done:"..xx.." "..yy) + end + end +end +function tools.fixwarp() + local mapoffset=offsets.getEx("WorldData")--0x131C128+offsets.base() + local x=engine.peek(mapoffset+24,DWORD) + local y=engine.peek(mapoffset+28,DWORD) + local z=engine.peek(mapoffset+32,DWORD) + --vec=engine.peek(mapoffset,ptr_vector) + + print("Blocks loaded:"..x.." "..y.." "..z) + print("Select type:") + print("1. All (SLOW)") + print("2. range (x0 x1 y0 y1 z0 z1)") + print("3. One block around pointer") + print("anything else- quit") + q=io.stdin:read() + n2=tonumber(q) + if n2==nil then return end + if n2>3 or n2<1 then return end + local xs,xe,ys,ye,zs,ze + if n2==1 then + xs=0 + xe=x-1 + ys=0 + ye=y-1 + zs=0 + ze=z-1 + elseif n2==2 then + print("enter x0:") + xs=tonumber(io.stdin:read()) + print("enter x1:") + xe=tonumber(io.stdin:read()) + print("enter y0:") + ys=tonumber(io.stdin:read()) + print("enter y1:") + ye=tonumber(io.stdin:read()) + print("enter z0:") + zs=tonumber(io.stdin:read()) + print("enter z1:") + ze=tonumber(io.stdin:read()) + function clamp(t,vmin,vmax) + if t> vmax then return vmax end + if t< vmin then return vmin end + return t + end + xs=clamp(xs,0,x-1) + ys=clamp(ys,0,y-1) + zs=clamp(zs,0,z-1) + xe=clamp(xe,xs,x-1) + ye=clamp(ye,ys,y-1) + ze=clamp(ze,zs,z-1) + else + xs,ys,zs=getxyz() + xs=math.floor(xs/16) + ys=math.floor(ys/16) + xe=xs + ye=ys + ze=zs + end + local xblocks=engine.peek(mapoffset,DWORD) + local flg=bit.bnot(bit.lshift(1,3)) + for xx=xs,xe do + local yblocks=engine.peek(xblocks+xx*4,DWORD) + for yy=ys,ye do + local zblocks=engine.peek(yblocks+yy*4,DWORD) + for zz=zs,ze do + local myblock=engine.peek(zblocks+zz*4,DWORD) + if myblock~=0 then + for i=0,255 do + local ff=engine.peek(myblock+0x67c+i*4,DWORD) + ff=bit.band(ff,flg) --set 14 flag to 1 + engine.poke(myblock+0x67c+i*4,DWORD,ff) + end + end + end + print("Blocks done:"..xx.." "..yy) + end + end +end \ No newline at end of file diff --git a/plugins/Dfusion/luafiles/tools/plugin.lua b/plugins/Dfusion/luafiles/tools/plugin.lua index 0a7bbc872..511b73205 100644 --- a/plugins/Dfusion/luafiles/tools/plugin.lua +++ b/plugins/Dfusion/luafiles/tools/plugin.lua @@ -1,501 +1,5 @@ --local bit = require("bit") -tools={} -tools.menu=MakeMenu() -function tools.setrace() - RaceTable=RaceTable or BuildNameTable() --slow.If loaded don't load again - print("Your current race is:"..GetRaceToken(engine.peekw(offsets.getEx('CurrentRace')))) - print("Type new race's token name in full caps:") - repeat - entry=io.stdin:read() - id=RaceTable[entry] - until id~=nil - engine.pokew(offsets.getEx('CurrentRace'),id) -end -tools.menu:add("Set current race",tools.setrace) -function tools.GiveSentience(names) --TODO make pattern... - RaceTable=RaceTable or BuildNameTable() --slow.If loaded don't load again - if names ==nil then - ids={} - print("Type race's token name in full caps to give sentience to:") - repeat - entry=io.stdin:read() - id=RaceTable[entry] - until id~=nil - table.insert(ids,id) - else - ids={} - for _,name in pairs(names) do - id=RaceTable[name] - table.insert(ids,id) - end - end - for _,id in pairs(ids) do - local off=offsets.getEx('CreatureGloss') - local races=engine.peek(off,ptr_vector) - --print("Vector start:"..off) - - off=races:getval(id) - print(string.format("race location:%x",off)) - local castes=engine.peek(off,ptr_CrGloss.castes) - print(string.format("Caste count:%i",castes:size())) - local flagPattern=ptt_dfflag.new(17) - for i =0,castes:size()-1 do - local offCaste=castes:getval(i) - print("Caste name:"..engine.peek(offCaste,ptr_CrCaste.name):getval().."...") - local flagoffset=engine.peek(offCaste,ptr_CrCaste.flags_ptr) - local flags=engine.peek(flagoffset,flagPattern) - --print(string.format("%x",flagoffset)) - if flags:get(57) then - print("\tis sentient.") - else - print("\tnon sentient. Allocating IQ...") - flags:set(57,1) - engine.poke(flagoffset,flagPattern,flags) - end - end - end -end -tools.menu:add("Give Sentience",tools.GiveSentience) -function tools.embark() - off=offsets.find(0,0x66, 0x83, 0x7F ,0x1A ,0xFF,0x74,0x04) - if off~=0 then - engine.pokeb(off+5,0x90) - engine.pokeb(off+6,0x90) - print("Found and patched") - else - print("not found") - end -end -tools.menu:add("Embark anywhere",tools.embark) -function tools.getlegendsid(croff) - local vec=engine.peek(croff,ptr_Creature.legends) - if vec:size()==0 then - return 0 - end - for i =0,vector:size()-1 do - --if engine.peekd(vec:getval(i))~=0 then - -- print(string.format("%x",engine.peekd(vec:getval(i))-offsets.base())) - --end - if(engine.peekd(vec:getval(i))==offsets.getEx("vtableLegends")) then --easy to get.. just copy from player's-base - return engine.peekd(vec:getval(i)+4) - end - end - return 0 -end -function tools.getCreatureId(vector) - tnames={} - rnames={} - --[[print("vector1 size:"..vector:size()) - print("vector2 size:"..vector2:size())]]-- - for i=0,vector:size()-1 do - --print(string.format("%x",vector:getval(i))) - - local name=engine.peek(vector:getval(i),ptt_dfstring):getval() - local lid= tools.getlegendsid(vector:getval(i)) - if lid ~=0 then - print(i..")*Creature Name:"..name.." race="..engine.peekw(vector:getval(i)+ptr_Creature.race.off).." legendid="..lid) - else - print(i..") Creature Name:"..name.." race="..engine.peekw(vector:getval(i)+ptr_Creature.race.off)) - end - if name ~="" and name~=nil then - tnames[i]=name - rnames[name]=i - end - end - print("=====================================") - print("type in name or number:") - r=io.stdin:read() - if tonumber(r) ==nil then - indx=rnames[r] - if indx==nil then return end - else - r=tonumber(r) - if rLOVE), q to quit:") - names={} - repeat - w=io.stdin:read(); - - if rwords[w]~=nil then - table.insert(names,w) - print("--added--") - end - - until w=='q' - end - - tnames={} - for _,v in pairs(names) do - if rwords[v] ~=nil then - table.insert(tnames,rwords[v]) --get word numbers - end - end - - local offsites=engine.peekd(offsets.getEx("SiteData"))+0x120 - snames={" pfort"," dfort"," cave","mohall","forest","hamlet","imploc"," lair"," fort"," camp"} - vector=engine.peek(offsites,ptr_vector) - print("Number of sites:"..vector:size()) - print("List of hits:") - for i =0,vector:size()-1 do - off=vector:getval(i) - - good=true - r="" - hits=0 - sname=engine.peek(off,ptr_site.name) - for k=0,6 do - vnum=sname[k]--engine.peekd(off+0x38+k*4) - tgood=false - - if vnum~=0xFFFFFFFF then - --print(string.format("%x",vnum)) - if names[vnum]~=nil then - r=r..names[vnum].." " - end - for _,v in pairs(tnames) do - if vnum==v then - tgood=true - --print("Match") - hits=hits+1 - break - end - end - if not tgood then - good=false - end - end - end - - if(good) and (hits>0)then - --if true then - --print("=====================") - typ=engine.peek(off,ptr_site.type)--engine.peekw(off+0x78) - flg=engine.peekd(engine.peek(off,ptr_site.flagptr)) - --flg=engine.peekd(off+224) - --flg2=engine.peekw(off) - --tv=engine.peek(off+0x84,ptr_vector) - --tv2=engine.peek(off+0xA4,ptr_vector) - - print(string.format("%d)%s off=%x type=%s\t flags=%x",i,r,off,snames[typ+1],flg)) - - if i%100==99 then - r=io.stdin:read() - end - - end - end - print("Type which to change (q cancels):") - repeat - r=io.stdin:read() - n=tonumber(r) - if(r=='q') then return end - until n~=nil - return vector:getval(n) -end -function tools.changesite(names) - off=tools.getsite(names) - snames={"Mountain halls (yours)","Dark fort","Cave","Mountain hall (NPC)","Forest retreat","Hamlet","Important location","Lair","Fort","Camp"} - - print("Type in the site type (q cancels):") - for k,v in pairs(snames) do - print((k-1).."->"..v) - end - repeat - r=io.stdin:read() - n2=tonumber(r) - if(r=='q') then return end - until n2~=nil - --off=vector:getval(n) - print(string.format("%x->%d",off,n2)) - engine.poke(off,ptr_site.type,n2) -end -function tools.changeflags(names) - myflag_pattern=ptt_dfflag.new(3*8) - off=tools.getsite(names) - offflgs=engine.peek(off,ptr_site.flagptr) - q='' - print(string.format("Site offset %x flags offset %x",off,offflgs)) - repeat - print("flags:") - - --off=vector:getval(n) - flg=engine.peek(offflgs,myflag_pattern) - r="" - for i=0,3*8-1 do - if flg:get(i)==1 then - r=r.."x" - else - r=r.."o" - end - if i%8==7 then - print(i-7 .."->"..r) - r="" - end - end - print("Type number to flip, or 'q' to quit.") - q=io.stdin:read() - n2=tonumber(q) - if n2~=nil then - - flg:flip(n2) - engine.poke(offflgs,myflag_pattern,flg) - end - until q=='q' -end -function tools.hostilate() - vector=engine.peek(offsets.getEx("CreatureVec"),ptr_vector) - id=engine.peekd(offsets.getEx("CreaturePtr")) - print(string.format("Vec:%d cr:%d",vector:size(),id)) - off=vector:getval(id) - crciv=engine.peek(off,ptr_Creature.civ) - print("Creatures civ:"..crciv) - curciv=engine.peekd(offsets.getEx("CurrentRace")-12) - print("My civ:"..curciv) - if curciv==crciv then - print("Friendly-making enemy") - engine.poke(off,ptr_Creature.civ,-1) - flg=engine.peek(off,ptr_Creature.flags) - flg:set(17,0) - print("flag 51:"..tostring(flg:get(51))) - engine.poke(off,ptr_Creature.flags,flg) - else - print("Enemy- making friendly") - engine.poke(off,ptr_Creature.civ,curciv) - flg=engine.peek(off,ptr_Creature.flags) - flg:set(17,1) - flg:set(19,0) - engine.poke(off,ptr_Creature.flags,flg) - end -end -function tools.mouseBlock() - local xs,ys,zs - xs,ys,zs=getxyz() - xs=math.floor(xs/16) - ys=math.floor(ys/16) - print("Mouse block is:"..xs.." "..ys.." "..zs) -end -function tools.protectsite() - local mapoffset=offsets.getEx("WorldData")--0x131C128+offsets.base() - local x=engine.peek(mapoffset+24,DWORD) - local y=engine.peek(mapoffset+28,DWORD) - local z=engine.peek(mapoffset+32,DWORD) - --vec=engine.peek(mapoffset,ptr_vector) - - print("Blocks loaded:"..x.." "..y.." "..z) - print("Select type:") - print("1. All (SLOW)") - print("2. range (x0 x1 y0 y1 z0 z1)") - print("3. One block around pointer") - print("anything else- quit") - q=io.stdin:read() - n2=tonumber(q) - if n2==nil then return end - if n2>3 or n2<1 then return end - local xs,xe,ys,ye,zs,ze - if n2==1 then - xs=0 - xe=x-1 - ys=0 - ye=y-1 - zs=0 - ze=z-1 - elseif n2==2 then - print("enter x0:") - xs=tonumber(io.stdin:read()) - print("enter x1:") - xe=tonumber(io.stdin:read()) - print("enter y0:") - ys=tonumber(io.stdin:read()) - print("enter y1:") - ye=tonumber(io.stdin:read()) - print("enter z0:") - zs=tonumber(io.stdin:read()) - print("enter z1:") - ze=tonumber(io.stdin:read()) - function clamp(t,vmin,vmax) - if t> vmax then return vmax end - if t< vmin then return vmin end - return t - end - xs=clamp(xs,0,x-1) - ys=clamp(ys,0,y-1) - zs=clamp(zs,0,z-1) - xe=clamp(xe,xs,x-1) - ye=clamp(ye,ys,y-1) - ze=clamp(ze,zs,z-1) - else - xs,ys,zs=getxyz() - xs=math.floor(xs/16) - ys=math.floor(ys/16) - xe=xs - ye=ys - ze=zs - end - local xblocks=engine.peek(mapoffset,DWORD) - local flg=bit.lshift(1,14) - for xx=xs,xe do - local yblocks=engine.peek(xblocks+xx*4,DWORD) - for yy=ys,ye do - local zblocks=engine.peek(yblocks+yy*4,DWORD) - for zz=zs,ze do - - - - local myblock=engine.peek(zblocks+zz*4,DWORD) - if myblock~=0 then - for i=0,255 do - local ff=engine.peek(myblock+0x67c+i*4,DWORD) - ff=bit.bor(ff,flg) --set 14 flag to 1 - engine.poke(myblock+0x67c+i*4,DWORD,ff) - end - end - end - print("Blocks done:"..xx.." "..yy) - end - end -end -function tools.fixwarp() - local mapoffset=offsets.getEx("WorldData")--0x131C128+offsets.base() - local x=engine.peek(mapoffset+24,DWORD) - local y=engine.peek(mapoffset+28,DWORD) - local z=engine.peek(mapoffset+32,DWORD) - --vec=engine.peek(mapoffset,ptr_vector) - - print("Blocks loaded:"..x.." "..y.." "..z) - print("Select type:") - print("1. All (SLOW)") - print("2. range (x0 x1 y0 y1 z0 z1)") - print("3. One block around pointer") - print("anything else- quit") - q=io.stdin:read() - n2=tonumber(q) - if n2==nil then return end - if n2>3 or n2<1 then return end - local xs,xe,ys,ye,zs,ze - if n2==1 then - xs=0 - xe=x-1 - ys=0 - ye=y-1 - zs=0 - ze=z-1 - elseif n2==2 then - print("enter x0:") - xs=tonumber(io.stdin:read()) - print("enter x1:") - xe=tonumber(io.stdin:read()) - print("enter y0:") - ys=tonumber(io.stdin:read()) - print("enter y1:") - ye=tonumber(io.stdin:read()) - print("enter z0:") - zs=tonumber(io.stdin:read()) - print("enter z1:") - ze=tonumber(io.stdin:read()) - function clamp(t,vmin,vmax) - if t> vmax then return vmax end - if t< vmin then return vmin end - return t - end - xs=clamp(xs,0,x-1) - ys=clamp(ys,0,y-1) - zs=clamp(zs,0,z-1) - xe=clamp(xe,xs,x-1) - ye=clamp(ye,ys,y-1) - ze=clamp(ze,zs,z-1) - else - xs,ys,zs=getxyz() - xs=math.floor(xs/16) - ys=math.floor(ys/16) - xe=xs - ye=ys - ze=zs - end - local xblocks=engine.peek(mapoffset,DWORD) - local flg=bit.bnot(bit.lshift(1,3)) - for xx=xs,xe do - local yblocks=engine.peek(xblocks+xx*4,DWORD) - for yy=ys,ye do - local zblocks=engine.peek(yblocks+yy*4,DWORD) - for zz=zs,ze do - local myblock=engine.peek(zblocks+zz*4,DWORD) - if myblock~=0 then - for i=0,255 do - local ff=engine.peek(myblock+0x67c+i*4,DWORD) - ff=bit.band(ff,flg) --set 14 flag to 1 - engine.poke(myblock+0x67c+i*4,DWORD,ff) - end - end - end - print("Blocks done:"..xx.." "..yy) - end - end -end if not(FILE) then tools.menu:add("Change site type",tools.changesite) tools.menu:add("Change site flags",tools.changeflags) diff --git a/plugins/Dfusion/luafiles/utils.lua b/plugins/Dfusion/luafiles/utils.lua new file mode 100644 index 000000000..0bc2a27e5 --- /dev/null +++ b/plugins/Dfusion/luafiles/utils.lua @@ -0,0 +1 @@ +function findVectorsSized(size) local ret={} local text=GetTextRegion() for k,v in pairs(offsets.getvectors()) do if GetRegionIn2(k)~=nil then --if v>4 then local tv=engine.peek(k,ptr_vector) if tv:size() == size then print(string.format("%x is size %d",k,size)) table.insert(ret,k) end end end return ret end function findMaterial(mattype,matname) --currently only stones local tbl=BuildMaterialTable() return tbl[matname] end \ No newline at end of file diff --git a/plugins/Dfusion/src/lua_FunctionCall.cpp b/plugins/Dfusion/src/lua_FunctionCall.cpp new file mode 100644 index 000000000..a537edbb5 --- /dev/null +++ b/plugins/Dfusion/src/lua_FunctionCall.cpp @@ -0,0 +1,39 @@ +#include "lua_FunctionCall.h" +using namespace lua; +int lua_FunctionCall(lua_State *L) +{ + lua::state st(L); + FunctionCaller cl(0); + size_t ptr=st.as(1); + int callconv=st.as(2); + vector arguments; + for(int i=3;i(i)); + int ret=cl.CallFunction(ptr,(FunctionCaller::callconv)callconv,arguments); + st.push(ret); + return 1;// dunno if len is needed... +} + +const luaL_Reg lua_functioncall_func[]= +{ + {"call",lua_FunctionCall}, + {NULL,NULL} +}; + +#define __ADDCONST(name) st.push(::FunctionCaller:: name); st.setglobal(#name) +void lua::RegisterFunctionCall(lua::state &st) +{ + st.getglobal("FunctionCall"); + if(st.is()) + { + st.pop(); + st.newtable(); + } + __ADDCONST(STD_CALL); + __ADDCONST(FAST_CALL); + __ADDCONST(THIS_CALL); + __ADDCONST(CDECL_CALL); + lua::RegFunctionsLocal(st, lua_functioncall_func); + st.setglobal("FunctionCall"); +} +#undef __ADDCONST \ No newline at end of file diff --git a/plugins/Dfusion/src/lua_VersionInfo.cpp b/plugins/Dfusion/src/lua_VersionInfo.cpp index 538de7360..d6f90be15 100644 --- a/plugins/Dfusion/src/lua_VersionInfo.cpp +++ b/plugins/Dfusion/src/lua_VersionInfo.cpp @@ -96,6 +96,29 @@ int OffsetGroup::getParent(lua_State *L) st.pcall(2,1); return 1; } +int OffsetGroup::getKeys(lua_State *L) +{ + const char* invalids[]={"notset","invalid","valid"}; + const char* keytypes[]={"offset","address","hexval","string","group"}; + lua::state st(L); + std::vector t= p->getKeys(); + st.newtable(); + for(size_t i=0;igetGroup(st.as(1)); - st.getglobal("OffsetGroup"); - st.getfield("new"); - st.getglobal("OffsetGroup"); - st.pushlightuserdata(t); - st.pcall(2,1); + if(st.as(1)=="") //if no argument, return version info as a groupoffset (dynamic cast) + { + st.getglobal("OffsetGroup"); + st.getfield("new"); + st.getglobal("OffsetGroup"); + st.pushlightuserdata(dynamic_cast(DFHack::Core::getInstance().vinfo)); + st.pcall(2,1); + } + else + { + DFHack::OffsetGroup* t= DFHack::Core::getInstance().vinfo->getGroup(st.as(1)); + st.getglobal("OffsetGroup"); + st.getfield("new"); + st.getglobal("OffsetGroup"); + st.pushlightuserdata(t); + st.pcall(2,1); + } return 1; } static int __lua_getParent(lua_State *S)