local _ENV = mkmodule('plugins.dfusion.tools') local dfu=require("plugins.dfusion") local ms=require "memscan" menu=dfu.SimpleMenu() RaceNames={} function build_race_names() if #RaceNames~=0 then return RaceNames else for k,v in pairs(df.global.world.raws.creatures.all) do RaceNames[v.creature_id]=k end dfhack.onStateChange.invalidate_races=function(change_id) --todo does this work? if change_id==SC_WORLD_UNLOADED then dfhack.onStateChange.invalidate_races=nil RaceNames={} end end return RaceNames end end function setrace(name) local RaceTable=build_race_names() print("Your current race is:"..df.global.world.raws.creatures.all[df.global.ui.race_id].creature_id) local id if name == nil then print("Type new race's token name in full caps (q to quit):") repeat local entry=io.stdin:read() 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 menu:add("Set current race",setrace) function GiveSentience(names) local RaceTable=build_race_names() --slow.If loaded don't load again local id,ids if names ==nil then ids={} print("Type race's token name in full caps to give sentience to:") repeat id=io.stdin:read() id=RaceTable[entry] if id~=nil then table.insert(ids,id) end until id==nil 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)) 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 menu:add("Give Sentience",GiveSentience) function MakeFollow(unit,trgunit) if unit == nil then unit=dfhack.gui.getSelectedUnit() 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=dfhack.units.getNemesis(unit) local t_nem=dfhack.units.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 menu:add("Make creature follow",MakeFollow) function project(unit,trg) --TODO add to menu? 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.general_refs:insert(#unit.general_refs,proj_ref) unit.flags1.projectile=true end function empregnate(unit) if unit==nil then unit=dfhack.gui.getSelectedUnit() 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 menu:add("Empregnate",empregnate) function healunit(unit) if unit==nil then unit=dfhack.gui.getSelectedUnit() end if unit==nil then error("Failed to Heal unit. Unit not selected/valid") end unit.body.wounds:resize(0) -- memory leak here :/ unit.body.blood_count=unit.body.blood_max --set flags for standing and grasping... unit.status2.able_stand=4 unit.status2.able_stand_impair=4 unit.status2.able_grasp=4 unit.status2.able_grasp_impair=4 --should also set temperatures, and flags for breath etc... unit.flags1.dead=false unit.flags2.calculated_bodyparts=false unit.flags2.calculated_nerves=false unit.flags2.circulatory_spray=false unit.flags2.vision_good=true unit.flags2.vision_damaged=false unit.flags2.vision_missing=false unit.counters.winded=0 unit.counters.unconscious=0 for k,v in pairs(unit.body.components) do for kk,vv in pairs(v) do if k == 'body_part_status' then v[kk].whole = 0 else v[kk] = 0 end end end end menu:add("Heal unit",healunit) function powerup(unit,labor_rating,military_rating,skills) if unit==nil then unit=dfhack.gui.getSelectedUnit() end if unit==nil then error("Failed to power up unit. Unit not selected/valid") end if unit.status.current_soul== nil then error("Failed to power up unit. Unit has no soul") end local utils = require 'utils' labor_rating = labor_rating or 15 military_rating = military_rating or 70 skill =skill or { 0,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,41,42,43,44,45,46,47,48,49,54,55,57,58,59,60,61,62,63,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,95,96,97,98,99,100,101,102,103,104,105,109,110,111,112,113,114,115 } local military = { 38,39,41,42,43,44,45,46,54,99,100,101,102,103,104,105 } for sk,sv in ipairs(skill) do local new_rating = labor_rating for _,v in ipairs(military) do if v == sv then local new_rating = military_rating end end utils.insert_or_update(unit.status.current_soul.skills, { new = true, id = sv, rating = new_rating, experience = (new_rating * 500) + (new_rating * (new_rating - 1)) * 50}, 'id') end end menu:add("Power up",powerup) return _ENV