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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
---------------------------------------------------------------------------
-- runrest.lua:
-- Controls shift-running and resting stop conditions.
--
-- To use this, add this line to your init.txt:
-- lua_file = lua/runrest.lua
--
-- What it does:
--
-- * Any message in runrest_ignore_message will *not* stop your run.
-- * Poison damage of x will be ignored if you have at least y hp if you've
-- defined a runrest_ignore_poison = x:y option.
-- * Any monster in runrest_ignore_monster will *not* stop your run
-- if it's at least the specified distance away.
-- You can specify this with runrest_ignore_monster = regex:distance.
--
-- IMPORTANT: You must define runrest_ options *after* sourcing runrest.lua.
---------------------------------------------------------------------------
g_rr_ignored = { }
chk_interrupt_activity.run = function (iname, cause, extra)
if not rr_check_params() then
return false
end
if iname == 'message' then
return rr_handle_message(cause, extra)
end
if iname == 'hp_loss' then
return rr_handle_hploss(cause, extra)
end
return false
end
-- run no longer automatically implies rest as of 0.1.3.
chk_interrupt_activity.rest = chk_interrupt_activity.run
chk_interrupt_activity.travel = chk_interrupt_activity.run
function rr_handle_message(cause, extra)
local ch, mess = rr_split_channel(cause)
for _, m in ipairs(g_rr_ignored) do
if m:matches(mess, ch) then
return nil
end
end
return false
end
function rr_split_channel(s)
local chi = string.find(s, ':')
local channel = -1
if chi and chi > 1 then
local chstr = string.sub(s, 1, chi - 1)
channel = crawl.msgch_num(chstr)
end
local sor = s
if chi then
s = string.sub(s, chi + 1, -1)
end
return channel, s
end
function rr_handle_hploss(hplost, source)
-- source == 1 for poisoning
if not g_rr_yhpmin or not g_rr_hplmax or source ~= 1 then
return false
end
-- If the hp lost is smaller than configured, and you have more than the
-- minimum health, ignore this poison event.
if hplost <= g_rr_hplmax and you.hp() >= g_rr_yhpmin then
return nil
end
return false
end
function rr_check_params()
if g_rrim ~= options.runrest_ignore_message then
g_rrim = options.runrest_ignore_message
rr_add_messages(nil, g_rrim)
end
if ( not g_rr_hplmax or not g_rr_yhpmin )
and options.runrest_ignore_poison
then
local opt = options.runrest_ignore_poison
local hpl, hpm
_, _, hpl, hpm = string.find(opt, "(%d+)%s*:%s*(%d+)")
if hpl and hpm then
g_rr_hplmax = tonumber(hpl)
g_rr_yhpmin = tonumber(hpm)
end
end
return true
end
function rr_add_message(s)
local channel, str = rr_split_channel(s)
table.insert( g_rr_ignored, crawl.message_filter( str, channel ) )
end
function rr_add_messages(key, value)
local segs = crawl.split(value, ',')
for _, s in ipairs(segs) do
rr_add_message(s)
end
end
chk_lua_option.runrest_ignore_message = rr_add_messages
-----------------------------------------------------------------------
g_rr_monsters = { {}, {} }
g_rr_monsters_moving = { {}, {} }
function rr_add_monster(mons_table, s)
local parts = crawl.split(s, ":")
if #parts ~= 2 then
return
end
local regexp = parts[1]
local dist = tonumber(parts[2])
if dist == 0 then
return
end
table.insert( mons_table[1], crawl.regex( regexp ) )
table.insert( mons_table[2], dist )
end
function rr_add_monsters(key, value)
local mons_table
if (key == "runrest_ignore_monster") then
mons_table = g_rr_monsters
elseif (key == "runrest_ignore_monster_moving") then
mons_table = g_rr_monsters_moving
else
return
end
local segs = crawl.split(value, ',')
for _, s in ipairs(segs) do
rr_add_monster(mons_table, s)
end
end
function ch_mon_is_safe(mon, default_is_safe, moving, dist)
if default_is_safe then
return true
end
local mons_table
-- If player is moving and the monster is in g_rr_monsters_moving,
-- then we do the distance comparison without decreasing the
-- distance value.
if moving then
mons_table = g_rr_monsters_moving
for i = 1, #mons_table[1] do
local m = mons_table[1][i]
local min_dist = mons_table[2][i]
if m:matches(mon.name) then
return min_dist <= dist
end
end
end
mons_table = g_rr_monsters
-- Reduce distance by 1 if moving, since the safety check is
-- done *before* moving closer to the monster
if moving then
dist = dist - 1
end
for i = 1, #mons_table[1] do
local m = mons_table[1][i]
local min_dist = mons_table[2][i]
if m:matches(mon.name) then
return min_dist <= dist
end
end
return false
end
chk_lua_option.runrest_ignore_monster = rr_add_monsters
chk_lua_option.runrest_ignore_monster_moving = rr_add_monsters
|