Merge remote-tracking branch 'PeridexisErrant/item-info' into develop

develop
lethosor 2015-04-18 17:56:32 -04:00
commit 1a23ce136a
5 changed files with 488 additions and 0 deletions

@ -6,6 +6,7 @@ DFHack Future
New internal commands New internal commands
New plugins New plugins
New scripts New scripts
view-item-info: adds information and customisable descriptions to item viewscreens
New tweaks New tweaks
New features New features
Fixes Fixes

@ -2573,6 +2573,17 @@ undump-buildings
================ ================
Undesignates building base materials for dumping. Undesignates building base materials for dumping.
view-item-info
==============
A script to extend the item or unit viewscreen with additional information
including a custom description of each item (when available), and properties
such as material statistics, weapon attacks, armor effectiveness, and more.
The associated script ``item-descriptions.lua`` supplies custom descriptions
of items. Individual descriptions can be added or overridden by a similar
script ``raw/scripts/more-item-descriptions.lua``. Both work as sparse lists,
so missing items simply go undescribed if not defined in the fallback.
======== ========
modtools modtools
======== ========

@ -229,6 +229,9 @@ soundsense-season
# write identifying information about the fort to gamelog on world load # write identifying information about the fort to gamelog on world load
log-region log-region
# add information to item viewscreens
view-item-info
####################################################### #######################################################
# Apply binary patches at runtime # # Apply binary patches at runtime #
####################################################### #######################################################

@ -0,0 +1,93 @@
-- Holds custom descriptions for view-item-info
-- By PeridexisErrant
if not moduleMode then
print("scripts/item-descriptions.lua is a content library; calling it does nothing.")
end
--[[
This script has a single function: to return a custom description for every
vanilla item in the game.
Having this as a separate script to "view-item-info.lua" allows either mods
to partially or fully replace the content.
If "raw/scripts/item-descriptions.lua" exists, it will entirely replace this one.
Instead, use "raw/scripts/more-item-descriptions.lua" to add content, or replace
descriptions on a case-by-case basis. If an item description cannot be found in
the latter script, view-item-info will fall back to the former.
Lines should be about 70 characters for consistent presentation and to fit
on-screen. Logical sections can be separated by an empty line ("").
Text blocks should use identical indentation to make formatting clearly visible.
All described vanilla item IDs:
"ANVIL", "ARMORSTAND", "BARREL", "BED", "BIN", "BLOCKS", "BOX", "BUCKET", "ITEM_AMMO_ARROWS", "ITEM_AMMO_BOLTS", "ITEM_ARMOR_LEATHER", "ITEM_WEAPON_PICK", "ITEM_WEAPON_AXE_BATTLE", "ITEM_WEAPON_AXE_TRAINING", "SLAB", "TRAPPARTS"
Remaining item IDs:
"AMULET", "ANIMALTRAP", "BACKPACK", "BALLISTAARROWHEAD", "BALLISTAPARTS", "BAR", "BOOK", "BOULDER", "BRACELET", "CABINET", "CAGE", "CATAPULTPARTS", "CHAIN", "CHAIR", "CLOTH", "COFFIN", "COIN", "CROWN", "CRUTCH", "DOOR", "EARRING", "FIGURINE", "FLASK", "FLOODGATE", "GOBLET", "GRATE", "HATCH_COVER", "ITEM_ARMOR_BREASTPLATE", "ITEM_ARMOR_CAPE", "ITEM_ARMOR_CLOAK", "ITEM_ARMOR_COAT", "ITEM_ARMOR_DRESS", "ITEM_ARMOR_MAIL_SHIRT", "ITEM_ARMOR_ROBE", "ITEM_ARMOR_SHIRT", "ITEM_ARMOR_TOGA", "ITEM_ARMOR_TUNIC", "ITEM_ARMOR_VEST", "ITEM_FOOD_BISCUITS", "ITEM_FOOD_ROAST", "ITEM_FOOD_STEW", "ITEM_GLOVES_GAUNTLETS", "ITEM_GLOVES_GLOVES", "ITEM_GLOVES_MITTENS", "ITEM_HELM_CAP", "ITEM_HELM_HELM", "ITEM_HELM_HOOD", "ITEM_HELM_MASK", "ITEM_HELM_SCARF_HEAD", "ITEM_HELM_TURBAN", "ITEM_HELM_VEIL_FACE", "ITEM_HELM_VEIL_HEAD", "ITEM_INSTRUMENT_DRUM", "ITEM_INSTRUMENT_FLUTE", "ITEM_INSTRUMENT_HARP", "ITEM_INSTRUMENT_PICCOLO", "ITEM_INSTRUMENT_TRUMPET", "ITEM_PANTS_BRAIES", "ITEM_PANTS_GREAVES", "ITEM_PANTS_LEGGINGS", "ITEM_PANTS_LOINCLOTH", "ITEM_PANTS_PANTS", "ITEM_PANTS_SKIRT", "ITEM_PANTS_SKIRT_LONG", "ITEM_PANTS_SKIRT_SHORT", "ITEM_PANTS_THONG", "ITEM_SHIELD_BUCKLER", "ITEM_SHIELD_SHIELD", "ITEM_SHOES_BOOTS", "ITEM_SHOES_BOOTS_LOW", "ITEM_SHOES_CHAUSSE", "ITEM_SHOES_SANDAL", "ITEM_SHOES_SHOES", "ITEM_SHOES_SOCKS", "ITEM_SIEGEAMMO_BALLISTA", "ITEM_TOOL_BOWL", "ITEM_TOOL_CAULDRON", "ITEM_TOOL_FORK_CARVING", "ITEM_TOOL_HIVE", "ITEM_TOOL_HONEYCOMB", "ITEM_TOOL_JUG", "ITEM_TOOL_KNIFE_BONING", "ITEM_TOOL_KNIFE_CARVING", "ITEM_TOOL_KNIFE_MEAT_CLEAVER", "ITEM_TOOL_KNIFE_SLICING", "ITEM_TOOL_LADLE", "ITEM_TOOL_LARGE_POT", "ITEM_TOOL_MINECART", "ITEM_TOOL_MORTAR", "ITEM_TOOL_NEST_BOX", "ITEM_TOOL_PESTLE", "ITEM_TOOL_POUCH", "ITEM_TOOL_SCALE_SHARD", "ITEM_TOOL_STEPLADDER", "ITEM_TOOL_WHEELBARROW", "ITEM_TOY_AXE", "ITEM_TOY_BOAT", "ITEM_TOY_HAMMER", "ITEM_TOY_MINIFORGE", "ITEM_TOY_PUZZLEBOX", "ITEM_TRAPCOMP_ENORMOUSCORKSCREW", "ITEM_TRAPCOMP_GIANTAXEBLADE", "ITEM_TRAPCOMP_LARGESERRATEDDISC", "ITEM_TRAPCOMP_MENACINGSPIKE", "ITEM_TRAPCOMP_SPIKEDBALL", "ITEM_WEAPON_AXE_GREAT", "ITEM_WEAPON_BLOWGUN", "ITEM_WEAPON_BOW", "ITEM_WEAPON_CROSSBOW", "ITEM_WEAPON_DAGGER_LARGE", "ITEM_WEAPON_FLAIL", "ITEM_WEAPON_HALBERD", "ITEM_WEAPON_HAMMER_WAR", "ITEM_WEAPON_MACE", "ITEM_WEAPON_MAUL", "ITEM_WEAPON_MORNINGSTAR", "ITEM_WEAPON_PIKE", "ITEM_WEAPON_SCIMITAR", "ITEM_WEAPON_SCOURGE", "ITEM_WEAPON_SPEAR", "ITEM_WEAPON_SPEAR_TRAINING", "ITEM_WEAPON_SWORD_2H", "ITEM_WEAPON_SWORD_LONG", "ITEM_WEAPON_SWORD_SHORT", "ITEM_WEAPON_SWORD_SHORT_TRAINING", "ITEM_WEAPON_WHIP", "MEAT", "MILLSTONE", "ORTHOPEDIC_CAST", "PIPE_SECTION", "QUERN", "QUIVER", "RING", "ROCK", "ROUGH", "SCEPTER", "SKIN_TANNED", "SMALLGEM", "SPLINT", "STATUE", "TABLE", "THREAD", "TOTEM", "TRACTION_BENCH", "WEAPONRACK", "WINDOW", "WOOD"
]]
descriptions = {
ANVIL = { "An essential component of the forge."},
ARMORSTAND = {
"A rack for the storage of military equipment, specifically armor.",
"It is required by some nobles, and can be used to create a barracks."},
BARREL = { "A hollow cylinder with a removable lid. It is used to hold liquids,",
"food, and seeds. It can be made from metal or wood, and is replaceable",
"with a rock pot. A barrel (or rock pot) is needed to brew drinks."},
BED = { "A pallet for dwarves to sleep on, which must be made from wood.",
"It prevents the stress of sleeping on the ground, and can be used",
"to designate a bedroom (used by one dwarf or couple), a dormitory",
"(used by multiple dwarves), or a barracks (used by a military",
"squad for training or sleep)."},
BIN = { "A container for the storage of ammunition, armor and weapons, bars,",
"blocks, cloth and leather, coins, finished goods and gems. It can",
"be used to carry multiple items to the Trade Depot at once.",
"A bin can be made from wood or forged from metal."},
BLOCKS = { "Blocks can be used for constructions in place of raw materials such",
"as logs or bars. Cutting boulders into blocks gives four times as",
"many items, all of which are lighter for faster hauling and yield",
"smooth constructions."},
BOX = { "A container for storing dwarves' items. They are required by nobles,",
"and will increase the value of rooms they are placed in. Also",
"required to store hospital supplies. They can be made from stone or",
"metal (coffers), wood (chests),or textiles or leather (bags)."},
BUCKET = { "A small cylindrical or conical container for holding and carrying",
"small amounts of liquid such as water or lye. They are used by",
"dwarves to give water to other dwarves, to store lye, and are",
"required to build wells and certain workshops. They can be made",
"from wood or metal."},
ITEM_AMMO_ARROWS = {
"Ammunition for bows, which are primarily used by elves."},
ITEM_AMMO_BOLTS = {
"Ammunition for crossbows, which are a dwarf's preferred ranged weapon.",
"It is not recommended to store bolts in bins, due to pickup bugs."},
ITEM_ARMOR_LEATHER = {
"Leather armor is light and covers both arms and legs",
"in addition to body"},
ITEM_WEAPON_PICK = {
"The most important item for a beginning fortress, a pick can",
"get a party underground. Also crucial mining for stone or",
"metals, expansion of living space, and so on.", "",
"A pick is also useful as a weapon, though putting miners in the",
"military causes equipment clashes."},
ITEM_WEAPON_AXE_BATTLE = {
"A battle axe is an edged weapon: essentially a sharp blade",
"mounted along the end of a short and heavy handle.", "",
"Dwarves can forge battle axes out of any weapon-grade metal,",
"though those with superior edge properties are more effective.", "",
"A battle axe may also be used as a tool for chopping down trees."},
ITEM_WEAPON_AXE_TRAINING = {
"As a battleaxe made from wood, this practise weapon is useful for",
"training recruits. Thanks to good craftsdwarfship, it can also",
"be used to cut down trees."},
SLAB = { "A memorial stone, used to quiet restless ghost when engraved with",
"the name of the deceased and built."},
TRAPPARTS = {
"Used to build traps, levers and other machines."}
}

@ -0,0 +1,380 @@
-- Extended Item Viewscreens
-- Shows information on material properties, weapon or armour stats, and more.
-- By PeridexisErrant, adapted from nb_item_info by Raidau
local help = [[Extended Item Viewscreen
A script to extend the item or unit viewscreen with additional information
including properties such as material info, weapon and attack properties,
armor thickness and coverage, and more - including custom item descriptions.]]
function isInList(list, item)
for k,v in pairs (list) do
if item == v then
return true
end
end
end
local args = {...}
local lastframe = df.global.enabler.frame_last
if isInList(args, "help") or isInList(args, "?") then
print(help) return
end
print ("view-item-info enabled")
function append (list, str, indent)
local str = str or " "
local indent = indent or 0
table.insert(list, {str, indent * 4})
end
function add_lines_to_list(t1,t2)
for i=1,#t2 do
t1[#t1+1] = t2[i]
end
return t1
end
function GetMatPlant (item)
if dfhack.matinfo.decode(item).mode == "plant" then
return dfhack.matinfo.decode(item).plant
end
end
function get_textid (item)
return string.match(tostring(item._type),"<type: item_(.+)st>"):upper()
end
function compare_iron (mat_prop, iron_prop)
return " "..mat_prop.." ("..math.floor(mat_prop/iron_prop*100).."% of iron)"
end
function GetMatPropertiesStringList (item)
local mat = dfhack.matinfo.decode(item).material
local list = {}
local deg_U = item.temperature.whole
local deg_C = math.floor((deg_U-10000)*5/9)
append(list,"Temperature: "..deg_C.."\248C ("..deg_U.."U)")
append(list,"Color: "..df.global.world.raws.language.colors[mat.state_color.Solid].name)
local function GetStrainDescription (number)
if tonumber(number) >= 50000 then return "very elastic"
elseif tonumber(number) < 50000 then return "elastic"
elseif tonumber(number) < 15001 then return "medium"
elseif tonumber(number) < 5001 then return "stiff"
elseif tonumber(number) < 1000 then return "very stiff"
elseif tonumber(number) < 1 then return "crystalline"
else return "unknown" end
end
local mat_properties_for = {"BAR", "SMALLGEM", "BOULDER", "ROUGH",
"WOOD", "GEM", "ANVIL", "THREAD", "SHOES", "CLOTH", "ROCK", "WEAPON", "TRAPCOMP",
"ORTHOPEDIC_CAST", "SIEGEAMMO", "SHIELD", "PANTS", "HELM", "GLOVES", "ARMOR", "AMMO"}
if isInList(mat_properties_for, get_textid (item)) then
append(list,"Material name: "..mat.state_name.Solid)
append(list,"Material properties: ")
append(list,"Solid density: "..mat.solid_density..'g/cm^3',1)
local maxedge = mat.strength.max_edge
append(list,"Maximum sharpness: "..maxedge.." ("..maxedge/standard.strength.max_edge*100 .."%)",1)
if mat.molar_mass > 0 then
append(list,"Molar mass: "..mat.molar_mass,1)
end
append(list,"Shear strength:",1)
append(list, "yield:"..compare_iron(mat.strength.yield.SHEAR, standard.strength.yield.SHEAR), 2)
append(list, "fracture:"..compare_iron(mat.strength.fracture.SHEAR, standard.strength.fracture.SHEAR), 2)
local s_strain = mat.strength.strain_at_yield.SHEAR
append(list, "elasticity: "..s_strain.." ("..GetStrainDescription(s_strain)..")", 2)
append(list,"Impact strength:",1)
append(list, "yield:"..compare_iron(mat.strength.yield.IMPACT, standard.strength.yield.IMPACT), 2)
append(list, "fracture:"..compare_iron(mat.strength.fracture.IMPACT, standard.strength.fracture.IMPACT), 2)
local i_strain = mat.strength.strain_at_yield.IMPACT
append(list, "elasticity: "..i_strain.." ("..GetStrainDescription(i_strain)..")", 2)
end
append(list)
return list
end
function GetArmorPropertiesStringList (item)
local mat = dfhack.matinfo.decode(item).material
local list = {}
append(list,"Armor properties: ")
append(list,"Thickness: "..item.subtype.props.layer_size,1)
append(list,"Coverage: "..item.subtype.props.coverage.."%",1)
append(list,"Fit for "..df.creature_raw.find(item.maker_race).name[0],1)
append(list)
return list
end
function GetShieldPropertiesStringList (item)
local mat = dfhack.matinfo.decode(item).material
local list = {}
append(list,"Shield properties:")
append(list,"Base block chance: "..item.subtype.blockchance,1)
append(list,"Fit for "..df.creature_raw.find(item.maker_race).name[0],1)
append(list)
return list
end
function GetWeaponPropertiesStringList (item)
local mat = dfhack.matinfo.decode(item).material
local list = {}
append(list)
if item._type == df.item_toolst and #item.subtype.attacks < 1 then
return list
end
append(list,"Weapon properties: ")
if item.sharpness > 0 then
append(list,"Sharpness:"..compare_iron(item.sharpness, standard.strength.max_edge),1)
else
append(list,"Not edged",1)
end
if string.len(item.subtype.ranged_ammo) > 0 then
append(list,"Ranged weapon",1)
append(list,"Ammo: "..item.subtype.ranged_ammo:lower(),2)
if item.subtype.shoot_force > 0 then
append(list,"Shoot force: "..item.subtype.shoot_force,2)
end
if item.subtype.shoot_maxvel > 0 then
append(list,"Maximum projectile velocity: "..item.subtype.shoot_maxvel,2)
end
end
append(list,"Required size: "..item.subtype.minimum_size*10,1)
if item.subtype.two_handed*10 > item.subtype.minimum_size*10 then
append(list,"Used as 2-handed until unit size: "..item.subtype.two_handed*10,2)
end
append(list,"Attacks: ",1)
for k,attack in pairs (item.subtype.attacks) do
local name = attack.verb_2nd
if attack.noun ~= "NO_SUB" then
name = name.." with "..attack.noun
end
if attack.edged then
name = name.." (edged)"
else
name = name.." (blunt)"
end
append(list,name,2)
append(list,"Contact area: "..attack.contact,3)
if attack.edged then
append(list,"Penetration: "..attack.penetration,3)
end
append(list,"Velocity multiplier: "..attack.velocity_mult/1000,3)
if attack.flags.bad_multiattack then
append(list,"Bad multiattack",3)
end
append(list,"Prepare "..attack.prepare.." / recover "..attack.recover,3)
end
append(list)
return list
end
function GetAmmoPropertiesStringList (item)
local mat = dfhack.matinfo.decode(item).material
local list = {}
append(list)
if item._type == df.item_toolst and #item.subtype.attacks < 1 then
return list
end
append(list,"Ammo properties: ")
if item.sharpness > 0 then
append(list,"Sharpness: "..item.sharpness,1)
else
append(list,"Not edged",1)
end
append(list,"Attacks: ", 1)
for k,attack in pairs (item.subtype.attacks) do
local name = attack.verb_2nd
if attack.noun ~= "NO_SUB" then
name = name.." with "..attack.noun
end
if attack.edged then
name = name.." (edged)"
else
name = name.." (blunt)"
end
append(list,name,2)
append(list,"Contact area: "..attack.contact,3)
if attack.edged then
append(list,"Penetration: "..attack.penetration,3)
end
append(list,"Velocity multiplier: "..attack.velocity_mult/1000,3)
if attack.flags.bad_multiattack then
append(list,"Bad multiattack",3)
end
append(list,"Prepare "..attack.prepare.." / recover "..attack.recover,3)
end
append(list)
return list
end
function edible_string (mat)
local edible_string = "Edible"
if mat.flags.EDIBLE_RAW or mat.flags.EDIBLE_COOKED then
if mat.flags.EDIBLE_RAW then
edible_string = edible_string.." raw"
if mat.flags.EDIBLE_COOKED then
edible_string = edible_string.." and cooked"
end
elseif mat.flags.EDIBLE_COOKED then
edible_string = edible_string.." only when cooked"
end
else
edible_string = "Not edible"
end
return edible_string
end
function GetReactionProduct (inmat, reaction)
for k,v in pairs (inmat.reaction_product.id) do
if v.value == reaction then
return {inmat.reaction_product.material.mat_type[k],
inmat.reaction_product.material.mat_index[k]}
end
end
end
function add_react_prod (list, mat, product, str)
local mat_type, mat_index = GetReactionProduct (mat, product)
if mat_type then
local result = dfhack.matinfo.decode(mat_type, mat_index).material.state_name.Liquid
append(list, str..result)
end
end
function get_plant_reaction_products (mat)
local list = {}
add_react_prod (list, mat, "DRINK_MAT", "Used to brew ")
add_react_prod (list, mat, "GROWTH_JUICE_PROD", "Pressed into ")
add_react_prod (list, mat, "PRESS_LIQUID_MAT", "Pressed into ")
add_react_prod (list, mat, "LIQUID_EXTRACTABLE", "Extractable product: ")
add_react_prod (list, mat, "WATER_SOLUTION_PROD", "Can be mixed with water to make ")
add_react_prod (list, mat, "RENDER_MAT", "Rendered into ")
add_react_prod (list, mat, "SOAP_MAT", "Used to make soap")
if GetReactionProduct (mat, "SUGARABLE") then
append(list,"Used to make sugar")
end
if GetReactionProduct (mat, "MILLABLE") or
GetReactionProduct (mat, "GRAIN_MILLABLE") or
GetReactionProduct (mat, "GROWTH_MILLABLE") then
append(list,"Can be milled")
end
if GetReactionProduct(mat, "GRAIN_THRESHABLE") then
append(list,"Grain can be threshed")
end
if GetReactionProduct (mat, "CHEESE_MAT") then
local mat_type, mat_index = GetReactionProduct (mat, "CHEESE_MAT")
append(list,"Used to make "..dfhack.matinfo.decode(mat_type, mat_index).material.state_name.Solid)
end
return list
end
function GetFoodPropertiesStringList (item)
local mat = dfhack.matinfo.decode(item).material
local list = {{" ", 0}}
append(list,edible_string(mat))
if item._type == df.item_foodst then
append(list,"This is prepared meal")
append(list)
return list
end
if mat == dfhack.matinfo.find ("WATER") then
append(list,"Water is drinkable")
append(list)
return list
end
add_lines_to_list(list, get_plant_reaction_products(mat))
if item._type == df.item_plantst and GetMatPlant (item) then
local plant = GetMatPlant (item)
for k,v in pairs (plant.material_defs) do
if v ~= -1 and string.find (k,"type_") and not string.find (k,"type_basic")
or string.find (k,"type_seed") or string.find (k,"type_tree") then
local targetmat = dfhack.matinfo.decode (v,
plant.material_defs["idx_"..string.match (k,"type_(.+)")])
local state = "Liquid"
if string.find (k,"type_mill") then state = "Powder"
elseif string.find (k,"type_thread") then state = "Solid" end
local st_name = targetmat.material.state_name[state]
append(list,"Used to make "..targetmat.material.prefix..''..st_name)
end
end
end
append(list)
return list
end
function get_all_uses_strings (item)
local all_lines = {}
local FoodsAndPlants = {df.item_meatst, df.item_globst,
df.item_plantst, df.item_plant_growthst, df.item_liquid_miscst,
df.item_powder_miscst, df.item_cheesest, df.item_foodst}
local ArmourTypes = {df.item_armorst, df.item_pantsst,
df.item_helmst, df.item_glovesst, df.item_shoesst}
if df.global.gamemode == df.game_mode.ADVENTURE and item ~= "COIN" then
add_lines_to_list(all_lines, {{"Value: "..dfhack.items.getValue(item),0}})
elseif isInList(ArmourTypes, item._type) then
add_lines_to_list(all_lines, GetArmorPropertiesStringList(item))
elseif item._type == df.item_weaponst or item._type == df.item_toolst then
add_lines_to_list(all_lines, GetWeaponPropertiesStringList(item))
elseif item._type == df.item_ammost then
add_lines_to_list(all_lines, GetAmmoPropertiesStringList(item))
elseif item._type == df.item_shieldst then
add_lines_to_list(all_lines, GetShieldPropertiesStringList(item))
elseif item._type == df.item_seedsst then
local str = math.floor(GetMatPlant(item).growdur/12).." days"
add_lines_to_list(all_lines, {{"Growth time: "..str, 0}})
elseif isInList(FoodsAndPlants, item._type) then
add_lines_to_list(all_lines, GetFoodPropertiesStringList(item))
end
if not dfhack.items.isCasteMaterial(df.item_type[get_textid(item)]) then
add_lines_to_list(all_lines, GetMatPropertiesStringList(item))
end
return all_lines
end
function get_custom_item_desc (item)
local desc
local ID = get_textid (item)
if ID and dfhack.items.getSubtypeCount(df.item_type[ID]) ~= -1 then
ID = item.subtype.id end
if not ID then return nil end
if dfhack.findScript("item-descriptions") then
local desc = dfhack.script_environment("item-descriptions").descriptions.ID
end
if dfhack.findScript("more-item-descriptions") then
local desc = dfhack.script_environment("more-item-descriptions").descriptions.ID or desc
end
if desc then add_lines_to_list(desc, {""}) end
return desc
end
function AddUsesString (viewscreen,line,indent)
local str = df.new("string")
str.value = tostring(line)
local indent = indent or 0
viewscreen.entry_ref:insert('#', nil)
viewscreen.entry_indent:insert('#', indent)
viewscreen.unk_34:insert('#', nil) -- TODO: get this into structures, and fix usage!
viewscreen.entry_string:insert('#', str)
viewscreen.entry_reaction:insert('#', -1)
end
function dfhack.onStateChange.item_info (code)
if code == SC_VIEWSCREEN_CHANGED and dfhack.isWorldLoaded() then
standard = dfhack.matinfo.find("INORGANIC:IRON").material
if not standard then return end
local scr = dfhack.gui.getCurViewscreen()
if scr._type == df.viewscreen_itemst then
if #scr.entry_string > 0 and scr.entry_string[#scr.entry_string-1].value == " " then
return
end
local description = get_custom_item_desc (scr.item) or ""
for i = 1, #description do
AddUsesString(scr,description[i])
end
local all_lines = get_all_uses_strings (scr.item)
for i = 1, #all_lines do
AddUsesString(scr,all_lines[i][1],all_lines[i][2])
end
scr.caption_uses = true
end
end
end