Removed dfusion lua files. Updated plugins.
parent
f1d4eac700
commit
33f674eee2
@ -1,3 +0,0 @@
|
||||
if not(FILE) then
|
||||
adv_tools.menu:display()
|
||||
end
|
@ -1,514 +0,0 @@
|
||||
dofile("dfusion/offsets_misc.lua")
|
||||
STD_STRING=0
|
||||
DWORD=1
|
||||
WORD=2
|
||||
BYTE=3
|
||||
QWORD=4
|
||||
DOUBLE=5
|
||||
FLOAT=6
|
||||
|
||||
getline=function (inp)
|
||||
return dfhack.lineedit(inp or "")
|
||||
end
|
||||
io.stdin=nil
|
||||
|
||||
function printd(...)
|
||||
if DEBUG then
|
||||
print(...)
|
||||
end
|
||||
end
|
||||
function GetTextRegion()
|
||||
if __TEXT ~=nil then --Chache this, not going to change.
|
||||
return __TEXT
|
||||
end
|
||||
|
||||
ranges__=Process.getMemRanges()
|
||||
--print("Ranges:"..#ranges__)
|
||||
for k,v in pairs(ranges__) do
|
||||
for k2,v2 in pairs(v) do
|
||||
--print(string.format("%d %s->%s",k,tostring(k2),tostring(v2)))
|
||||
end
|
||||
--local num
|
||||
--flgs=""
|
||||
--if(v["read"])then flgs=flgs..'r' end
|
||||
--if(v["write"])then flgs=flgs..'w' end
|
||||
--if(v["execute"]) then flgs=flgs..'e' end
|
||||
--if num>=100 then
|
||||
--print(string.format("%d %x->%x %s %s",k,v["start"],v["end"],v.name or "",flgs))
|
||||
--end
|
||||
local pos=string.find(v.name,"Dwarf Fortress.exe") or string.find(v.name,"libs/Dwarf_Fortress")
|
||||
if(pos~=nil) and v["execute"] then
|
||||
__TEXT=v;
|
||||
return v;
|
||||
end
|
||||
end
|
||||
error(".Text region not found!")
|
||||
end
|
||||
function UpdateRanges()
|
||||
ranges__=Process.getMemRanges()
|
||||
end
|
||||
function GetRegionIn(pos)
|
||||
ranges__=ranges__ or Process.getMemRanges()
|
||||
for k,v in pairs(ranges__) do
|
||||
if pos>=v.start and pos<v["end"] then
|
||||
return v
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
function GetRegionIn2(pos)
|
||||
ranges__=ranges__ or Process.getMemRanges()
|
||||
local cr=nil
|
||||
for k,v in pairs(ranges__) do
|
||||
--for k2,v2 in pairs(v) do
|
||||
-- print(string.format("%d %s->%s",k,tostring(k2),tostring(v2)))
|
||||
--end
|
||||
--local num
|
||||
--num=0
|
||||
--if(v["read"])then num=num+1 end
|
||||
--if(v["write"])then num=num+10 end
|
||||
--if(v["execute"]) then num=num+100 end
|
||||
--print(string.format("%d %x->%x %s %x",k,v["start"],v["end"],v.name,pos))
|
||||
if pos>=v.start then --This is a hack to counter .text region suddenly shrinking.
|
||||
if cr~=nil then
|
||||
if v.start < cr.start then -- find region that start is closest
|
||||
cr=v
|
||||
end
|
||||
else
|
||||
cr=v
|
||||
end
|
||||
end
|
||||
end
|
||||
return cr
|
||||
end
|
||||
function ValidOffset(pos)
|
||||
ranges__=ranges__ or Process.getMemRanges()
|
||||
return GetRegionIn(pos)~=nil
|
||||
end
|
||||
function unlockDF()
|
||||
local reg=GetTextRegion()
|
||||
reg["write"]=true
|
||||
Process.setPermisions(reg,reg)
|
||||
end
|
||||
function lockDF()
|
||||
local reg=GetTextRegion()
|
||||
reg["write"]=false
|
||||
Process.setPermisions(reg,reg)
|
||||
end
|
||||
function SetExecute(pos)
|
||||
UpdateRanges()
|
||||
local reg=GetRegionIn(pos)
|
||||
reg.execute=true
|
||||
reg["write"]=true
|
||||
Process.setPermisions(reg,reg) -- TODO maybe make a page with only execute permisions or sth
|
||||
end
|
||||
-- engine bindings
|
||||
engine=engine or {}
|
||||
--[=[ use default peek/pokes for now
|
||||
engine.peekd=Process.readDWord
|
||||
engine.poked=Process.writeDWord
|
||||
engine.peekb=Process.readByte
|
||||
engine.pokeb=Process.writeByte
|
||||
engine.peekw=Process.readWord
|
||||
engine.pokew=Process.writeWord
|
||||
engine.peekstr_stl=Process.readSTLString
|
||||
engine.pokestr_stl=Process.writeSTLString
|
||||
engine.peekstr=Process.readCString
|
||||
--engine.pokestr=Process.readCString
|
||||
engine.peekarb=Process.read
|
||||
engine.pokearb=Process.write
|
||||
--]=]
|
||||
|
||||
function engine.peek(offset,rtype)
|
||||
if type(rtype)=="table" then
|
||||
if rtype.off ==nil then
|
||||
return engine.peekpattern(offset,rtype)
|
||||
else
|
||||
return engine.peek(rtype.off+offset,rtype.rtype)
|
||||
end
|
||||
end
|
||||
if rtype==STD_STRING then
|
||||
return engine.peekstr2(offset)
|
||||
elseif rtype==DWORD then
|
||||
return engine.peekd(offset)
|
||||
elseif rtype==WORD then
|
||||
return engine.peekw(offset)
|
||||
elseif rtype==BYTE then
|
||||
return engine.peekb(offset)
|
||||
elseif rtype==QWORD then
|
||||
return engine.peekq(offset)
|
||||
elseif rtype==FLOAT then
|
||||
return engine.peekfloat(offset)
|
||||
elseif rtype==DOUBLE then
|
||||
return engine.peekdouble(offset)
|
||||
else
|
||||
error("Invalid peek type")
|
||||
return
|
||||
end
|
||||
end
|
||||
function engine.poke(offset,rtype,val)
|
||||
if type(rtype)=="table" then
|
||||
if rtype.off ==nil then
|
||||
return engine.pokepattern(offset,rtype,val)
|
||||
else
|
||||
return engine.poke(rtype.off+offset,rtype.rtype,val)
|
||||
end
|
||||
end
|
||||
if rtype==STD_STRING then
|
||||
return engine.pokestr2(offset,val)
|
||||
elseif rtype==DWORD then
|
||||
return engine.poked(offset,val)
|
||||
elseif rtype==WORD then
|
||||
return engine.pokew(offset,val)
|
||||
elseif rtype==BYTE then
|
||||
return engine.pokeb(offset,val)
|
||||
elseif rtype==QWORD then
|
||||
return engine.pokeq(offset,val)
|
||||
elseif rtype==FLOAT then
|
||||
return engine.pokefloat(offset,val)
|
||||
elseif rtype==DOUBLE then
|
||||
return engine.pokedouble(offset,val)
|
||||
else
|
||||
error("Invalid poke type:"..tostring(rtype))
|
||||
return
|
||||
end
|
||||
end
|
||||
function engine.sizeof(rtype)
|
||||
if rtype==STD_STRING then
|
||||
error("String has no constant size")
|
||||
return
|
||||
elseif rtype==DWORD then
|
||||
return 4;
|
||||
elseif rtype==WORD then
|
||||
return 2;
|
||||
elseif rtype==BYTE then
|
||||
return 1;
|
||||
else
|
||||
error("Invalid sizeof type")
|
||||
return
|
||||
end
|
||||
end
|
||||
function engine.peekpattern(offset,pattern)
|
||||
local ret={}
|
||||
for k,v in pairs(pattern) do
|
||||
--print("k:"..k.." v:"..type(v))
|
||||
if type(v)=="table" then
|
||||
ret[k]=engine.peek(offset+v.off,v.rtype)
|
||||
--print(k.." peeked:"..offset+v.off)
|
||||
else
|
||||
ret[k]=v
|
||||
end
|
||||
end
|
||||
ret.__offset=offset
|
||||
return ret
|
||||
end
|
||||
function engine.pokepattern(offset,pattern,val)
|
||||
for k,v in pairs(pattern) do
|
||||
--print("k:"..k.." v:"..type(v))
|
||||
if type(v)=="table" then
|
||||
engine.poke(offset+v.off,v.rtype,val[k])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function engine.LoadModData(file)
|
||||
local T2={}
|
||||
T2.symbols={}
|
||||
T2.data,T2.size=engine.loadobj(file)
|
||||
data,modsize=engine.loadobj(file)
|
||||
local T=engine.loadobjsymbols(file)
|
||||
for k,v in pairs(T) do
|
||||
|
||||
if v.pos~=0 then
|
||||
T2.symbols[v.name]=v.pos
|
||||
end
|
||||
end
|
||||
return T2
|
||||
end
|
||||
function engine.FindMarkerCall(moddata,name)
|
||||
if moddata.symbols[name] ~=nil then
|
||||
return moddata.symbols[name]+1
|
||||
end
|
||||
end
|
||||
function engine.FindMarker(moddata,name)
|
||||
if moddata.symbols[name] ~=nil then
|
||||
return engine.findmarker(0xDEADBEEF,moddata.data,moddata.size,moddata.symbols[name])
|
||||
end
|
||||
end
|
||||
function engine.installMod(file,name,bonussize)
|
||||
local T=engine.LoadModData(file)
|
||||
local modpos,modsize=engine.loadmod(file,name,bonussize)
|
||||
T.pos=modpos
|
||||
return T
|
||||
end
|
||||
|
||||
|
||||
|
||||
function PrintPattern(loadedpattern)
|
||||
for k,v in pairs(loadedpattern) do
|
||||
if type(v)== "string" then
|
||||
print(k.." "..v)
|
||||
else
|
||||
print(string.format("%s %d inhex:%x",k,v,v))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function printPattern(pattern)
|
||||
local i=0;
|
||||
local names={}
|
||||
names[STD_STRING]="std_string (STD_STRING)"
|
||||
names[DWORD]= "Double word (DWORD)"
|
||||
names[WORD]= "Word (WORD)"
|
||||
names[STD_STRING]="Byte (BYTE)"
|
||||
ret={}
|
||||
for k,v in pairs(pattern) do
|
||||
if type(v)=="table" and v.off~=nil then
|
||||
|
||||
if names[v.rtype]~=nil then
|
||||
lname=names[v.rtype]
|
||||
else
|
||||
if type(v.rtype)=="table" then
|
||||
lname="Table (prob subpattern)"
|
||||
else
|
||||
lname="Other"
|
||||
end
|
||||
end
|
||||
print(string.format("%d. %s is %s with offset %x",i,k,lname,v.off))
|
||||
table.insert(ret,k)
|
||||
else
|
||||
print(string.format("%d. %s",i,k))
|
||||
end
|
||||
i=i+1
|
||||
end
|
||||
return ret;
|
||||
end
|
||||
function editPattern(offset,pattern,name)
|
||||
if type(pattern[name].rtype)=="table" then
|
||||
if pattern[name].rtype.setval~=nil then
|
||||
print(string.format("%x",offset+pattern[name].off))
|
||||
local t=engine.peek(offset+pattern[name].off,pattern[name].rtype)
|
||||
print("Value is now:"..t:getval())
|
||||
print("Enter new value:")
|
||||
val=io.stdin:read()
|
||||
t:setval(val)
|
||||
else
|
||||
ModPattern(offset+pattern[name].off,pattern[name].rtype)
|
||||
end
|
||||
return
|
||||
end
|
||||
val=engine.peek(offset,pattern[name])
|
||||
print("Value is now:"..val)
|
||||
print("Enter new value:")
|
||||
if pattern[name].rtype==STD_STRING then
|
||||
val=io.stdin:read()
|
||||
else
|
||||
val=tonumber(io.stdin:read())
|
||||
end
|
||||
engine.poke(offset,pattern[name],val)
|
||||
end
|
||||
function ModPattern(itemoffset,pattern)
|
||||
print("Select what to edit:")
|
||||
nm=printPattern(pattern)
|
||||
q=tonumber(io.stdin:read())
|
||||
if q~=nil and q<#nm then
|
||||
editPattern(itemoffset,pattern,nm[q+1])
|
||||
end
|
||||
end
|
||||
|
||||
function findVectors()
|
||||
if __VECTORS ~=nil then --chache
|
||||
return __VECTORS
|
||||
end
|
||||
local text=GetTextRegion()
|
||||
local h=hexsearch(text.start,text["end"],0x8b,ANYBYTE,ANYDWORD,0x8b,ANYBYTE,ANYDWORD,0x2b)
|
||||
local pos=h:findall()
|
||||
local T={}
|
||||
for k,v in pairs(pos) do
|
||||
local loc1,loc2
|
||||
loc1=engine.peekd(v+2)
|
||||
loc2=engine.peekd(v+8)
|
||||
--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
|
||||
else
|
||||
T[loc1-4]=1
|
||||
end
|
||||
end
|
||||
end
|
||||
__VECTORS=T
|
||||
return T
|
||||
end
|
||||
|
||||
function GetRaceToken(p) --actually gets token...
|
||||
local vec=df.global.world.raws.creatures.all
|
||||
return vec[p].creature_id
|
||||
end
|
||||
function BuildNameTable()
|
||||
local rtbl={}
|
||||
local vec=df.global.world.raws.creatures.all
|
||||
--print(string.format("Vector start:%x",vec.st))
|
||||
--print(string.format("Vector end:%x",vec.en))
|
||||
--print("Creature count:"..vec.size)
|
||||
for k=0,#vec-1 do
|
||||
local name=vec[k].creature_id
|
||||
--print(k.." "..tostring(name))
|
||||
rtbl[name]=k
|
||||
end
|
||||
return rtbl;
|
||||
end
|
||||
function BuildMaterialTable()
|
||||
local rtbl={}
|
||||
local vec=engine.peek(offsets.getEx('Materials'),ptr_vector)
|
||||
--print(string.format("Vector start:%x",vec.st))
|
||||
--print(string.format("Vector end:%x",vec.en))
|
||||
--local i=0
|
||||
for p=0,vec:size()-1 do
|
||||
local off=vec:getval(p)
|
||||
--print("First member:"..off)
|
||||
local name=engine.peek(off,ptt_dfstring)
|
||||
--print("Loading:"..p.."="..name:getval())
|
||||
rtbl[name:getval()]=p
|
||||
--i=i+1
|
||||
--if i>100 then
|
||||
-- io.stdin:read()
|
||||
-- i=0
|
||||
--end
|
||||
end
|
||||
return rtbl;
|
||||
end
|
||||
function BuildWordTables()
|
||||
local names={}
|
||||
local rnames={}
|
||||
local vector=engine.peek(offsets.getEx('WordVec'),ptr_vector)
|
||||
for i =0,vector:size()-1 do
|
||||
local off=vector:getval(i)
|
||||
local n=engine.peekstr(off)
|
||||
names[i]=n
|
||||
rnames[n]=i
|
||||
end
|
||||
return names,rnames
|
||||
end
|
||||
function ParseScript(file)
|
||||
|
||||
io.input(file)
|
||||
f=""
|
||||
first=0
|
||||
nobraces=0
|
||||
function updFunction()
|
||||
if f~="" then
|
||||
first=0
|
||||
if nobraces==0 then
|
||||
f=f.."}"
|
||||
end
|
||||
nobraces=0
|
||||
print("Doing:"..f)
|
||||
assert(loadstring(f))()
|
||||
|
||||
f=""
|
||||
end
|
||||
end
|
||||
while true do
|
||||
|
||||
local line = io.read("*line")
|
||||
if line == nil then break end
|
||||
if string.sub(line,1,2)==">>" then
|
||||
updFunction()
|
||||
if string.find(line,"%b()") then
|
||||
f=string.sub(line,3)
|
||||
nobraces=1
|
||||
else
|
||||
f=string.sub(line,3).."{"
|
||||
end
|
||||
--print(string.sub(line,3)..)
|
||||
else
|
||||
if first~=0 then
|
||||
f=f..","
|
||||
else
|
||||
first=1
|
||||
end
|
||||
f=f..string.format('%q',line)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
updFunction()
|
||||
end
|
||||
function ParseNames(path)
|
||||
local ret={}
|
||||
local ff=io.open(path)
|
||||
for n in ff:lines() do
|
||||
table.insert(ret,n)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
function getSelectedUnit()
|
||||
if df.global.ui.main.mode~=23 then
|
||||
return nil
|
||||
end
|
||||
local unit_indx=df.global.ui_selected_unit
|
||||
if unit_indx<#df.global.world.units.active-1 then
|
||||
return df.global.world.units.active[unit_indx]
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
function getxyz() -- this will return pointers x,y and z coordinates.
|
||||
local x=df.global.cursor.x
|
||||
local y=df.global.cursor.y
|
||||
local z=df.global.cursor.z
|
||||
return x,y,z -- return the coords
|
||||
end
|
||||
function getCreatureAtPos(x,y,z) -- gets the creature index @ x,y,z coord
|
||||
--local x,y,z=getxyz() --get 'X' coords
|
||||
local vector=df.global.world.units.all -- load all creatures
|
||||
for i = 0, #vector-1 do -- look into all creatures offsets
|
||||
local curpos=vector[i].pos --get its coordinates
|
||||
local cx=curpos.x
|
||||
local cy=curpos.y
|
||||
local cz=curpos.z
|
||||
if cx==x and cy==y and cz==z then --compare them
|
||||
return vector[i] --return index
|
||||
end
|
||||
end
|
||||
--print("Creature not found!")
|
||||
return nil
|
||||
|
||||
end
|
||||
function getCreatureAtPointer()
|
||||
return getCreatureAtPos(getxyz())
|
||||
end
|
||||
function getCreature()
|
||||
local unit=getSelectedUnit()
|
||||
if unit==nil then
|
||||
unit=getCreatureAtPointer()
|
||||
end
|
||||
--any other selection methods...
|
||||
return unit
|
||||
end
|
||||
function getNemesisId(unit)
|
||||
for k,v in pairs(unit.refs) do
|
||||
if df.general_ref_is_nemesisst:is_instance(v) then
|
||||
return v.nemesis_id
|
||||
end
|
||||
end
|
||||
end
|
||||
function getNemesis(unit)
|
||||
local id=getNemesisId(unit)
|
||||
if id then
|
||||
return df.nemesis_record.find(id)
|
||||
end
|
||||
end
|
||||
function Allocate(size)
|
||||
local ptr=engine.getmod('General_Space')
|
||||
if ptr==nil then
|
||||
ptr=engine.newmod("General_Space",4096) -- some time later maybe make some more space
|
||||
engine.poked(ptr,4)
|
||||
end
|
||||
|
||||
local curptr=engine.peekd(ptr)
|
||||
curptr=curptr+size
|
||||
engine.poked(ptr,curptr)
|
||||
return curptr-size+ptr
|
||||
end
|
@ -1 +0,0 @@
|
||||
as -a --32 -o embark.o embark.asm
|
@ -1,7 +0,0 @@
|
||||
.intel_syntax
|
||||
mov eax , [esp+0x1C] # loop counter
|
||||
mark_caste:
|
||||
movsx ecx, word ptr[eax*2+0xdeadbeef]
|
||||
mark_race:
|
||||
movzx eax,word ptr [eax*2+0xDEADBEEF]
|
||||
ret
|
Binary file not shown.
@ -1,95 +0,0 @@
|
||||
local dfu=require("plugins.dfusion")
|
||||
local ms=require("memscan")
|
||||
local MAX_RACES=100
|
||||
CustomEmbark=defclass(CustomEmbark,dfu.BinaryPlugin)
|
||||
local myos=dfhack.getOSType()
|
||||
if myos=="windows" then
|
||||
|
||||
CustomEmbark.ATTRS{filename="dfusion/embark/embark.o",name="CustomEmbark",race_caste_data=DEFAULT_NIL}
|
||||
CustomEmbark.class_status="valid, not installed"
|
||||
function CustomEmbark:install()
|
||||
local stoff=dfhack.internal.getAddress('start_dwarf_count')
|
||||
|
||||
if #self.race_caste_data<7 then
|
||||
error("caste and race count must be bigger than 6")
|
||||
end
|
||||
if #self.race_caste_data>MAX_RACES then
|
||||
error("caste and race count must be less then "..MAX_RACES)
|
||||
end
|
||||
if stoff==nil then
|
||||
error("address for start_dwarf_count not found!")
|
||||
end
|
||||
local _,race_id_offset=df.sizeof(df.global.ui:_field("race_id"))
|
||||
print(string.format("start=%08x",stoff))
|
||||
local needle={0x0f,0xb7,0x0d} --movzx eax,dword ptr [race_id]
|
||||
local tmp_table=dfu.dwordToTable(race_id_offset)
|
||||
for k,v in ipairs(tmp_table) do
|
||||
table.insert(needle,v)
|
||||
end
|
||||
|
||||
local mem=ms.get_code_segment()
|
||||
print(mem.uint8_t:addr2idx(stoff))
|
||||
print(mem.uint8_t:find(needle,mem.uint8_t:addr2idx(stoff)))
|
||||
local _,trg_offset=mem.uint8_t:find(needle,mem.uint8_t:addr2idx(stoff),nil)--maybe endoff=stoff+bignumber
|
||||
if trg_offset==nil then
|
||||
error("address for race_load not found")
|
||||
end
|
||||
local call_data={0x90,0x90}
|
||||
local _,data_offset=df.sizeof(self.data)
|
||||
dfu.concatTables(call_data,dfu.makeCall(trg_offset+2,data_offset))
|
||||
self.call_patch=dfu.BinaryPatch{pre_data=needle,data=call_data,address=trg_offset,name="custom_embark_call_patch"}
|
||||
needle={0x83,0xc8,0xff} -- or eax, 0xFF
|
||||
local _,caste_offset=mem.uint8_t:find(needle,mem.uint8_t:addr2idx(trg_offset),nil)
|
||||
if caste_offset==nil or caste_offset-stoff>1000 then
|
||||
error("Caste change code not found or found too far!")
|
||||
end
|
||||
|
||||
self.disable_castes=dfu.BinaryPatch{pre_data={0x83,0xc8,0xff},data={0x90,0x90,0x90},address=caste_offset,name="custom_embark_caste_disable"}
|
||||
self.disable_castes:apply()
|
||||
self.dwarfcount=dfu.BinaryPatch{pre_data=dfu.dwordToTable(7),data=dfu.dwordToTable(#self.race_caste_data),address=stoff,name="custom_embark_embarkcount"}
|
||||
self.dwarfcount:apply()
|
||||
local caste_array=self:allocate("caste_array","uint16_t",#self.race_caste_data)
|
||||
local race_array=self:allocate("race_array","uint16_t",#self.race_caste_data)
|
||||
self:setEmbarkParty(self.race_caste_data)
|
||||
for k,v in ipairs(self.race_caste_data) do
|
||||
caste_array[k-1]=v[2]
|
||||
race_array[k-1]=v[1]
|
||||
end
|
||||
local race_array_off,caste_array_off
|
||||
local _
|
||||
_,race_array_off=df.sizeof(race_array)
|
||||
_,caste_array_off=df.sizeof(caste_array)
|
||||
self:set_marker_dword("race",caste_array_off) --hehe... mixed them up i guess...
|
||||
self:set_marker_dword("caste",race_array_off)
|
||||
|
||||
self:move_to_df()
|
||||
self.call_patch:apply()
|
||||
self.installed=true
|
||||
end
|
||||
function CustomEmbark:setEmbarkParty(racesAndCastes)
|
||||
self.race_caste_data=racesAndCastes
|
||||
if self.dwarfcount== nil then
|
||||
self.dwarfcount=dfu.BinaryPatch{pre_data=dfu.dwordToTable(7),data=dfu.dwordToTable(#self.race_caste_data),address=stoff,name="custom_embark_embarkcount"}
|
||||
self.dwarfcount:apply()
|
||||
else
|
||||
self.dwarfcount:repatch(dfu.dwordToTable(#self.race_caste_data))
|
||||
end
|
||||
|
||||
end
|
||||
function CustomEmbark:status()
|
||||
if self.installed then
|
||||
return "valid, installed"
|
||||
else
|
||||
return "valid, not installed"
|
||||
end
|
||||
end
|
||||
function CustomEmbark:uninstall()
|
||||
if self.installed then
|
||||
self.call_patch:remove()
|
||||
self.disable_castes:remove()
|
||||
self.dwarfcount:remove()
|
||||
end
|
||||
end
|
||||
else
|
||||
CustomEmbark.class_status="invalid, os not supported"
|
||||
end
|
@ -1,5 +0,0 @@
|
||||
|
||||
if not(FILE)then
|
||||
names=ParseNames("dfusion/embark/races.txt")--io.open("plugins/embark/races.txt"):lines()
|
||||
embark(names)
|
||||
end
|
@ -1,9 +0,0 @@
|
||||
ANT_MAN:0
|
||||
ANT_MAN:0
|
||||
ANT_MAN:0
|
||||
ANT_MAN:1
|
||||
ANT_MAN:1
|
||||
ANT_MAN:0
|
||||
ANT_MAN:0
|
||||
ANT_MAN:2
|
||||
ANT_MAN:3
|
@ -1 +0,0 @@
|
||||
as -anl --32 -o friendship.o friendship.asm
|
@ -1,106 +0,0 @@
|
||||
.intel_syntax
|
||||
push eax
|
||||
mov eax,[esp+0x04]
|
||||
push ebx
|
||||
pushfd
|
||||
mov eax,[eax] # get a byte after the call this procedure to analyze what register holds cr ptr
|
||||
jmptbl:
|
||||
cmp al,0x81
|
||||
jz regC
|
||||
cmp al,0x82
|
||||
jz regD
|
||||
cmp al,0x83
|
||||
jz regB
|
||||
cmp al,0x85
|
||||
jz regBP
|
||||
cmp al,0x86
|
||||
jz regESI
|
||||
cmp al,0x87
|
||||
jz regEDI
|
||||
cmp al,0x88
|
||||
jz regA
|
||||
cmp al,0x8A
|
||||
jz regD
|
||||
cmp al,0x8B
|
||||
jz regB
|
||||
cmp al,0x8D
|
||||
jz regBP
|
||||
cmp al,0x8E
|
||||
jz regESI
|
||||
cmp al,0x8F
|
||||
jz regEDI
|
||||
cmp al,0x90
|
||||
jz regA
|
||||
cmp al,0x91
|
||||
jz regC
|
||||
cmp al,0x93
|
||||
jz regB
|
||||
cmp al,0x95
|
||||
jz regBP
|
||||
cmp al,0x96
|
||||
jz regESI
|
||||
cmp al,0x97
|
||||
jz regEDI
|
||||
jmp fail
|
||||
regA:
|
||||
mov eax, [esp+0x8]
|
||||
mov eax, [eax+0x8c]
|
||||
jmp compare
|
||||
regC:
|
||||
mov eax, [ecx+0x8c]
|
||||
jmp compare
|
||||
regB:
|
||||
mov eax, [ebx+0x8c]
|
||||
jmp compare
|
||||
regD:
|
||||
mov eax, [edx+0x8c]
|
||||
jmp compare
|
||||
regBP:
|
||||
mov eax, [ebp+0x8c]
|
||||
jmp compare
|
||||
regESI:
|
||||
mov eax, [esi+0x8c]
|
||||
jmp compare
|
||||
regEDI:
|
||||
mov eax, [edi+0x8c]
|
||||
#jmp compare
|
||||
compare:
|
||||
push ecx
|
||||
mark_racepointer:
|
||||
mov ebx,0xDEADBEEF #write a pointer to the list of allowed races
|
||||
mark_racecount:
|
||||
mov ecx,0xDEADBEEF #write a number of allowed races
|
||||
loop1:
|
||||
cmp word[ebx+ecx*2],ax
|
||||
jz endok
|
||||
dec ecx
|
||||
cmp ecx ,-1
|
||||
jnz loop1
|
||||
pop ecx
|
||||
popfd
|
||||
jmp fail
|
||||
endok:
|
||||
pop ecx
|
||||
popfd
|
||||
cmp eax,eax
|
||||
jmp endfinal
|
||||
fail:
|
||||
|
||||
xor ebx,ebx
|
||||
xor eax,eax
|
||||
inc eax
|
||||
cmp eax,ebx
|
||||
endfinal:
|
||||
|
||||
pop ebx
|
||||
pop eax
|
||||
mark_safeloc1:
|
||||
mov [0xDEADBEEF],eax #write a pointer to safe location (usually after this)
|
||||
pop eax
|
||||
pushfd
|
||||
inc eax #skip one instruction
|
||||
popfd
|
||||
push eax
|
||||
mark_safeloc2:
|
||||
mov eax,[0xDEADBEEF] #write a pointer to safe location (same as above)
|
||||
ret
|
Binary file not shown.
@ -1,45 +0,0 @@
|
||||
function analyzeF(off)
|
||||
pos=offsets.find(off,0x39,ANYBYTE,0x8c,00,00,00)
|
||||
print(string.format("Compare at:%x",pos))
|
||||
if pos ==0 then
|
||||
return 0
|
||||
end
|
||||
if(pos-off>0x100) then
|
||||
print(string.format("Distance to cmp:%x",pos-off))
|
||||
pos =offsets.find(off,CALL)
|
||||
print(string.format("Distance to call:%x",pos-off))
|
||||
return 0
|
||||
--return analyzeF(pos)
|
||||
else
|
||||
return pos
|
||||
end
|
||||
end
|
||||
function minEx(list)
|
||||
local imin=list[1]
|
||||
for _,v in ipairs(list) do
|
||||
if imin> v and v~=0 then
|
||||
imin=v
|
||||
end
|
||||
end
|
||||
return imin
|
||||
end
|
||||
function signDword(dw)
|
||||
if(dw>0xFFFFFFFF) then
|
||||
return dw-0xFFFFFFFF
|
||||
end
|
||||
return dw
|
||||
end
|
||||
--[[
|
||||
Warning: not all mov's are acounted for. Found one: mov EAX,WORD PTR[EBP+1EF4] WTF??
|
||||
Two more compares are missing. There are calls instead (same function)
|
||||
]]--
|
||||
|
||||
friendship_in={}
|
||||
dofile("dfusion/friendship/install.lua")
|
||||
dofile("dfusion/friendship/patch.lua")
|
||||
|
||||
function friendship(names)
|
||||
friendship_in.install(names)
|
||||
friendship_in.patch()
|
||||
end
|
||||
|
@ -1,35 +0,0 @@
|
||||
|
||||
function friendship_in.install(names)
|
||||
RaceTable=RaceTable or BuildNameTable()
|
||||
mypos=engine.getmod("Friendship")
|
||||
if mypos then
|
||||
modpos=mypos
|
||||
_,modsize=engine.loadobj("dfusion/friendship/friendship.o")
|
||||
_=nil
|
||||
else
|
||||
modpos,modsize=engine.loadmod("dfusion/friendship/friendship.o","Friendship",1024)
|
||||
print(string.format("Loaded module @:%x",modpos))
|
||||
end
|
||||
count=0
|
||||
for _,v in pairs(names) do
|
||||
if RaceTable[v] == nil then
|
||||
--print("Failure, "..v.." not found!")
|
||||
error("Failure, "..v.." not found!")
|
||||
--break --maybe some indication of failure? and cleanup?
|
||||
end
|
||||
engine.pokew(modpos+modsize+count*2+4+2,RaceTable[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(modpos+0x8f,modpos+modsize+4) -- set ptr to creatures
|
||||
engine.poked(modpos+0x94,count) -- set count of creatures
|
||||
engine.poked(modpos+0xb9,modpos+modsize) -- set safe location
|
||||
engine.poked(modpos+0xc3,modpos+modsize) -- set safe location
|
||||
SetExecute(modpos)
|
||||
end
|
||||
function pokeCall(off)
|
||||
engine.pokeb(off,0xe8)
|
||||
b=engine.peekb(off+1)
|
||||
engine.poked(off+1,modpos-off-5)
|
||||
engine.pokeb(off+5,b)
|
||||
end
|
@ -1,57 +0,0 @@
|
||||
function friendship_in.patch()
|
||||
UpdateRanges()
|
||||
pos=GetTextRegion().start
|
||||
local _,crace=df.sizeof(df.global.ui:_field("race_id"))
|
||||
hits={}
|
||||
i=1
|
||||
repeat
|
||||
--todo make something better/smarter...
|
||||
pos1=offsets.find(pos+7,0x0f,0xBF,ANYBYTE,DWORD_,crace) -- movsx
|
||||
pos2=offsets.find(pos+7,0x66,0xa1,DWORD_,crace) -- mov ax,[ptr]
|
||||
pos3=offsets.find(pos+7,0xa1,DWORD_,crace) -- mov eax,[ptr]
|
||||
pos4=offsets.find(pos+7,0x66,0x8b,ANYBYTE,DWORD_,crace) -- mov ANYREG,[ptr]
|
||||
--pos5=offsets.find(pos+7,0x66,0x8b,0x15,DWORD_,crace) -- mov dx,[ptr]
|
||||
pos=minEx{pos1,pos2,pos3,pos4}
|
||||
if pos ~=0 then
|
||||
hits[i]=pos
|
||||
i=i+1
|
||||
print(string.format("Found at %x",pos))
|
||||
end
|
||||
until pos==0
|
||||
print("=======================================")
|
||||
for _,p in pairs(hits) do
|
||||
myp=p
|
||||
repeat
|
||||
|
||||
--print(string.format("Analyzing %x...",p))
|
||||
--TODO read offset from memory.xml
|
||||
pos1=offsets.find(myp,0x39,ANYBYTE,0x8c,00,00,00) -- compare [reg+08c] (creature race) with any reg
|
||||
pos2=offsets.find(myp,0x3b,ANYBYTE,0x8c,00,00,00) -- compare any reg with [reg+08c] (creature race)
|
||||
pos=minEx{pos1,pos2}
|
||||
if pos ~=0 then
|
||||
|
||||
if(pos-p>250) then
|
||||
--this here does not work yet...
|
||||
--[[pos =offsets.find(p,CALL)
|
||||
print(string.format("Distance to call:%x",pos-p))
|
||||
print(string.format("Call: %x",signDword(engine.peekd(pos+1)+pos)))
|
||||
pos=analyzeF(signDword(signDword(engine.peekd(pos+1)+pos)))
|
||||
|
||||
print(string.format("Cmp @:%x",pos))]]--
|
||||
print(string.format("skipping %x... Cmp too far away (dist=%i)",p,pos-p))
|
||||
else
|
||||
--print(string.format("Found at %x, simple compare",pos))
|
||||
--print(string.format("Distance =%x",pos-p))
|
||||
--patch compares
|
||||
|
||||
pokeCall(pos)
|
||||
end
|
||||
else
|
||||
break
|
||||
end
|
||||
myp=myp+pos+6
|
||||
if myp-p >250 then break end
|
||||
until false
|
||||
|
||||
end
|
||||
end
|
@ -1,18 +0,0 @@
|
||||
if not(FILE) then
|
||||
--sanity test
|
||||
--print("race num:"..engine.peekw(offsets.getEx("CurrentRace")))
|
||||
--print(string.format("%x vs %x",offsets.getEx("CurrentRace"),VersionInfo.getGroup("Creatures"):getAddress("current_race")))
|
||||
print("Race num:"..df.global.ui.race_id)
|
||||
print("Your current race is:"..GetRaceToken(df.global.ui.race_id))
|
||||
print("If this is wrong please type 'q'")
|
||||
if(getline()=='q') then
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if not(FILE) then
|
||||
names=ParseNames("dfusion/friendship/races.txt")--io.open("plugins/friendship/races.txt"):lines()
|
||||
friendship_in.install(names)
|
||||
friendship_in.patch()
|
||||
end
|
@ -1,8 +0,0 @@
|
||||
DWARF
|
||||
GOBLIN
|
||||
ELF
|
||||
HUMAN
|
||||
KOBOLD
|
||||
GREMLIN
|
||||
TIGERMAN
|
||||
ANT_MAN
|
@ -1 +0,0 @@
|
||||
as -anl --32 -o friendship_c.o friendship_c.asm
|
@ -1,41 +0,0 @@
|
||||
.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
|
Binary file not shown.
@ -1,89 +0,0 @@
|
||||
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
|
@ -1,57 +0,0 @@
|
||||
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()
|
@ -1,92 +0,0 @@
|
||||
function dofile(filename) --safer dofile, with traceback (very usefull)
|
||||
f,perr=loadfile(filename)
|
||||
if f~=nil then
|
||||
return safecall(f)
|
||||
else
|
||||
print(perr)
|
||||
end
|
||||
end
|
||||
function dofile_silent(filename) --safer dofile, with traceback, no file not found error
|
||||
f,perr=loadfile(filename)
|
||||
if f~=nil then
|
||||
return safecall(f)
|
||||
else
|
||||
if(string.sub(perr,1,11)~="cannot open") then --ugly hack
|
||||
print(perr)
|
||||
end
|
||||
end
|
||||
end
|
||||
function loadall(t1) --loads all non interactive plugin parts, so that later they could be used
|
||||
for k,v in pairs(t1) do
|
||||
dofile_silent("dfusion/"..v[1].."/init.lua")
|
||||
end
|
||||
end
|
||||
function mainmenu(t1)
|
||||
while true do
|
||||
print("No. Name Desc")
|
||||
for k,v in pairs(t1) do
|
||||
print(string.format("%3d %15s %s",k,v[1],v[2]))
|
||||
end
|
||||
local q=dfhack.lineedit("Select plugin to run (q to quit):")
|
||||
if q=='q' then return end
|
||||
q=tonumber(q)
|
||||
if q~=nil then
|
||||
if q>=1 and q<=#t1 then
|
||||
if t1[q][3]==nil then
|
||||
dofile("dfusion/"..t1[q][1].."/plugin.lua")
|
||||
else
|
||||
t1[q][3]()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function RunSaved()
|
||||
print("Locating saves...")
|
||||
local str=df.global.world.cur_savegame.save_dir
|
||||
print("Current region:"..str)
|
||||
str="data/save/"..str.."/dfusion/init.lua"
|
||||
print("Trying to run:"..str)
|
||||
dofile_silent(str)
|
||||
end
|
||||
dofile("dfusion/common.lua")
|
||||
dofile("dfusion/utils.lua")
|
||||
dofile("dfusion/offsets_misc.lua")
|
||||
dofile("dfusion/editor.lua")
|
||||
|
||||
unlockDF()
|
||||
plugins={}
|
||||
table.insert(plugins,{"simple_embark","A simple embark dwarf count editor"})
|
||||
table.insert(plugins,{"tools","some misc tools"})
|
||||
table.insert(plugins,{"embark","Multi race embark"})
|
||||
table.insert(plugins,{"friendship","Multi race fort enabler"})
|
||||
--[=[table.insert(plugins,{"items","A collection of item hacking tools"})
|
||||
table.insert(plugins,{"offsets","Find all offsets"})
|
||||
|
||||
table.insert(plugins,{"friendship_civ","Multi civ fort enabler"})
|
||||
|
||||
|
||||
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"})
|
||||
--table.insert(plugins,{"editor","edit internals of df",EditDF})
|
||||
table.insert(plugins,{"saves","run current worlds's init.lua",RunSaved})
|
||||
table.insert(plugins,{"adv_tools","some tools for (mainly) adventurer hacking"})
|
||||
loadall(plugins)
|
||||
dofile_silent("dfusion/initcustom.lua")
|
||||
|
||||
local args={...}
|
||||
|
||||
|
||||
local f,err=load(table.concat(args,' '))
|
||||
if f then
|
||||
f()
|
||||
else
|
||||
dfhack.printerr(err)
|
||||
end
|
||||
|
||||
if not INIT then
|
||||
mainmenu(plugins)
|
||||
end
|
||||
|
@ -1 +0,0 @@
|
||||
as -anl --32 -o migrants.o migrants.asm
|
@ -1,62 +0,0 @@
|
||||
--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",400)
|
||||
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
|
||||
_,raceoff=df.sizeof(df.global.ui:_field('race_id'))
|
||||
pos=offsets.find(offsets.base(),0xa1,DWORD_,raceoff,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
|
@ -1,20 +0,0 @@
|
||||
.intel_syntax
|
||||
pushfd
|
||||
push ebx
|
||||
push edx
|
||||
mov eax,[0xdeadbeef] # get old seed
|
||||
mov ebx,1103515245
|
||||
#mul 1103515245
|
||||
mul ebx
|
||||
add eax,12345
|
||||
mov [0xdeadbeef],eax #put seed back...thus generation rnd is complete
|
||||
|
||||
xor edx,edx
|
||||
mov ebx,2000 #put size of array here
|
||||
div ebx #why oh why there is no div const? compiler prob makes some xor/add magic
|
||||
movzx eax,word ptr[0xdeadbeef+edx*2]
|
||||
pop edx
|
||||
pop ebx
|
||||
|
||||
popfd
|
||||
ret
|
Binary file not shown.
@ -1,5 +0,0 @@
|
||||
|
||||
if not(FILE) then
|
||||
names=ParseNames("dfusion/migrants/races.txt")--io.open("plugins/migrants/races.txt"):lines()
|
||||
migrants(names)
|
||||
end
|
@ -1,29 +0,0 @@
|
||||
DWARF
|
||||
DWARF
|
||||
DWARF
|
||||
DWARF
|
||||
DWARF
|
||||
DWARF
|
||||
DWARF
|
||||
DWARF
|
||||
DWARF
|
||||
ELF
|
||||
HUMAN
|
||||
DWARF
|
||||
GREMLIN
|
||||
KOBOLD
|
||||
DWARF
|
||||
DWARF
|
||||
DWARF
|
||||
DWARF
|
||||
DWARF
|
||||
DWARF
|
||||
DWARF
|
||||
DWARF
|
||||
DWARF
|
||||
ELF
|
||||
HUMAN
|
||||
DWARF
|
||||
GREMLIN
|
||||
KOBOLD
|
||||
DEMON_13
|
@ -1,2 +0,0 @@
|
||||
offsets.searchoffsets()
|
||||
offsets.save()
|
@ -1,48 +0,0 @@
|
||||
offsets=offsets or {}
|
||||
function offsets.find(startoffset,...)
|
||||
-- [=[
|
||||
if startoffset== 0 then
|
||||
local text=GetTextRegion()
|
||||
--print("searching in:"..text.name)
|
||||
startoffset=text.start
|
||||
endadr=text["end"]
|
||||
else
|
||||
local reg=GetRegionIn(startoffset)
|
||||
--print("searching in:"..reg.name)
|
||||
if reg==nil then
|
||||
print(string.format("Warning: memory range for search @:%x not found!",startoffset))
|
||||
return 0
|
||||
end
|
||||
endadr=reg["end"]
|
||||
end
|
||||
--]=]
|
||||
--print(string.format("Searching (%x->%x)",startoffset,endadr))
|
||||
local h=hexsearch(startoffset,endadr,...)
|
||||
local pos=h:find()
|
||||
h=nil
|
||||
return pos
|
||||
end
|
||||
function offsets.findall(startoffset,...)
|
||||
local endadr;
|
||||
if startoffset== 0 then
|
||||
local text=GetTextRegion()
|
||||
--print("searching in:"..text.name)
|
||||
startoffset=text.start
|
||||
endadr=text["end"]
|
||||
else
|
||||
local reg=GetRegionIn(startoffset)
|
||||
--print("searching in:"..reg.name)
|
||||
endadr=reg["end"]
|
||||
end
|
||||
local h=hexsearch(startoffset,endadr,...)
|
||||
local pos=h:findall()
|
||||
h=nil
|
||||
return pos
|
||||
end
|
||||
function offsets.base()
|
||||
return Process.getBase()
|
||||
end
|
||||
function offsets.getvectors()
|
||||
return findVectors()
|
||||
end
|
||||
ADDRESS=ANYDWORD
|
@ -1,23 +0,0 @@
|
||||
function simple_embark(num)
|
||||
local stoff=dfhack.internal.getAddress('start_dwarf_count')
|
||||
print("Starting dwarves found:"..df.reinterpret_cast('int32_t', stoff).value)
|
||||
local tmp_val=df.new('int32_t')
|
||||
local size,pos=tmp_val:sizeof()
|
||||
tmp_val.value=num
|
||||
local ret=dfhack.internal.patchMemory(stoff,tmp_val,size)
|
||||
if ret then
|
||||
print("Success!")
|
||||
else
|
||||
qerror("Failed to patch in number")
|
||||
end
|
||||
end
|
||||
if not(FILE) then
|
||||
print("Type in new amount (more than 6, less than 15000):")
|
||||
repeat
|
||||
ans=tonumber(io.read())
|
||||
if ans==nil or not(ans<=15000 and ans>0) then
|
||||
print("incorrect choice")
|
||||
end
|
||||
until ans~=nil and (ans<=15000 and ans>0)
|
||||
simple_embark(ans)
|
||||
end
|
@ -1,511 +0,0 @@
|
||||
local ms=require "memscan"
|
||||
tools={}
|
||||
tools.menu=MakeMenu()
|
||||
function tools.setrace(name)
|
||||
RaceTable=BuildNameTable()
|
||||
print("Your current race is:"..GetRaceToken(df.global.ui.race_id))
|
||||
local id
|
||||
if name == nil then
|
||||
print("Type new race's token name in full caps (q to quit):")
|
||||
repeat
|
||||
entry=getline()
|
||||
if entry=="q" then
|
||||
return
|
||||
end
|
||||
id=RaceTable[entry]
|
||||
until id~=nil
|
||||
else
|
||||
id=RaceTable[name]
|
||||
if id==nil then
|
||||
error("Name not found!")
|
||||
end
|
||||
end
|
||||
df.global.ui.race_id=id
|
||||
end
|
||||
tools.menu:add("Set current race",tools.setrace)
|
||||
function tools.GiveSentience(names)
|
||||
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=getline()
|
||||
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 races=df.global.world.raws.creatures.all
|
||||
|
||||
local castes=races[id].caste
|
||||
print(string.format("Caste count:%i",castes.size))
|
||||
for i =0,#castes-1 do
|
||||
|
||||
print("Caste name:"..castes[i].caste_id.."...")
|
||||
|
||||
local flags=castes[i].flags
|
||||
--print(string.format("%x",flagoffset))
|
||||
if flags.CAN_SPEAK then
|
||||
print("\tis sentient.")
|
||||
else
|
||||
print("\tnon sentient. Allocating IQ...")
|
||||
flags.CAN_SPEAK=true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
tools.menu:add("Give Sentience",tools.GiveSentience)
|
||||
function tools.embark() --windows only?
|
||||
local seg=ms.get_code_segment()
|
||||
local idx,off
|
||||
|
||||
idx,off=seg.uint8_t:find_one{0x66, 0x83, 0x7F ,0x1A ,0xFF,0x74,0x04}
|
||||
if idx then
|
||||
local tmp_val=df.new('uint8_t',2)
|
||||
tmp_val[0]=0x90
|
||||
tmp_val[1]=0x90
|
||||
local size,pos=tmp_val:sizeof()
|
||||
local ret=dfhack.internal.patchMemory(off+5,pos,size*2)
|
||||
if ret then
|
||||
print("Found and patched:",off+5)
|
||||
else
|
||||
print("Patching failed at:",off+5)
|
||||
end
|
||||
tmp_val:delete()
|
||||
else
|
||||
qerror("Offset for embark patch not found!")
|
||||
end
|
||||
end
|
||||
if WINDOWS then
|
||||
tools.menu:add("Embark anywhere",tools.embark)
|
||||
end
|
||||
function tools.getCreatureId(vector) --redo it to getcreature by name/id or something
|
||||
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=getline()
|
||||
if tonumber(r) ==nil then
|
||||
indx=rnames[r]
|
||||
if indx==nil then return end
|
||||
else
|
||||
r=tonumber(r)
|
||||
if r<vector:size() then indx=r else return end
|
||||
end
|
||||
return indx
|
||||
end
|
||||
function tools.change_adv(unit,nemesis)
|
||||
if nemesis==nil then
|
||||
nemesis=true --default value is nemesis switch too.
|
||||
end
|
||||
if unit==nil then
|
||||
unit=getCreatureAtPointer()
|
||||
end
|
||||
if unit==nil then
|
||||
error("Invalid unit!")
|
||||
end
|
||||
local other=df.global.world.units.active
|
||||
local unit_indx
|
||||
for k,v in pairs(other) do
|
||||
if v==unit then
|
||||
unit_indx=k
|
||||
break
|
||||
end
|
||||
end
|
||||
if unit_indx==nil then
|
||||
error("Unit not found in array?!") --should not happen
|
||||
end
|
||||
other[unit_indx]=other[0]
|
||||
other[0]=unit
|
||||
if nemesis then --basicly copied from advtools plugin...
|
||||
local nem=getNemesis(unit)
|
||||
local other_nem=getNemesis(other[unit_indx])
|
||||
if other_nem then
|
||||
other_nem.flags[0]=false
|
||||
other_nem.flags[1]=true
|
||||
end
|
||||
if nem then
|
||||
nem.flags[0]=true
|
||||
nem.flags[2]=true
|
||||
for k,v in pairs(df.global.world.nemesis.all) do
|
||||
if v.id==nem.id then
|
||||
df.global.ui_advmode.player_id=k
|
||||
end
|
||||
end
|
||||
else
|
||||
error("Current unit does not have nemesis record, further working not guaranteed")
|
||||
end
|
||||
end
|
||||
end
|
||||
tools.menu:add("Change Adventurer",tools.change_adv)
|
||||
|
||||
function tools.MakeFollow(unit,trgunit)
|
||||
|
||||
if unit == nil then
|
||||
unit=getCreature()
|
||||
end
|
||||
if unit== nil then
|
||||
error("Invalid creature")
|
||||
end
|
||||
if trgunit==nil then
|
||||
trgunit=df.global.world.units.active[0]
|
||||
end
|
||||
unit.relations.group_leader_id=trgunit.id
|
||||
local u_nem=getNemesis(unit)
|
||||
local t_nem=getNemesis(trgunit)
|
||||
if u_nem then
|
||||
u_nem.group_leader_id=t_nem.id
|
||||
end
|
||||
if t_nem and u_nem then
|
||||
t_nem.companions:insert(#t_nem.companions,u_nem.id)
|
||||
end
|
||||
end
|
||||
tools.menu:add("Make creature follow",tools.MakeFollow)
|
||||
function tools.getsite(names)
|
||||
if words==nil then --do once its slow.
|
||||
words,rwords=BuildWordTables()
|
||||
end
|
||||
|
||||
if names==nil then
|
||||
print("Type words that are in the site name, FULLCAPS, no modifiers (lovely->LOVE), q to quit:")
|
||||
names={}
|
||||
repeat
|
||||
w=getline();
|
||||
|
||||
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=getline()
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
print("Type which to change (q cancels):")
|
||||
repeat
|
||||
r=getline()
|
||||
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=getline()
|
||||
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.project(unit,trg)
|
||||
if unit==nil then
|
||||
unit=getCreatureAtPointer()
|
||||
end
|
||||
|
||||
if unit==nil then
|
||||
error("Failed to project unit. Unit not selected/valid")
|
||||
end
|
||||
-- todo: add projectile to world, point to unit, add flag to unit, add gen-ref to projectile.
|
||||
local p=df.proj_unitst:new()
|
||||
local startpos={x=unit.pos.x,y=unit.pos.y,z=unit.pos.z}
|
||||
p.origin_pos=startpos
|
||||
p.target_pos=trg
|
||||
p.cur_pos=startpos
|
||||
p.prev_pos=startpos
|
||||
p.unit=unit
|
||||
--- wtf stuff
|
||||
p.unk14=100
|
||||
p.unk16=-1
|
||||
p.unk23=-1
|
||||
p.fall_delay=5
|
||||
p.fall_counter=5
|
||||
p.collided=true
|
||||
-- end wtf
|
||||
local citem=df.global.world.proj_list
|
||||
local maxid=1
|
||||
local newlink=df.proj_list_link:new()
|
||||
newlink.item=p
|
||||
while citem.item~= nil do
|
||||
if citem.item.id>maxid then maxid=citem.item.id end
|
||||
if citem.next ~= nil then
|
||||
citem=citem.next
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
p.id=maxid+1
|
||||
newlink.prev=citem
|
||||
citem.next=newlink
|
||||
|
||||
local proj_ref=df.general_ref_projectile:new()
|
||||
proj_ref.projectile_id=p.id
|
||||
unit.refs:insert(#unit.refs,proj_ref)
|
||||
unit.flags1.projectile=true
|
||||
end
|
||||
function tools.empregnate(unit)
|
||||
if unit==nil then
|
||||
unit=getSelectedUnit()
|
||||
end
|
||||
|
||||
if unit==nil then
|
||||
unit=getCreatureAtPos(getxyz())
|
||||
end
|
||||
|
||||
if unit==nil then
|
||||
error("Failed to empregnate. Unit not selected/valid")
|
||||
end
|
||||
if unit.curse then
|
||||
unit.curse.add_tags2.STERILE=false
|
||||
end
|
||||
local genes = unit.appearance.genes
|
||||
if unit.relations.pregnancy_ptr == nil then
|
||||
print("creating preg ptr.")
|
||||
if false then
|
||||
print(string.format("%x %x",df.sizeof(unit.relations:_field("pregnancy_ptr"))))
|
||||
return
|
||||
end
|
||||
unit.relations.pregnancy_ptr = { new = true, assign = genes }
|
||||
end
|
||||
local ngenes = unit.relations.pregnancy_ptr
|
||||
if #ngenes.appearance ~= #genes.appearance or #ngenes.colors ~= #genes.colors then
|
||||
print("Array sizes incorrect, fixing.")
|
||||
ngenes:assign(genes);
|
||||
end
|
||||
print("Setting preg timer.")
|
||||
unit.relations.pregnancy_timer=10
|
||||
unit.relations.pregnancy_mystery=1
|
||||
end
|
||||
tools.menu:add("Empregnate",tools.empregnate)
|
||||
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=getline()
|
||||
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.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=getline()
|
||||
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(getline())
|
||||
print("enter x1:")
|
||||
xe=tonumber(getline())
|
||||
print("enter y0:")
|
||||
ys=tonumber(getline())
|
||||
print("enter y1:")
|
||||
ye=tonumber(getline())
|
||||
print("enter z0:")
|
||||
zs=tonumber(getline())
|
||||
print("enter z1:")
|
||||
ze=tonumber(getline())
|
||||
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
|
@ -1,8 +0,0 @@
|
||||
if not(FILE) then
|
||||
--tools.menu:add("Change site type",tools.changesite)
|
||||
--tools.menu:add("Change site flags",tools.changeflags)
|
||||
--tools.menu:add("Hostilate creature",tools.hostilate)
|
||||
--tools.menu:add("Print current mouse block",tools.mouseBlock)
|
||||
|
||||
tools.menu:display()
|
||||
end
|
@ -1 +0,0 @@
|
||||
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
function iter(tbl)
if getmetatable(tbl) ~=nil then
if getmetatable(tbl).__next~= nil then
return getmetatable(tbl).__next,tbl
else
return getmetatable(tbl).__pairs(tbl) or pairs(tbl)
end
else
return pairs(tbl)
end
end
|
Loading…
Reference in New Issue