dfhack/scripts/modtools/interaction-trigger.lua

169 lines
4.7 KiB
Lua

--scripts/modtools/interaction-trigger.lua
--author expwnent
--triggers scripts when a unit does a unit interaction on another
local eventful = require 'plugins.eventful'
local utils = require 'utils'
attackTriggers = attackTriggers or {}
defendTriggers = defendTriggers or {}
commands = commands or {}
commandCount = commandCount or 0
eventful.enableEvent(eventful.eventType.INTERACTION,1) --cheap, so every tick is fine
eventful.enableEvent(eventful.eventType.UNLOAD,1)
eventful.onUnload.interactionTrigger = function()
attackTriggers = {}
defendTriggers = {}
commands = {}
commandCount = 0
end
local function processTrigger(args)
local command = {}
for _,arg in ipairs(args.command) do
if arg == '\\ATTACK_VERB' then
table.insert(command,args.attackVerb)
elseif arg == '\\DEFEND_VERB' then
table.insert(command,args.defendVerb)
elseif arg == '\\ATTACKER_ID' then
table.insert(command,args.attackerId)
elseif arg == '\\DEFENDER_ID' then
table.insert(command,args.defenderId)
elseif arg == '\\ATTACK_REPORT' then
table.insert(command,args.attackReport)
elseif arg == '\\DEFEND_REPORT' then
table.insert(command,args.defendReport)
elseif string.sub(arg,1,1) == '\\' then
table.insert(command,string.sub(arg,2))
else
table.insert(command,arg)
end
end
dfhack.run_command(table.unpack(command))
end
eventful.onInteraction.interactionTrigger = function(attackVerb, defendVerb, attacker, defender, attackReport, defendReport)
local extras = {}
extras.attackVerb = attackVerb
extras.defendVerb = defendVerb
extras.attackReport = attackReport
extras.defendReport = defendReport
extras.attackerId = attacker
extras.defenderId = defender
local suppressAttack = false
local suppressDefend = false
local todo = {}
for _,trigger in ipairs(attackTriggers[attackVerb] or {}) do
todo[trigger] = true
end
for _,trigger in ipairs(defendTriggers[defendVerb] or {}) do
todo[trigger] = true
end
for k,v in pairs(todo) do
command = commands[k]
suppressAttack = suppressAttack or command.suppressAttack
suppressDefend = suppressDefend or command.suppressDefend
utils.fillTable(command,extras)
processTrigger(command)
utils.unfillTable(command,extras)
end
local eraseReport = function(unit,report)
for i,v in ipairs(unit.reports.log.Combat) do
if v == report then
unit.reports.log.Combat:erase(i)
break
end
end
end
if suppressAttack or suppressDefend then
attacker = df.unit.find(tonumber(attacker))
defender = df.unit.find(tonumber(defender))
end
if suppressAttack then
eraseReport(attacker,attackReport)
eraseReport(defender,attackReport)
end
if suppressDefend then
eraseReport(attacker,defendReport)
eraseReport(defender,defendReport)
end
--TODO: get rid of combat report on LHS of screen
end
----------------------------------------------------
--argument processing
validArgs = validArgs or utils.invert({
'clear',
'help',
'onAttackStr',
'onDefendStr',
'command',
'suppressAttack',
'suppressDefend',
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print([[scripts/modtools/interaction-trigger.lua
arguments:
-help
print this help message
-clear
unregisters all triggers
-onAttackStr str
trigger the command when the attack verb is "str". both onAttackStr and onDefendStr MUST be specified
-onDefendStr str
trigger the command when the defend verb is "str". both onAttackStr and onDefendStr MUST be specified
-suppressAttack
delete the attack announcement from the combat logs
-suppressDefend
delete the defend announcement from the combat logs
-command [ commandStrs ]
specify the command to be executed
commandStrs
\\ATTACK_VERB
\\DEFEND_VERB
\\ATTACKER_ID
\\DEFENDER_ID
\\ATTACK_REPORT
\\DEFEND_REPORT
\\anything -> \anything
anything -> anything
You must specify both an attack string and a defend string to guarantee correct performance. Either will trigger the script when it happens, but it will not be triggered twice in a row if both happen.
]])
return
end
if args.clear then
triggers = {}
commands = {}
commandCount = 0
end
if not args.command then
return
end
if not args.onAttackStr or not args.onDefendStr then
error 'You must specify both onAttackStr and onDefendStr.'
end
commands[commandCount] = args
if not attackTriggers[args.onAttackStr] then
attackTriggers[args.onAttackStr] = {}
end
table.insert(attackTriggers[args.onAttackStr],commandCount)
if not defendTriggers[args.onDefendStr] then
defendTriggers[args.onDefendStr] = {}
end
table.insert(defendTriggers[args.onDefendStr],commandCount)
commandCount = commandCount+1