Advertisement
CommanderC

autopray.lua

Apr 21st, 2012
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.84 KB | None | 0 0
  1. ---------------------------------------------------------------------------
  2. -- autopray.lua:
  3. -- Sacrifice any corpse in LOS.
  4. --
  5. -- To use this, add this line to your init.txt:
  6. --   lua_file = lua/autopray.lua
  7. -- then macro a key to ===offer_all
  8. --
  9. ---------------------------------------------------------------------------
  10.  
  11. local function delta_to_vi(dx, dy)
  12.   local d2v = {
  13.     [-1] = { [-1] = 'y', [0] = 'h', [1] = 'b'},
  14.     [0]  = { [-1] = 'k',            [1] = 'j'},
  15.     [1]  = { [-1] = 'u', [0] = 'l', [1] = 'n'},
  16.   }
  17.   return d2v[dx][dy]
  18. end
  19.  
  20. local function sign(a)
  21.   return a > 0 and 1 or a < 0 and -1 or 0
  22. end
  23.  
  24. local function abs(a)
  25.   return a * sign(a)
  26. end
  27.  
  28. local function try_move(dx, dy)
  29.   m = monster.get_monster_at(dx, dy)
  30.   -- attitude > ATT_NEUTRAL should mean you can push past the monster
  31.   if view.is_safe_square(dx, dy) and (not m or m:attitude() > ATT_NEUTRAL) then
  32.     delta = {}
  33.     delta.dx = dx
  34.     delta.dy = dy
  35.     return delta
  36.   else
  37.     return nil
  38.   end
  39. end
  40.  
  41. local function move_towards(dx, dy)
  42.   local move = nil
  43.   if abs(dx) > abs(dy) then
  44.     if abs(dy) == 1 then
  45.       move = try_move(sign(dx), 0)
  46.     end
  47.     if move == nil then move = try_move(sign(dx), sign(dy)) end
  48.     if move == nil then move = try_move(sign(dx), 0) end
  49.     if move == nil and abs(dx) > abs(dy)+1 then
  50.       move = try_move(sign(dx), 1)
  51.     end
  52.     if move == nil and abs(dx) > abs(dy)+1 then
  53.       move = try_move(sign(dx), -1)
  54.     end
  55.     if move == nil then move = try_move(0, sign(dy)) end
  56.   elseif abs(dx) == abs(dy) then
  57.     move = try_move(sign(dx), sign(dy))
  58.     if move == nil then move = try_move(sign(dx), 0) end
  59.     if move == nil then move = try_move(0, sign(dy)) end
  60.   else
  61.     if abs(dx) == 1 then
  62.       move = try_move(0, sign(dy))
  63.     end
  64.     if move == nil then move = try_move(sign(dx), sign(dy)) end
  65.     if move == nil then move = try_move(0, sign(dy)) end
  66.     if move == nil and abs(dy) > abs(dx)+1 then
  67.       move = try_move(1, sign(dy))
  68.     end
  69.     if move == nil and abs(dy) > abs(dx)+1 then
  70.       move = try_move(-1, sign(dy))
  71.     end
  72.     if move == nil then move = try_move(sign(dx), 0) end
  73.   end
  74.   if move == nil then
  75.     crawl.mpr("Failed to move towards target.")
  76.   else
  77.     local vi_move = delta_to_vi(move.dx, move.dy)
  78.     if vi_move ~= nil then
  79.       crawl.process_keys(vi_move)
  80.     else
  81.       return nil    
  82.     end
  83.   end
  84.   return move
  85. end
  86.  
  87. local function is_rotting(item)
  88.   return string.find(item.name(), 'rotting')
  89. end
  90.  
  91. local function is_skeleton(item)
  92.    return string.find(item.name(), 'skeleton')
  93. end
  94.  
  95. local function is_good_corpse(item)
  96.   if not item then
  97.     return false
  98.   end
  99.   if item.class() == 'Carrion' and not is_rotting(item) and not is_skeleton(item) then
  100.     if you.god() ~= 'Beogh' or string.find(item.name(), 'orc ') ~= nil then
  101.        return true
  102.     else
  103.        return false
  104.     end
  105.   else
  106.     return false
  107.   end
  108. end
  109.  
  110. local function is_candidate_for_offering()
  111.   floor_items = you.floor_items()
  112.   if not floor_items then
  113.     return false
  114.   end
  115.   for i, el in ipairs(floor_items) do
  116.     if is_good_corpse(el) then
  117.       return true
  118.     end
  119.   end
  120.   return false
  121. end
  122.  
  123. local function move_to(dx, dy)
  124.   while dx ~= 0 or dy ~= 0 do
  125.      local move = move_towards(dx, dy)
  126.      if move then
  127.        coroutine.yield(true)
  128.        dx = dx - move.dx
  129.        dy = dy - move.dy
  130.      else
  131.        return false
  132.      end
  133.   end
  134.   return true
  135. end
  136.  
  137. local function offer()
  138.    crawl.process_keys('p')
  139.    coroutine.yield(true)
  140. end
  141.  
  142. local function get_all_targets()
  143.   local targets = {}
  144.   local index = 1
  145.   for x = -8,8 do
  146.     for y = -8,8 do
  147.       if items.get_item_at(x, y) then
  148.         targets[index] = {}
  149.         targets[index].x = x
  150.         targets[index].y = y
  151.         targets[index].d = (abs(x) > abs(y)) and abs(x) or abs(y)        
  152.         index = index + 1
  153.       end
  154.     end
  155.   end
  156.   return targets
  157. end
  158.  
  159. function offer_all()
  160.   if you.confused() then
  161.     crawl.mpr("You are too confused!")
  162.     return
  163.   elseif caught then
  164.     crawl.mpr("You are " .. caught .. "!")
  165.     return
  166.  end
  167.  
  168.   local god = you.god()
  169.   if god ~= 'Makhleb' and god ~= 'Lugonu' and god ~= 'Okawaru'
  170.      and god ~= 'Trog' and god ~= 'Beogh' then
  171. --     if god ~= 'Nemelex Xobeh' and god ~= 'Elyvilon' then
  172. --       crawl.mpr("You can't offer anything.")
  173. --     end
  174.      return
  175.   end
  176.  
  177.   local targets = get_all_targets()
  178.   if table.getn(targets) < 1 then
  179.     return
  180.   end
  181.  
  182.   table.sort(targets, function (a, b) return (a.d < b.d) end)
  183.   local last_move = {x=0, y=0}
  184.  
  185.   crawl.more_autoclear(true)
  186.   for _,t in ipairs(targets) do
  187.     if move_to(t.x - last_move.x, t.y - last_move.y) then
  188.       if is_candidate_for_offering() then
  189.         offer()
  190.       end
  191.       if is_candidate_for_offering() then
  192.         -- avoid infinite loop
  193.         return
  194.       end
  195.  
  196.       last_move.x = t.x
  197.       last_move.y = t.y
  198.     else
  199.       -- pathing problems? return to initial position, and try again
  200.       if move_to(-last_move.x, -last_move.y) then
  201.         if move_to(t.x, t.y) then
  202.           if is_candidate_for_offering() then
  203.             offer()
  204.           end
  205.           if is_candidate_for_offering() then
  206.             -- avoid infinite loop
  207.             return
  208.           end
  209.           last_move.x = t.x
  210.           last_move.y = t.y
  211.         else
  212.           -- can't go to the initial pos
  213.           return
  214.         end
  215.        else
  216.         -- can't go to t
  217.         return
  218.       end
  219.     end
  220.   end
  221.   crawl.more_autoclear(false)
  222. end
  223.  
  224. function autopray_interrupt_macro(interrupt_name)
  225.     return interrupt_name == "hp_loss" or interrupt_name == "stat" or
  226.            interrupt_name == "monster" or interrupt_name == "force"
  227. end
  228.  
  229. -- Add a macro interrupt hook so that we don't get stopped by any old interrupt
  230. chk_interrupt_macro.offer_all = autopray_interrupt_macro
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement