--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 commands[commandCount] = args if args.onAttackStr then if not attackTriggers[args.onAttackStr] then attackTriggers[args.onAttackStr] = {} end table.insert(attackTriggers[args.onAttackStr],commandCount) end if args.onDefendStr then if not defendTriggers[args.onDefendStr] then defendTriggers[args.onDefendStr] = {} end table.insert(defendTriggers[args.onDefendStr],commandCount) end commandCount = commandCount+1