diff --git a/plugins/Dfusion/luafiles/editor.lua b/plugins/Dfusion/luafiles/editor.lua new file mode 100644 index 000000000..53d2c5b05 --- /dev/null +++ b/plugins/Dfusion/luafiles/editor.lua @@ -0,0 +1,145 @@ +function getTypename(object) + local tbl + local ret={} + if getmetatable(object)~=nil then + local tbl=getmetatable(object) + for k,v in pairs(xtypes) do + if v==tbl then + return k + end + end + for k,v in pairs(xtypes.containers) do + if v==tbl then + return k + end + end + end + if object.name~= nil then + return object.name + end + return "?" +end +function getFields(object) + local tbl + local ret={} + if getmetatable(object)==xtypes["struct-type"].wrap then + tbl=rawget(object,"mtype") + elseif getmetatable(object)==xtypes["struct-type"] then + tbl=object + else + error("Not an class_type or a class_object") + end + for k,v in pairs(tbl.types) do + table.insert(ret,{k,v[2],getTypename(v[1])}) + --ret[v[2]]=k + --print(string.format("%s %x",k,v[2])) + end + table.sort(ret,function (a,b) return a[2]>b[2] end) + return ret +end +function editField(tbl,field,typename) + if EditType[typename] ~= nil then + EditType[typename](tbl[field]) + else + print("Cur value:"..tostring(tbl[field])) + val=getline("Enter newvalue:") + tbl[field]=val + end +end +EditType={} +EditType["df-flagarray"]=function(trg) + local fields=rawget(trg,"mtype").index.names + print("Flag count:"..trg.size) + print("Name count:"..#fields) + for i=0,#fields do + print(string.format("%3d %20s %s",i,fields[i],tostring(trg[i-1]))) + end + number=getline("enter flag id to flip:") + number=tonumber(number) + if number then + trg[fields[number]]= not trg[fields[number]] + end +end +EditType["enum-type"]=function(trg) + local fields=rawget(trg,"mtype").names + local typename=getTypename(rawget(trg,"mtype").etype) + for k,v in pairs(fields) do + print(string.format("%3d %s",k,v)) + end + local cval=trg:get() + if fields[cval]~= nil then + print(string.format("Current value:%d (%s)",cval,fields[cval])) + else + print(string.format("Current value:%d",cval)) + end + number=getline("enter new value:") + number=tonumber(number) + if number then + trg:set(number) + end +end +EditType["static-array"]=function(trg) + local item_type=rawget(trg,"mtype").item_type + local typename=getTypename(item_type) + number=getline(string.format("Select item (max %d, item-type '%s'):",trg.size,typename)) + number=tonumber(number) + if number then + EditType[typename](trg[number]) + end +end +EditType["stl-vector"]=EditType["static-array"] +EditType["struct-type"]=function(trg) + local mtype=rawget(trg,"mtype") + local fields=getFields(trg) + for k,v in pairs(fields) do + print(string.format("%4d %25s %s",k,v[1],v[3])) + end + number=getline("Choose field to edit:") + number=tonumber(number) + if number then + local v=fields[number] + editField(trg,v[1],v[3]) + end +end +EditType["pointer"]=function(trg) + local mtype=rawget(trg,"mtype").ptype + local typename=getTypename(mtype) + print("Auto dereferencing pointer! type:"..typename) + if EditType[typename] ~= nil then + EditType[typename](trg:deref()) + else + print("Cur value:"..tostring(trg:deref())) + val=getline("Enter newvalue:") + trg:setref(val) + end +end + +function EditDF() + local i=1 + local tbl={} + for k,v in pairs(rawget(df,"types")) do + print(string.format("%4d %25s %s",i,k,getTypename(v))) + tbl[i]={k,getTypename(v)} + i=i+1 + end + number=Console.lineedit("select item to edit (q to quit):") + if number and tonumber(number) then + local entry=tbl[tonumber(number)] + if entry==nil then + return + end + editField(df,entry[1],entry[2]) + --[=[ + if EditType[entry[2]] ~= nil then + EditType[entry[2]](df[entry[1]]) + else + print("Cur value:"..tostring(df[entry[1]])) + val=getline("Enter newvalue:") + df[entry[1]]=val + end + --]=] + end +end +function EditObject(obj) + EditType[getTypename(obj)](obj) +end \ No newline at end of file diff --git a/plugins/Dfusion/luafiles/init.lua b/plugins/Dfusion/luafiles/init.lua index d329bd704..e20ff2426 100644 --- a/plugins/Dfusion/luafiles/init.lua +++ b/plugins/Dfusion/luafiles/init.lua @@ -70,12 +70,12 @@ table.insert(plugins,{"editor","edit internals of df",EditDF}) loadall(plugins) dofile_silent("dfusion/initcustom.lua") ---[=[print("Locating saves...") -local str=engine.peekstr(0x1447A40+offsets.base()) +print("Locating saves...") +local str=df.world.cur_savegame.save_dir 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/tools/init.lua b/plugins/Dfusion/luafiles/tools/init.lua index 8f8a426fa..8381b1d0e 100644 --- a/plugins/Dfusion/luafiles/tools/init.lua +++ b/plugins/Dfusion/luafiles/tools/init.lua @@ -32,27 +32,21 @@ function tools.GiveSentience(names) --TODO make pattern... 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) + local races=df.world.raws.creatures.all + + local castes=races[id]:deref().caste + print(string.format("Caste count:%i",castes.size)) + for i =0,castes.size-1 do + + print("Caste name:"..castes[i]:deref().caste_id.."...") + + local flags=castes[i]:deref().flags --print(string.format("%x",flagoffset)) - if flags:get(57) then + if flags.CAN_SPEAK then print("\tis sentient.") else print("\tnon sentient. Allocating IQ...") - flags:set(57,1) - engine.poke(flagoffset,flagPattern,flags) + flags.CAN_SPEAK=true end end end @@ -162,16 +156,6 @@ function tools.MakeFollow() end end tools.menu:add("Make creature follow",tools.MakeFollow) -function tools.runscript(files) - if files==nil then - files={} - table.insert(files,getline()) - end - for _,v in pairs(files) do - print("Running script:"..v) - ParseScript(v) - end -end function tools.getsite(names) if words==nil then --do once its slow. words,rwords=BuildWordTables() @@ -341,86 +325,6 @@ function tools.mouseBlock() 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=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.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) diff --git a/plugins/Dfusion/luafiles/tools/plugin.lua b/plugins/Dfusion/luafiles/tools/plugin.lua index 511b73205..8eaefd44d 100644 --- a/plugins/Dfusion/luafiles/tools/plugin.lua +++ b/plugins/Dfusion/luafiles/tools/plugin.lua @@ -1,33 +1,8 @@ ---local bit = require("bit") - if not(FILE) then - tools.menu:add("Change site type",tools.changesite) - tools.menu:add("Change site flags",tools.changeflags) - tools.menu:add("Run script file",tools.runscript) - tools.menu:add("Hostilate creature",tools.hostilate) - tools.menu:add("Protect site from item scattering",tools.protectsite) - tools.menu:add("Print current mouse block",tools.mouseBlock) - --tools.menu:add("XXX",tools.fixwarp) + --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() - - --[[choices={ - {tools.setrace,"Change race"}, - {tools.GiveSentience,"Give Sentience"}, - {tools.embark,"Embark anywhere"}, - {tools.change_adv,"Change Adventurer"}, - {tools.changesite,"Change site type"}, - {tools.runscript,"Run script file"}, - {tools.MakeFollow,"Make creature follow"}, - {function () return end,"Quit"}} - print("Select choice:") - for p,c in pairs(choices) do - print(p..")."..c[2]) - end - repeat - ans=tonumber(io.stdin:read()) - if ans==nil or not(ans<=table.maxn(choices) and ans>0) then - print("incorrect choice") - end - until ans~=nil and (ans<=table.maxn(tdir) and ans>0) - choices[ans][1]()]]-- end \ No newline at end of file diff --git a/plugins/Dfusion/luafiles/xml_types.lua b/plugins/Dfusion/luafiles/xml_types.lua index ee3505dab..b3fa67239 100644 --- a/plugins/Dfusion/luafiles/xml_types.lua +++ b/plugins/Dfusion/luafiles/xml_types.lua @@ -130,9 +130,13 @@ function type_enum.new(node,obj) setmetatable(o,type_enum) o.names={} for k,v in pairs(node) do - if type(v)=="table" and v.xarg~=nil then - --print("\t"..k.." "..v.xarg.name) - o.names[k-1]=v.xarg.name + if v.label=="enum-item" then + if v.xarg~=nil and v.xarg.name then + --print("\t"..k.." "..v.xarg.name) + o.names[k-1]=v.xarg.name + else + o.names[k-1]=string.format("unk_%d",k-1) + end end end local btype=node.xarg["base-type"] or "uint32_t" @@ -486,6 +490,9 @@ function farr.new(node,obj) setmetatable(o,farr) o.size=8 o.__align=4 + if node.xarg["index-enum"]~= nil then + o.index=getGlobal(node.xarg["index-enum"],true) + end return o end function farr:makewrap(address) @@ -495,29 +502,79 @@ function farr:makewrap(address) setmetatable(o,self.wrap) return o end +function farr:bitread(addr,nbit) + local byte=engine.peekb(addr+nbit/8) + if bit.band(byte,bit.lshift(1,nbit%8))~=0 then + return true + else + return false + end +end +function farr:bitwrite(addr,nbit,value) + local byte=engine.peekb(addr+nbit/8) + if self:bitread(addr,nbit)~= value then + local byte=bit.bxor(byte,bit.lshift(1,nbit%8)) + engine.pokeb(addr+nbit/8,byte) + end +end +type_bitfield.wrap={} + +function type_bitfield:makewrap(address) + local o={} + o.mtype=self + o.ptr=address + setmetatable(o,self.wrap) + return o +end + farr.wrap={} +function farr.wrap.__next(tbl,key) + error("TODO") +end function farr.wrap:__index(key) local num=tonumber(key) local mtype=rawget(self,"mtype") - local size=type_read(rawget(self,"ptr")+4,DWORD) + local size=engine.peekd(rawget(self,"ptr")+4)*8 if key=="size" then - return size/mtype.ctype.size; + return size; + end + if mtype.index~=nil and num==nil then + --print("Requested:"..key) + for k,v in pairs(mtype.index.names) do + if v==key then + num=k + break + end + end + --print("is key:"..num) + end - error("TODO make __index for df-flagarray") - if num~=nil and num