forked from DFHack/scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinteraction-trigger.lua
More file actions
176 lines (155 loc) · 5.04 KB
/
interaction-trigger.lua
File metadata and controls
176 lines (155 loc) · 5.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
-- triggers scripts based on unit interactions
--author expwnent
local help = [====[
modtools/interaction-trigger
============================
This triggers events when a unit uses an interaction on another. It works by
scanning the announcements for the correct attack verb, so the attack verb
must be specified in the interaction. It includes an option to suppress this
announcement after it finds it.
Usage::
-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.
]====]
local eventful = require 'plugins.eventful'
local utils = require 'utils'
attackTriggers = attackTriggers or {} --as:number[][]
defendTriggers = defendTriggers or {} --as:number[][]
commands = commands or {} --as:{_type:table,_array:{_type:table,onAttackStr:string,onDefendStr:string,command:'string[]',suppressAttack:bool,suppressDefend:bool}}
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 = {} --as:string[]
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,tostring(args.attackerId))
elseif arg == '\\DEFENDER_ID' then
table.insert(command,tostring(args.defenderId))
elseif arg == '\\ATTACK_REPORT' then
table.insert(command,tostring(args.attackReport))
elseif arg == '\\DEFEND_REPORT' then
table.insert(command,tostring(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 suppressAttack = false
local suppressDefend = false
local todo = {} --as:bool[]
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
local command = commands[k]
suppressAttack = suppressAttack or command.suppressAttack
suppressDefend = suppressDefend or command.suppressDefend
command.attackVerb = attackVerb
command.defendVerb = defendVerb
command.attackReport = attackReport
command.defendReport = defendReport
command.attackerId = attacker
command.defenderId = defender
processTrigger(command)
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)) --luacheck: retype
defender = df.unit.find(tonumber(defender)) --luacheck: retype
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
local validArgs = utils.invert({
'clear',
'help',
'onAttackStr',
'onDefendStr',
'command',
'suppressAttack',
'suppressDefend',
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print(help)
return
end
if args.clear then
attackTriggers = {}
defendTriggers = {}
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