Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 37 38 [39] 40 41 ... 44

Author Topic: Putnam's DFHack scripts  (Read 114919 times)

nuker22110

  • Bay Watcher
    • View Profile
Re: Putnam's DFHack scripts
« Reply #570 on: August 29, 2014, 08:38:47 pm »

If you're not already, use gui/hack-wish from now on (included with DFHack).

thank you for your reply. attempting to use gui/hack-wish in 0.40.10 gives off some error about 'attempt to index global utils(a nill value), something about tail calls'

am i doing something wrong? thank you once again
Logged

Putnam

  • Bay Watcher
  • DAT WIZARD
    • View Profile
Re: Putnam's DFHack scripts
« Reply #571 on: August 29, 2014, 08:42:30 pm »

Nope, you're fine, replace it with this:

Code: [Select]
-- Allows for script-based wishing.
 
function getGenderString(gender)
 local genderStr
 if gender==0 then
  genderStr=string.char(12)
 elseif gender==1 then
  genderStr=string.char(11)
 else
  return ""
 end
 return string.char(40)..genderStr..string.char(41)
end
 
function getCreatureList()
 local crList={}
 for k,cr in ipairs(df.global.world.raws.creatures.alphabetic) do
  for kk,ca in ipairs(cr.caste) do
   local str=ca.caste_name[0]
   str=str..' '..getGenderString(ca.gender)
   table.insert(crList,{str,nil,ca})
  end
 end
 return crList
end
 
function getMatFilter(itemtype)
  local itemTypes={
   SEEDS=function(mat,parent,typ,idx)
    return mat.flags.SEED_MAT
   end,
   PLANT=function(mat,parent,typ,idx)
    return mat.flags.STRUCTURAL_PLANT_MAT
   end,
   LEAVES=function(mat,parent,typ,idx)
    return mat.flags.LEAF_MAT
   end,
   MEAT=function(mat,parent,typ,idx)
    return mat.flags.MEAT
   end,
   CHEESE=function(mat,parent,typ,idx)
    return (mat.flags.CHEESE_PLANT or mat.flags.CHEESE_CREATURE)
   end,
   LIQUID_MISC=function(mat,parent,typ,idx)
    return (mat.flags.LIQUID_MISC_PLANT or mat.flags.LIQUID_MISC_CREATURE or mat.flags.LIQUID_MISC_OTHER)
   end,
   POWDER_MISC=function(mat,parent,typ,idx)
    return (mat.flags.POWDER_MISC_PLANT or mat.flags.POWDER_MISC_CREATURE)
   end,
   DRINK=function(mat,parent,typ,idx)
    return (mat.flags.ALCOHOL_PLANT or mat.flags.ALCOHOL_CREATURE)
   end,
   GLOB=function(mat,parent,typ,idx)
    return (mat.flags.STOCKPILE_GLOB)
   end,
   WOOD=function(mat,parent,typ,idx)
    return (mat.flags.WOOD)
   end,
   THREAD=function(mat,parent,typ,idx)
    return (mat.flags.THREAD_PLANT)
   end,
   LEATHER=function(mat,parent,typ,idx)
    return (mat.flags.LEATHER)
   end
  }
  return itemTypes[df.item_type[itemtype]] or getRestrictiveMatFilter(itemtype)
end
 
function getRestrictiveMatFilter(itemType)
 if not args.veryRestrictive then return nil else
 local itemTypes={
   WEAPON=function(mat,parent,typ,idx)
    return (mat.flags.ITEMS_WEAPON or mat.flags.ITEMS_WEAPON_RANGED)
   end,
   AMMO=function(mat,parent,typ,idx)
    return (mat.flags.ITEMS_AMMO)
   end,
   ARMOR=function(mat,parent,typ,idx)
    return (mat.flags.ITEMS_ARMOR)
   end,
   SHOES,SHIELD,HELM,GLOVES=ARMOR,ARMOR,ARMOR,ARMOR,
   INSTRUMENT=function(mat,parent,typ,idx)
    return (mat.flags.ITEMS_HARD)
   end,
   GOBLET,FLASK,TOY,RING,CROWN,SCEPTER,FIGURINE,TOOL=INSTRUMENT,INSTRUMENT,INSTRUMENT,INSTRUMENT,INSTRUMENT,INSTRUMENT,INSTRUMENT,
   AMULET=function(mat,parent,typ,idx)
    return (mat.flags.ITEMS_SOFT or mat.flags.ITEMS_HARD)
   end,
   EARRING,BRACELET=AMULET,AMULET,
   ROCK=function(mat,parent,typ,idx)
    return (mat.flags.IS_STONE)
   end,
   BOULDER=ROCK,
   BAR=function(mat,parent,typ,idx)
    return (mat.flags.IS_METAL or mat.flags.SOAP or mat.id==COAL)
   end
   
  }
 return itemTypes[df.item_type[itemType]]
 end
end
 
function createItem(mat,itemType,quality,creator,description)
dfhack.items.createItem(itemType[1], itemType[2], mat[1], mat[2], creator)
 if df.item_type[itemType[1]]=='SLAB' then
  item.description=description
 end
end
 
function qualityTable()
 return {{'None'},
 {'-Well-crafted-'},
 {'+Finely-crafted+'},
 {'*Superior*'},
 {string.char(240)..'Exceptional'..string.char(240)},
 {string.char(15)..'Masterwork'..string.char(15)}
 }
end
 
local script=require('gui.script')
 
function showItemPrompt(text,item_filter,hide_none)
 require('gui.materials').ItemTypeDialog{
  prompt=text,
  item_filter=item_filter,
  hide_none=hide_none,
  on_select=script.mkresume(true),
  on_cancel=script.mkresume(false),
  on_close=script.qresume(nil)
 }:show()
 
 return script.wait()
end
 
function showMaterialPrompt(title, prompt, filter, inorganic, creature, plant) --the one included with DFHack doesn't have a filter or the inorganic, creature, plant things available
 require('gui.materials').MaterialDialog{
  frame_title = title,
  prompt = prompt,
  mat_filter = filter,
  use_inorganic = inorganic,
  use_creature = creature,
  use_plant = plant,
  on_select = script.mkresume(true),
  on_cancel = script.mkresume(false),
  on_close = script.qresume(nil)
 }:show()
 
 return script.wait()
end
 
function usesCreature(itemtype)
 typesThatUseCreatures={REMAINS=true,FISH=true,FISH_RAW=true,VERMIN=true,PET=true,EGG=true,CORPSE=true,CORPSEPIECE=true}
 return typesThatUseCreatures[df.item_type[itemtype]]
end
 
function getCreatureRaceAndCaste(caste)
 return df.global.world.raws.creatures.list_creature[caste.index],df.global.world.raws.creatures.list_caste[caste.index]
end
 
function hackWish(unit)
 script.start(function()
  local amountok, amount
  local matok,mattype,matindex,matFilter
  local itemok,itemtype,itemsubtype=showItemPrompt('What item do you want?',function(itype) return df.item_type[itype]~='CORPSE' and df.item_type[itype]~='FOOD' end ,true)
  if not args.notRestrictive then
   matFilter=getMatFilter(itemtype)
  end
  if not usesCreature(itemtype) then
   matok,mattype,matindex=showMaterialPrompt('Wish','And what material should it be made of?',matFilter)
  else
   local creatureok,useless,creatureTable=script.showListPrompt('Wish','What creature should it be?',COLOR_LIGHTGREEN,getCreatureList())
   mattype,matindex=getCreatureRaceAndCaste(creatureTable[3])
  end
  local qualityok,quality=script.showListPrompt('Wish','What quality should it be?',COLOR_LIGHTGREEN,qualityTable())
  local description
  if df.item_type[itemtype]=='SLAB' then
   local descriptionok
   descriptionok,description=script.showInputPrompt('Slab','What should the slab say?',COLOR_WHITE)
  end
  if args.multi then
   repeat amountok,amount=script.showInputPrompt('Wish','How many do you want? (numbers only!)',COLOR_LIGHTGREEN) until tonumber(amount)
    if mattype and itemtype then
     for i=1,tonumber(amount) do
      createItem({mattype,matindex},{itemtype,itemsubtype},quality,unit,description)
     end
    end
  else
   if mattype and itemtype then
    createItem({mattype,matindex},{itemtype,itemsubtype},quality,unit,description)
   end   
  end
 end)
end
 
scriptArgs={...}

utils=require('utils')

validArgs = validArgs or utils.invert({
 'startup',
 'all',
 'restrictive',
 'unit',
 'multi'
})

args = utils.processArgs({...}, validArgs)
 
eventful=require('plugins.eventful')

if not args.startup then
 local unit=args.unit and df.unit.find(args.unit) or dfhack.gui.getSelectedUnit(true)
 hackWish(unit)
else
 eventful.onReactionComplete.hackWishP=function(reaction,unit,input_items,input_reagents,output_items,call_native)
  if not reaction.code:find('DFHACK_WISH') then return nil end
  hackWish(unit)
 end
end

nuker22110

  • Bay Watcher
    • View Profile
Re: Putnam's DFHack scripts
« Reply #572 on: August 29, 2014, 09:52:48 pm »

Nope, you're fine, replace it with this:

Code: [Select]
-- Allows for script-based wishing.
 
function getGenderString(gender)
 local genderStr
 if gender==0 then
  genderStr=string.char(12)
 elseif gender==1 then
  genderStr=string.char(11)
 else
  return ""
 end
 return string.char(40)..genderStr..string.char(41)
end
 
function getCreatureList()
 local crList={}
 for k,cr in ipairs(df.global.world.raws.creatures.alphabetic) do
  for kk,ca in ipairs(cr.caste) do
   local str=ca.caste_name[0]
   str=str..' '..getGenderString(ca.gender)
   table.insert(crList,{str,nil,ca})
  end
 end
 return crList
end
 
function getMatFilter(itemtype)
  local itemTypes={
   SEEDS=function(mat,parent,typ,idx)
    return mat.flags.SEED_MAT
   end,
   PLANT=function(mat,parent,typ,idx)
    return mat.flags.STRUCTURAL_PLANT_MAT
   end,
   LEAVES=function(mat,parent,typ,idx)
    return mat.flags.LEAF_MAT
   end,
   MEAT=function(mat,parent,typ,idx)
    return mat.flags.MEAT
   end,
   CHEESE=function(mat,parent,typ,idx)
    return (mat.flags.CHEESE_PLANT or mat.flags.CHEESE_CREATURE)
   end,
   LIQUID_MISC=function(mat,parent,typ,idx)
    return (mat.flags.LIQUID_MISC_PLANT or mat.flags.LIQUID_MISC_CREATURE or mat.flags.LIQUID_MISC_OTHER)
   end,
   POWDER_MISC=function(mat,parent,typ,idx)
    return (mat.flags.POWDER_MISC_PLANT or mat.flags.POWDER_MISC_CREATURE)
   end,
   DRINK=function(mat,parent,typ,idx)
    return (mat.flags.ALCOHOL_PLANT or mat.flags.ALCOHOL_CREATURE)
   end,
   GLOB=function(mat,parent,typ,idx)
    return (mat.flags.STOCKPILE_GLOB)
   end,
   WOOD=function(mat,parent,typ,idx)
    return (mat.flags.WOOD)
   end,
   THREAD=function(mat,parent,typ,idx)
    return (mat.flags.THREAD_PLANT)
   end,
   LEATHER=function(mat,parent,typ,idx)
    return (mat.flags.LEATHER)
   end
  }
  return itemTypes[df.item_type[itemtype]] or getRestrictiveMatFilter(itemtype)
end
 
function getRestrictiveMatFilter(itemType)
 if not args.veryRestrictive then return nil else
 local itemTypes={
   WEAPON=function(mat,parent,typ,idx)
    return (mat.flags.ITEMS_WEAPON or mat.flags.ITEMS_WEAPON_RANGED)
   end,
   AMMO=function(mat,parent,typ,idx)
    return (mat.flags.ITEMS_AMMO)
   end,
   ARMOR=function(mat,parent,typ,idx)
    return (mat.flags.ITEMS_ARMOR)
   end,
   SHOES,SHIELD,HELM,GLOVES=ARMOR,ARMOR,ARMOR,ARMOR,
   INSTRUMENT=function(mat,parent,typ,idx)
    return (mat.flags.ITEMS_HARD)
   end,
   GOBLET,FLASK,TOY,RING,CROWN,SCEPTER,FIGURINE,TOOL=INSTRUMENT,INSTRUMENT,INSTRUMENT,INSTRUMENT,INSTRUMENT,INSTRUMENT,INSTRUMENT,
   AMULET=function(mat,parent,typ,idx)
    return (mat.flags.ITEMS_SOFT or mat.flags.ITEMS_HARD)
   end,
   EARRING,BRACELET=AMULET,AMULET,
   ROCK=function(mat,parent,typ,idx)
    return (mat.flags.IS_STONE)
   end,
   BOULDER=ROCK,
   BAR=function(mat,parent,typ,idx)
    return (mat.flags.IS_METAL or mat.flags.SOAP or mat.id==COAL)
   end
   
  }
 return itemTypes[df.item_type[itemType]]
 end
end
 
function createItem(mat,itemType,quality,creator,description)
dfhack.items.createItem(itemType[1], itemType[2], mat[1], mat[2], creator)
 if df.item_type[itemType[1]]=='SLAB' then
  item.description=description
 end
end
 
function qualityTable()
 return {{'None'},
 {'-Well-crafted-'},
 {'+Finely-crafted+'},
 {'*Superior*'},
 {string.char(240)..'Exceptional'..string.char(240)},
 {string.char(15)..'Masterwork'..string.char(15)}
 }
end
 
local script=require('gui.script')
 
function showItemPrompt(text,item_filter,hide_none)
 require('gui.materials').ItemTypeDialog{
  prompt=text,
  item_filter=item_filter,
  hide_none=hide_none,
  on_select=script.mkresume(true),
  on_cancel=script.mkresume(false),
  on_close=script.qresume(nil)
 }:show()
 
 return script.wait()
end
 
function showMaterialPrompt(title, prompt, filter, inorganic, creature, plant) --the one included with DFHack doesn't have a filter or the inorganic, creature, plant things available
 require('gui.materials').MaterialDialog{
  frame_title = title,
  prompt = prompt,
  mat_filter = filter,
  use_inorganic = inorganic,
  use_creature = creature,
  use_plant = plant,
  on_select = script.mkresume(true),
  on_cancel = script.mkresume(false),
  on_close = script.qresume(nil)
 }:show()
 
 return script.wait()
end
 
function usesCreature(itemtype)
 typesThatUseCreatures={REMAINS=true,FISH=true,FISH_RAW=true,VERMIN=true,PET=true,EGG=true,CORPSE=true,CORPSEPIECE=true}
 return typesThatUseCreatures[df.item_type[itemtype]]
end
 
function getCreatureRaceAndCaste(caste)
 return df.global.world.raws.creatures.list_creature[caste.index],df.global.world.raws.creatures.list_caste[caste.index]
end
 
function hackWish(unit)
 script.start(function()
  local amountok, amount
  local matok,mattype,matindex,matFilter
  local itemok,itemtype,itemsubtype=showItemPrompt('What item do you want?',function(itype) return df.item_type[itype]~='CORPSE' and df.item_type[itype]~='FOOD' end ,true)
  if not args.notRestrictive then
   matFilter=getMatFilter(itemtype)
  end
  if not usesCreature(itemtype) then
   matok,mattype,matindex=showMaterialPrompt('Wish','And what material should it be made of?',matFilter)
  else
   local creatureok,useless,creatureTable=script.showListPrompt('Wish','What creature should it be?',COLOR_LIGHTGREEN,getCreatureList())
   mattype,matindex=getCreatureRaceAndCaste(creatureTable[3])
  end
  local qualityok,quality=script.showListPrompt('Wish','What quality should it be?',COLOR_LIGHTGREEN,qualityTable())
  local description
  if df.item_type[itemtype]=='SLAB' then
   local descriptionok
   descriptionok,description=script.showInputPrompt('Slab','What should the slab say?',COLOR_WHITE)
  end
  if args.multi then
   repeat amountok,amount=script.showInputPrompt('Wish','How many do you want? (numbers only!)',COLOR_LIGHTGREEN) until tonumber(amount)
    if mattype and itemtype then
     for i=1,tonumber(amount) do
      createItem({mattype,matindex},{itemtype,itemsubtype},quality,unit,description)
     end
    end
  else
   if mattype and itemtype then
    createItem({mattype,matindex},{itemtype,itemsubtype},quality,unit,description)
   end   
  end
 end)
end
 
scriptArgs={...}

utils=require('utils')

validArgs = validArgs or utils.invert({
 'startup',
 'all',
 'restrictive',
 'unit',
 'multi'
})

args = utils.processArgs({...}, validArgs)
 
eventful=require('plugins.eventful')

if not args.startup then
 local unit=args.unit and df.unit.find(args.unit) or dfhack.gui.getSelectedUnit(true)
 hackWish(unit)
else
 eventful.onReactionComplete.hackWishP=function(reaction,unit,input_items,input_reagents,output_items,call_native)
  if not reaction.code:find('DFHACK_WISH') then return nil end
  hackWish(unit)
 end
end

thank you sir. i would like to report that attempting to spawn any raw materials like meat/seeds/bars would cause the game to crash after choosing quality(be it none or masterwork)
Logged

Putnam

  • Bay Watcher
  • DAT WIZARD
    • View Profile
Re: Putnam's DFHack scripts
« Reply #573 on: August 29, 2014, 10:06:26 pm »

Oh my. That's odd.

lethosor

  • Bay Watcher
    • View Profile
Re: Putnam's DFHack scripts
« Reply #574 on: August 29, 2014, 10:07:23 pm »

It looks like you have to select a unit (edit: confirmed) - without it, dfhack.items.createItem() receives nil as the 5th argument and crashes.
« Last Edit: August 29, 2014, 10:09:13 pm by lethosor »
Logged
DFHack - Dwarf Manipulator (Lua) - DF Wiki talk

There was a typo in the siegers' campfire code. When the fires went out, so did the game.

Putnam

  • Bay Watcher
  • DAT WIZARD
    • View Profile
Re: Putnam's DFHack scripts
« Reply #575 on: August 29, 2014, 10:09:13 pm »

It looks like you have to select a unit - without it, dfhack.items.createItem() receives nil as the 5th argument and crashes.

I would hope that having a nil argument doesn't crash it. I'll have to implement an exception for that then...

lethosor

  • Bay Watcher
    • View Profile
Re: Putnam's DFHack scripts
« Reply #576 on: August 29, 2014, 10:19:55 pm »

Passing nil as the fifth argument to createItem() will actually crash in the first (source) line (nil is converted to NULL, and accessing a null pointer almost always crashes):
int32_t Items::createItem(df::item_type item_type, int16_t item_subtype, int16_t mat_type, int32_t mat_index, df::unit* unit) {
    //based on Quietust's plugins/createitem.cpp
    df::map_block* block = Maps::getTileBlock(unit->pos.x, unit->pos.y, unit->pos.z);
It should be possible to implement your old method of item creation in C++ easily enough, though (I believe it used moveToGround() and a cursor position).
Logged
DFHack - Dwarf Manipulator (Lua) - DF Wiki talk

There was a typo in the siegers' campfire code. When the fires went out, so did the game.

TimoRan

  • Escaped Lunatic
    • View Profile
Re: Putnam's DFHack scripts
« Reply #577 on: September 01, 2014, 11:35:05 am »

Okay, so any updates on force? I'm using the latest DF version, and I tried the old force script from the DF repository, didn't work obviously. The version of the script from Putnams github gave me this...


*edit* Line 94: allEventTypes[eventType]()

Then I tried the latest dfhack force script from the github and I got...


*edit* Line 607: error('error parsing arg ' .. i .. ': ' .. arg)
          (under the processArgs(args, validArgs) function)
          Line 25:   local args = utils.processArgs({...}, validArgs)


Not sure if entirely relevant it's just that I'm out of ideas, Lua isn't a familiar language.

*edit* I'm trying to start off with a 100 or so dwarves, and I'm here because none of the embark scripts worked for me either.
« Last Edit: September 01, 2014, 11:49:04 am by TimoRan »
Logged

expwnent

  • Bay Watcher
    • View Profile
Re: Putnam's DFHack scripts
« Reply #578 on: September 01, 2014, 12:57:50 pm »

There's no way around the unit requirement. The way items are created by that method is by simulating a custom reaction. There must be a worker so that item creator race / creator id / etc are set correctly. In this case we're calling DF's code directly so there's nothing we can do about that requirement.
Logged

lethosor

  • Bay Watcher
    • View Profile
Re: Putnam's DFHack scripts
« Reply #579 on: September 01, 2014, 04:27:40 pm »

startdwarf needs the start_dwarf_count offset to work on Windows and Linux - replace DF/hack/symbols.xml with this.
Logged
DFHack - Dwarf Manipulator (Lua) - DF Wiki talk

There was a typo in the siegers' campfire code. When the fires went out, so did the game.

TimoRan

  • Escaped Lunatic
    • View Profile
Re: Putnam's DFHack scripts
« Reply #580 on: September 01, 2014, 10:58:24 pm »

startdwarf needs the start_dwarf_count offset to work on Windows and Linux - replace DF/hack/symbols.xml with this.

Wow, that actually worked, thanks! 100 starting dwarves!  :D
Logged

expwnent

  • Bay Watcher
    • View Profile
Re: Putnam's DFHack scripts
« Reply #581 on: September 02, 2014, 04:22:25 am »

startdwarf needs the start_dwarf_count offset to work on Windows and Linux - replace DF/hack/symbols.xml with this.

I'm surprised that works. I expected it to be necessary to recompile with that.
Logged

faloxx

  • Bay Watcher
  • Petting a dragon is not a good idea, trust me.
    • View Profile
Re: Putnam's DFHack scripts
« Reply #582 on: September 17, 2014, 10:44:10 am »

Is there any more news on that force event thing? I do want to force some of the events and I'm getting kind of the same error.



So is there any fix for it?
Logged

Putnam

  • Bay Watcher
  • DAT WIZARD
    • View Profile
Re: Putnam's DFHack scripts
« Reply #583 on: September 17, 2014, 03:20:53 pm »

yeah, use the latest version of force, which doesn't use whatever stupid thing is going on there (looks like I was trying to find an entity using df.global.world.history.entities.all or something along those lines, which is very, very wrong).

expwnent

  • Bay Watcher
    • View Profile
Re: Putnam's DFHack scripts
« Reply #584 on: September 17, 2014, 03:27:03 pm »

Is there anything wrong with the one in the main repo?
Logged
Pages: 1 ... 37 38 [39] 40 41 ... 44