item-trigger: trigger scripts based on equipping items, unequipping items, and striking enemies with items. Select item by type, material, or by *contaminant* material.
parent
801d521093
commit
f58e659193
@ -1,127 +0,0 @@
|
|||||||
--attackTrigger.lua
|
|
||||||
--author expwnent
|
|
||||||
--triggers scripts when a unit attacks another with a weapon type, a weapon of a particular material
|
|
||||||
|
|
||||||
local eventful = require 'plugins.eventful'
|
|
||||||
local utils = require 'utils'
|
|
||||||
eventful.enableEvent(eventful.eventType.UNIT_ATTACK,1)
|
|
||||||
|
|
||||||
itemTriggers = itemTriggers or {}
|
|
||||||
materialTriggers = materialTriggers or {}
|
|
||||||
--itemMaterialTriggers = itemMaterialTriggers or {}
|
|
||||||
|
|
||||||
local function processTrigger(command, attacker, defender)
|
|
||||||
local command2 = {}
|
|
||||||
for i,arg in ipairs(command) do
|
|
||||||
if arg == '\\ATTACKER' then
|
|
||||||
command2[i] = '' .. attacker.id
|
|
||||||
elseif arg == '\\DEFENDER' then
|
|
||||||
command2[i] = '' .. defender.id
|
|
||||||
else
|
|
||||||
command2[i] = arg
|
|
||||||
end
|
|
||||||
end
|
|
||||||
print(dfhack.run_command(table.unpack(command2)))
|
|
||||||
end
|
|
||||||
|
|
||||||
eventful.onUnitAttack.attackTrigger = function(attacker,defender,wound)
|
|
||||||
attacker = df.unit.find(attacker)
|
|
||||||
defender = df.unit.find(defender)
|
|
||||||
|
|
||||||
if not attacker then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local attackerWeapon
|
|
||||||
for _,item in ipairs(attacker.inventory) do
|
|
||||||
if item.mode == df.unit_inventory_item.T_mode.Weapon then
|
|
||||||
attackerWeapon = item.item
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not attackerWeapon then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local weaponType = attackerWeapon.subtype.subtype --attackerWeapon.subtype.id
|
|
||||||
|
|
||||||
if itemTriggers[weaponType] then
|
|
||||||
for _,command in pairs(itemTriggers[weaponType]) do
|
|
||||||
processTrigger(command,attacker,defender)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- if materialTriggers[attackerWeapon.mat_type] and materialTriggers[attackerWeapon.mat_type][attackerWeapon.mat_index] then
|
|
||||||
if materialTriggers[attackerWeapon.mat_index] then
|
|
||||||
for _,command in pairs(materialTriggers[attackerWeapon.mat_index]) do
|
|
||||||
processTrigger(command,attacker,defender)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- if itemMaterialTriggers[weaponType] and itemMaterialTriggers[weaponType][attackerWeapon.mat_type] and itemMaterialTriggers[weaponType][attackerWeapon.mat_type][attackerWeapon.mat_index] then
|
|
||||||
-- for _,command in pairs(itemMaterialTriggers[weaponType][attackerWeapon.mat_type][attackerWeapon.mat_index]) do
|
|
||||||
-- processTrigger(command,attacker,defender)
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
end
|
|
||||||
|
|
||||||
local args = utils.processArgs(...)
|
|
||||||
|
|
||||||
if args.clear then
|
|
||||||
itemTriggers = {}
|
|
||||||
materialTriggers = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
if not args.command then
|
|
||||||
if not args.clear then
|
|
||||||
error 'specify a command'
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if args.weaponType then
|
|
||||||
local temp
|
|
||||||
for _,itemdef in ipairs(df.global.world.raws.itemdefs.weapons) do
|
|
||||||
if itemdef.id == args.weaponType then
|
|
||||||
temp = itemdef.subtype
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not temp then
|
|
||||||
error 'Could not find weapon type.'
|
|
||||||
end
|
|
||||||
args.weaponType = temp
|
|
||||||
end
|
|
||||||
|
|
||||||
if args.material then
|
|
||||||
local i = 0
|
|
||||||
while true do
|
|
||||||
local mat = dfhack.matinfo.decode(0,i)
|
|
||||||
if not mat then
|
|
||||||
error('Could not find material "' .. args.material .. '" after '..i..' materials.')
|
|
||||||
end
|
|
||||||
if mat.inorganic.id == args.material then
|
|
||||||
args.material = mat.index
|
|
||||||
break
|
|
||||||
end
|
|
||||||
i = i+1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if args.material and args.weaponType then
|
|
||||||
error 'both material and weaponType defined'
|
|
||||||
end
|
|
||||||
|
|
||||||
if args.material then
|
|
||||||
if not materialTriggers[args.material] then
|
|
||||||
materialTriggers[args.material] = {}
|
|
||||||
end
|
|
||||||
table.insert(materialTriggers[args.material],args.command)
|
|
||||||
elseif args.weaponType then
|
|
||||||
if not itemTriggers[args.weaponType] then
|
|
||||||
itemTriggers[args.weaponType] = {}
|
|
||||||
end
|
|
||||||
table.insert(itemTriggers[args.weaponType],args.command)
|
|
||||||
end
|
|
||||||
|
|
@ -0,0 +1,201 @@
|
|||||||
|
--attackTrigger.lua
|
||||||
|
--author expwnent
|
||||||
|
--based on itemsyndrome by Putnam
|
||||||
|
--triggers scripts when a unit attacks another with a weapon type, a weapon of a particular material
|
||||||
|
|
||||||
|
local eventful = require 'plugins.eventful'
|
||||||
|
local utils = require 'utils'
|
||||||
|
eventful.enableEvent(eventful.eventType.UNIT_ATTACK,1) -- this event type is cheap, so checking every tick is fine
|
||||||
|
eventful.enableEvent(eventful.eventType.INVENTORY_CHANGE,1000) --this is expensive, but you'll still want to set it lower
|
||||||
|
eventful.enableEvent(eventful.eventType.INVENTORY_CHANGE,1)
|
||||||
|
|
||||||
|
itemTriggers = itemTriggers or {}
|
||||||
|
materialTriggers = materialTriggers or {}
|
||||||
|
contaminantTriggers = contaminantTriggers or {}
|
||||||
|
|
||||||
|
function processTrigger(command)
|
||||||
|
local command2 = {}
|
||||||
|
for i,arg in ipairs(command.command) do
|
||||||
|
if arg == '\\ATTACKER_ID' then
|
||||||
|
command2[i] = '' .. command.attacker.id
|
||||||
|
elseif arg == '\\DEFENDER_ID' then
|
||||||
|
command2[i] = '' .. command.defender.id
|
||||||
|
elseif arg == '\\ITEM_MATERIAL' then
|
||||||
|
command2[i] = command.itemMat:getToken()
|
||||||
|
elseif arg == '\\ITEM_MATERIAL_TYPE' then
|
||||||
|
command2[i] = command.itemMat['type']
|
||||||
|
elseif arg == '\\ITEM_MATERIAL_INDEX' then
|
||||||
|
command2[i] = command.itemMat.index
|
||||||
|
elseif arg == '\\ITEM_ID' then
|
||||||
|
command2[i] = '' .. command.item.id
|
||||||
|
elseif arg == '\\ITEM_TYPE' then
|
||||||
|
command2[i] = command.itemType
|
||||||
|
elseif arg == '\\CONTAMINANT_MATERIAL' then
|
||||||
|
command2[i] = command.contaminantMat:getToken()
|
||||||
|
elseif arg == '\\CONTAMINANT_MATERIAL_TYPE' then
|
||||||
|
command2[i] = command.contaminantMat['type']
|
||||||
|
elseif arg == '\\CONTAMINANT_MATERIAL_INDEX' then
|
||||||
|
command2[i] = command.contaminantMat.index
|
||||||
|
elseif arg == '\\MODE' then
|
||||||
|
command2[i] = command.mode
|
||||||
|
elseif arg == '\\UNIT_ID' then
|
||||||
|
command2[i] = command.unit.id
|
||||||
|
elseif string.sub(arg,1,1) == '\\' then
|
||||||
|
command2[i] = string.sub(command,2)
|
||||||
|
else
|
||||||
|
command2[i] = arg
|
||||||
|
end
|
||||||
|
end
|
||||||
|
print(dfhack.run_command(table.unpack(command2)))
|
||||||
|
end
|
||||||
|
|
||||||
|
function fillTable(table1,table2)
|
||||||
|
for k,v in pairs(table2) do
|
||||||
|
table1[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function unfillTable(table1,table2)
|
||||||
|
for k,v in pairs(table2) do
|
||||||
|
table1[k] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function handler(table)
|
||||||
|
local itemMat = dfhack.matinfo.decode(table.item)
|
||||||
|
local itemMatStr = itemMat:getToken()
|
||||||
|
local itemType = dfhack.items.getSubtypeDef(table.item:getType(),table.item:getSubtype()).id
|
||||||
|
table.itemMat = itemMat
|
||||||
|
table.itemType = itemType
|
||||||
|
|
||||||
|
for _,command in ipairs(itemTriggers[itemType] or {}) do
|
||||||
|
if command[table.mode] then
|
||||||
|
print('asdf')
|
||||||
|
fillTable(command,table)
|
||||||
|
processTrigger(command)
|
||||||
|
unfillTable(command,table)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _,command in ipairs(materialTriggers[itemMatStr] or {}) do
|
||||||
|
if command[table.mode] then
|
||||||
|
print('asdf')
|
||||||
|
fillTable(command,table)
|
||||||
|
processTrigger(command)
|
||||||
|
unfillTable(command,table)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _,contaminant in ipairs(table.item.contaminants) do
|
||||||
|
local contaminantMat = dfhack.matinfo.decode(contaminant.mat_type, contaminant.mat_index)
|
||||||
|
local contaminantStr = contaminantMat:getToken()
|
||||||
|
table.contaminantMat = contaminantMat
|
||||||
|
for _,command in ipairs(contaminantTriggers[contaminantStr] or {}) do
|
||||||
|
print('asdf')
|
||||||
|
fillTable(command,table)
|
||||||
|
processTrigger(command)
|
||||||
|
unfillTable(command,table)
|
||||||
|
end
|
||||||
|
table.contaminantMat = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
eventful.onInventoryChange.equipmentTrigger = function(unit, item, item_old, item_new)
|
||||||
|
if item_old and item_new then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local isEquip = item_new and not item_old
|
||||||
|
local mode = (isEquip and 'onEquip') or (not isEquip and 'onUnequip')
|
||||||
|
local table = {}
|
||||||
|
table.mode = mode
|
||||||
|
table.item = df.item.find(item)
|
||||||
|
table.unit = unit
|
||||||
|
handler(table)
|
||||||
|
end
|
||||||
|
|
||||||
|
eventful.onUnitAttack.attackTrigger = function(attacker,defender,wound)
|
||||||
|
attacker = df.unit.find(attacker)
|
||||||
|
defender = df.unit.find(defender)
|
||||||
|
|
||||||
|
if not attacker then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local attackerWeapon
|
||||||
|
for _,item in ipairs(attacker.inventory) do
|
||||||
|
if item.mode == df.unit_inventory_item.T_mode.Weapon then
|
||||||
|
attackerWeapon = item.item
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not attackerWeapon then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local table = {}
|
||||||
|
table.attacker = attacker
|
||||||
|
table.defender = defender
|
||||||
|
table.item = attackerWeapon
|
||||||
|
table.mode = 'onStrike'
|
||||||
|
handler(table)
|
||||||
|
end
|
||||||
|
|
||||||
|
local args = utils.processArgs(...)
|
||||||
|
|
||||||
|
if args.clear then
|
||||||
|
itemTriggers = {}
|
||||||
|
materialTriggers = {}
|
||||||
|
contaminantTriggers = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
if args.checkEvery then
|
||||||
|
if not tonumber(args.checkEvery) then
|
||||||
|
error('checkEvery must be a number')
|
||||||
|
end
|
||||||
|
eventful.enableEvent(eventful.eventType.INVENTORY_CHANGE,tonumber(args.checkEvery))
|
||||||
|
end
|
||||||
|
|
||||||
|
if not args.command then
|
||||||
|
if not args.clear then
|
||||||
|
error 'specify a command'
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if args.weaponType then
|
||||||
|
local temp
|
||||||
|
for _,itemdef in ipairs(df.global.world.raws.itemdefs.weapons) do
|
||||||
|
if itemdef.id == args.weaponType then
|
||||||
|
temp = itemdef.subtype
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not temp then
|
||||||
|
error 'Could not find weapon type.'
|
||||||
|
end
|
||||||
|
args.weaponType = temp
|
||||||
|
end
|
||||||
|
|
||||||
|
if (args.material and 1) + (args.weaponType and 1) + (args.contaminant and 1) > 1 then
|
||||||
|
error 'too many conditions defined: not (yet) supported (pester expwnent if you want it)'
|
||||||
|
end
|
||||||
|
|
||||||
|
if args.material then
|
||||||
|
if not materialTriggers[args.material] then
|
||||||
|
materialTriggers[args.material] = {}
|
||||||
|
end
|
||||||
|
table.insert(materialTriggers[args.material],args)
|
||||||
|
elseif args.itemType then
|
||||||
|
if not itemTriggers[args.itemType] then
|
||||||
|
itemTriggers[args.itemType] = {}
|
||||||
|
end
|
||||||
|
table.insert(itemTriggers[args.itemType],args)
|
||||||
|
elseif args.contaminant then
|
||||||
|
if not contaminantTriggers[args.contaminant] then
|
||||||
|
contaminantTriggers[args.contaminant] = {}
|
||||||
|
end
|
||||||
|
table.insert(contaminantTriggers[args.contaminant],args)
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in New Issue