<
rs_default_target = 80
rs_hp_target = rs_default_target
rs_mp_target = rs_default_target
rs_target_mode = "both"
rs_max_swings = 200
rs_stop_on_any_monster = false
rs_active = false
rs_left = 0
local rs_dirs = {
{-1, 0}, {1, 0}, {0, -1}, {0, 1},
{-1, -1}, {1, -1}, {-1, 1}, {1, 1},
}
local function rs_attack_command(x, y)
local d2v = {
[-1] = {
[-1] = "CMD_ATTACK_UP_LEFT",
[0] = "CMD_ATTACK_LEFT",
[1] = "CMD_ATTACK_DOWN_LEFT",
},
[0] = {
[-1] = "CMD_ATTACK_UP",
[1] = "CMD_ATTACK_DOWN",
},
[1] = {
[-1] = "CMD_ATTACK_UP_RIGHT",
[0] = "CMD_ATTACK_RIGHT",
[1] = "CMD_ATTACK_DOWN_RIGHT",
},
}
return d2v[x] and d2v[x][y]
end
local function rs_need_recovery()
local hp, mhp = you.hp()
local mp, mmp = you.mp()
local hp_low = hp * 100 < mhp * rs_hp_target
local mp_low = mmp > 0 and mp * 100 < mmp * rs_mp_target
if rs_target_mode == "hp" then
return hp_low
elseif rs_target_mode == "mp" then
return mp_low
elseif rs_target_mode == "any" then
if mmp <= 0 then return hp_low end
return hp_low and mp_low
end
return hp_low or mp_low
end
local function rs_bad_status()
return you.poisoned() or you.sick() or you.confused()
or you.berserk() or you.on_fire() or you.teleporting()
or you.constricted()
end
local function rs_monster_seen()
local los = you.los()
for x = -los, los do
for y = -los, los do
if not (x == 0 and y == 0) and you.see_cell(x, y) then
if view.invisible_monster(x, y) then
return true
end
local m = monster.get_monster_at(x, y)
if m and (rs_stop_on_any_monster or not m:is_safe()) then
return true
end
end
end
end
return false
end
local function rs_find_empty_adjacent()
for _, d in ipairs(rs_dirs) do
local x, y = d[1], d[2]
if you.see_cell(x, y)
and view.is_safe_square(x, y)
and not view.invisible_monster(x, y)
and not monster.get_monster_at(x, y) then
return x, y
end
end
return nil, nil
end
local function rs_stop(msg)
rs_active = false
if msg then crawl.mpr(msg) end
end
local function rs_trim(s)
return s:gsub("^%s+", ""):gsub("%s+$", "")
end
local function rs_parse_target(input)
input = rs_trim(input):lower()
if input == "" then
return "both", rs_default_target
end
local target = tonumber(input)
local mode = "both"
if not target then
local prefix, value = input:match("^([a-z]+)%s*(%d+%.?%d*)$")
target = tonumber(value)
if prefix == "h" or prefix == "hp" then
mode = "hp"
elseif prefix == "m" or prefix == "mp" then
mode = "mp"
elseif prefix == "any" then
mode = "any"
elseif prefix == "b" or prefix == "both" then
mode = "both"
else
return nil, nil
end
end
if target == nil or target < 1 or target > 100 then
return nil, nil
end
return mode, math.floor(target)
end
local function rs_target_description()
if rs_target_mode == "hp" then
return "HP " .. rs_hp_target .. "%"
elseif rs_target_mode == "mp" then
return "MP " .. rs_mp_target .. "%"
elseif rs_target_mode == "any" then
return "HP or MP " .. rs_hp_target .. "%"
end
return "HP/MP " .. rs_hp_target .. "%"
end
local function rs_prompt_target()
crawl.mpr("Rest swing target? Enter=" .. rs_default_target
.. ", 80=both, h80=HP, m80=MP, any80=either.", "prompt")
local input = crawl.c_input_line()
if input == nil then return false end
local mode, target = rs_parse_target(input)
if not mode then
crawl.mpr("Rest swing cancelled: enter 1-100, hN, mN, or anyN.")
return false
end
rs_target_mode = mode
rs_hp_target = target
rs_mp_target = target
return true
end
function rest_swing_step()
if not rs_active or you.turn_is_over() then return end
if not rs_need_recovery() then return rs_stop("Rest swing done.") end
if rs_left <= 0 then return rs_stop("Rest swing stopped: limit reached.") end
if rs_bad_status() then return rs_stop("Rest swing stopped: bad status.") end
if not you.feel_safe() or rs_monster_seen() then
return rs_stop("Rest swing stopped: monster or danger seen.")
end
local x, y = rs_find_empty_adjacent()
if not x then return rs_stop("Rest swing stopped: no safe empty adjacent cell.") end
local cmd = rs_attack_command(x, y)
if not cmd then return rs_stop("Rest swing stopped: no attack command.") end
rs_left = rs_left - 1
crawl.do_commands({cmd})
end
function rest_swing_toggle()
if rs_active then return rs_stop("Rest swing stopped.") end
if not rs_prompt_target() then return end
rs_active = true
rs_left = rs_max_swings
crawl.mpr("Rest swing started: target " .. rs_target_description() .. ".")
rest_swing_step()
end
local old_ready = ready
function ready()
if old_ready then old_ready() end
rest_swing_step()
end
>
macros += M \{F4} ===rest_swing_toggle
이렇게까지 턴을 깎는단말인가
회복턴이 젤 마니 걸림 ㅋㅋ