2015-06-13 03:41:51 -06:00
-- create-item.lua
-- A gui-based item creation script.
2014-06-26 06:36:57 -06:00
-- author Putnam
-- edited by expwnent
2015-08-02 08:07:57 -06:00
--@module = true
2015-02-14 20:53:06 -07:00
2015-04-23 19:11:13 -06:00
local function getGenderString ( gender )
2014-06-26 06:36:57 -06:00
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
2015-02-14 20:53:06 -07:00
2015-04-23 19:11:13 -06:00
local function getCreatureList ( )
2014-06-26 06:36:57 -06:00
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
2015-02-14 20:53:06 -07:00
2015-04-23 19:11:13 -06:00
local function getRestrictiveMatFilter ( itemType )
if not args.restrictive then return nil end
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 ,
INSTRUMENT = function ( mat , parent , typ , idx )
return ( mat.flags . ITEMS_HARD )
end ,
AMULET = function ( mat , parent , typ , idx )
return ( mat.flags . ITEMS_SOFT or mat.flags . ITEMS_HARD )
end ,
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
}
for k , v in ipairs ( { ' GOBLET ' , ' FLASK ' , ' TOY ' , ' RING ' , ' CROWN ' , ' SCEPTER ' , ' FIGURINE ' , ' TOOL ' } ) do
itemTypes [ v ] = itemTypes.INSTRUMENT
end
for k , v in ipairs ( { ' SHOES ' , ' SHIELD ' , ' HELM ' , ' GLOVES ' } ) do
itemTypes [ v ] = itemTypes.ARMOR
end
for k , v in ipairs ( { ' EARRING ' , ' BRACELET ' } ) do
itemTypes [ v ] = itemTypes.AMULET
end
itemTypes.BOULDER = itemTypes.ROCK
return itemTypes [ df.item_type [ itemType ] ]
end
local function getMatFilter ( itemtype )
2014-08-16 06:45:49 -06:00
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 )
2014-06-26 06:36:57 -06:00
end
2015-02-14 20:53:06 -07:00
2015-04-23 19:11:13 -06:00
local function createItem ( mat , itemType , quality , creator , description )
local item = df.item . find ( dfhack.items . createItem ( itemType [ 1 ] , itemType [ 2 ] , mat [ 1 ] , mat [ 2 ] , creator ) )
2015-08-02 08:07:57 -06:00
assert ( item , ' failed to create item ' )
quality = math.max ( 0 , math.min ( 5 , quality - 1 ) )
item : setQuality ( quality )
2014-06-26 06:36:57 -06:00
if df.item_type [ itemType [ 1 ] ] == ' SLAB ' then
item.description = description
end
end
2015-02-14 20:53:06 -07:00
2015-04-23 19:11:13 -06:00
local function qualityTable ( )
2014-06-26 06:36:57 -06:00
return { { ' None ' } ,
2014-08-16 06:45:49 -06:00
{ ' -Well-crafted- ' } ,
{ ' +Finely-crafted+ ' } ,
{ ' *Superior* ' } ,
{ string.char ( 240 ) .. ' Exceptional ' .. string.char ( 240 ) } ,
{ string.char ( 15 ) .. ' Masterwork ' .. string.char ( 15 ) }
2014-06-26 06:36:57 -06:00
}
end
2015-02-14 20:53:06 -07:00
2014-08-16 06:45:49 -06:00
local script = require ( ' gui.script ' )
2015-02-14 20:53:06 -07:00
2015-04-23 19:11:13 -06:00
local function showItemPrompt ( text , item_filter , hide_none )
2014-08-16 06:45:49 -06:00
require ( ' gui.materials ' ) . ItemTypeDialog {
2014-06-26 06:36:57 -06:00
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 ( )
2015-02-14 20:53:06 -07:00
2014-06-26 06:36:57 -06:00
return script.wait ( )
end
2015-02-14 20:53:06 -07:00
2015-04-23 19:11:13 -06:00
local 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
2014-08-16 06:45:49 -06:00
require ( ' gui.materials ' ) . MaterialDialog {
2014-06-26 06:36:57 -06:00
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 ( )
2015-02-14 20:53:06 -07:00
2014-06-26 06:36:57 -06:00
return script.wait ( )
end
2015-02-14 20:53:06 -07:00
2015-04-23 19:11:13 -06:00
local function usesCreature ( itemtype )
2014-06-26 06:36:57 -06:00
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
2015-02-14 20:53:06 -07:00
2015-04-23 19:11:13 -06:00
local function getCreatureRaceAndCaste ( caste )
2014-06-26 06:36:57 -06:00
return df.global . world.raws . creatures.list_creature [ caste.index ] , df.global . world.raws . creatures.list_caste [ caste.index ]
end
2015-02-14 20:53:06 -07:00
2014-08-16 06:45:49 -06:00
function hackWish ( unit )
2014-06-26 06:36:57 -06:00
script.start ( function ( )
2014-08-16 06:45:49 -06:00
local amountok , amount
2014-06-26 06:36:57 -06:00
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 )
2015-08-02 08:07:57 -06:00
if not itemok then return end
2014-06-26 06:36:57 -06:00
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 )
2015-08-02 08:07:57 -06:00
if not matok then return end
2014-06-26 06:36:57 -06:00
else
local creatureok , useless , creatureTable = script.showListPrompt ( ' Wish ' , ' What creature should it be? ' , COLOR_LIGHTGREEN , getCreatureList ( ) )
2015-08-02 08:07:57 -06:00
if not creatureok then return end
2014-06-26 06:36:57 -06:00
mattype , matindex = getCreatureRaceAndCaste ( creatureTable [ 3 ] )
end
local qualityok , quality = script.showListPrompt ( ' Wish ' , ' What quality should it be? ' , COLOR_LIGHTGREEN , qualityTable ( ) )
2015-08-02 08:07:57 -06:00
if not qualityok then return end
2014-06-26 06:36:57 -06:00
local description
if df.item_type [ itemtype ] == ' SLAB ' then
local descriptionok
descriptionok , description = script.showInputPrompt ( ' Slab ' , ' What should the slab say? ' , COLOR_WHITE )
2015-08-02 08:07:57 -06:00
if not descriptionok then return end
2014-06-26 06:36:57 -06:00
end
2014-08-16 06:45:49 -06:00
if args.multi then
repeat amountok , amount = script.showInputPrompt ( ' Wish ' , ' How many do you want? (numbers only!) ' , COLOR_LIGHTGREEN ) until tonumber ( amount )
2015-08-02 08:07:57 -06:00
if not amountok then return end
2015-04-23 19:11:13 -06:00
if mattype and itemtype then
if df.item_type . attrs [ itemtype ] . is_stackable then
local proper_item = df.item . find ( dfhack.items . createItem ( itemtype , itemsubtype , mattype , matindex , unit ) )
proper_item : setStackSize ( amount )
else
for i = 1 , amount do
dfhack.items . createItem ( itemtype , itemsubtype , mattype , matindex , unit )
2014-08-16 06:45:49 -06:00
end
end
2015-04-23 19:11:13 -06:00
return true
end
return false
2014-08-16 06:45:49 -06:00
else
if mattype and itemtype then
createItem ( { mattype , matindex } , { itemtype , itemsubtype } , quality , unit , description )
2015-04-23 19:11:13 -06:00
return true
2015-02-14 20:53:06 -07:00
end
2015-04-23 19:11:13 -06:00
return false
2014-06-26 06:36:57 -06:00
end
end )
end
2015-02-14 20:53:06 -07:00
2014-06-26 06:36:57 -06:00
scriptArgs = { ... }
2014-08-29 19:43:22 -06:00
utils = require ( ' utils ' )
2014-08-16 06:45:49 -06:00
validArgs = validArgs or utils.invert ( {
' startup ' ,
' all ' ,
' restrictive ' ,
' unit ' ,
' multi '
} )
2014-06-26 06:36:57 -06:00
2014-08-16 06:45:49 -06:00
args = utils.processArgs ( { ... } , validArgs )
2015-02-14 20:53:06 -07:00
2014-06-26 06:36:57 -06:00
eventful = require ( ' plugins.eventful ' )
2015-02-14 20:53:06 -07:00
if not args.startup then
2014-08-16 06:45:49 -06:00
local unit = args.unit and df.unit . find ( args.unit ) or dfhack.gui . getSelectedUnit ( true )
2014-09-08 18:00:49 -06:00
if unit then
hackWish ( unit )
else
2015-06-13 03:41:51 -06:00
qerror ( ' A unit needs to be selected to use gui/create-item. ' )
2014-09-08 18:00:49 -06:00
end
2014-06-26 06:36:57 -06:00
else
2014-08-16 06:45:49 -06:00
eventful.onReactionComplete . hackWishP = function ( reaction , unit , input_items , input_reagents , output_items , call_native )
2014-06-26 06:36:57 -06:00
if not reaction.code : find ( ' DFHACK_WISH ' ) then return nil end
hackWish ( unit )
end
2014-08-29 19:43:22 -06:00
end