A set of functions to examine/describe a monster


Questions, Explanations, Howtos

User avatar

Dungeon Dilettante

Posts: 4

Joined: Saturday, 14th April 2012, 02:18

Post Wednesday, 2nd August 2017, 14:25

A set of functions to examine/describe a monster

Something I'm interested in trying is automating an xv on a monster that comes into view. Later I'd keep track of monsters I've "identified" and only xv the first of each monster type.

In bot code they might find monsters like this:

  Code:
: local function find_next_monster()
:   local r, x, y
:   for r = 1,8 do
:     for x = -r,r do
:       for y = -r,r do
:         m = monster.get_monster_at(x, y)
:       end
:     end
:   end
: end

Is that how you might go about this? I was toying with the idea of doing a string.find on "comes into view" but someone mentioned that may only work if something came into view on its own?

I'm just looking for ideas. If you have any particular rc files that'd you recommend parsing, that'd be nice. Here's a list of ones I currently need to scour more: https://gist.github.com/shmup/97e8d966a ... f2be8046e2

One sort of useful reply in this thread could just be the psuedo code you'd use for this sort of functionality.

I'd call this script StopAndThinkBeforeYouCombat.rc

Spider Stomper

Posts: 202

Joined: Thursday, 11th April 2013, 21:07

Post Wednesday, 9th August 2017, 02:02

Re: A set of functions to examine/describe a monster

shmup wrote:Something I'm interested in trying is automating an xv on a monster that comes into view. Later I'd keep track of monsters I've "identified" and only xv the first of each monster type.

If you have any particular rc files that'd you recommend parsing, that'd be nice.

Here's the Lua to do this. Much of it is available in qw.rc (which makes for a good first reference whenever you want to see how something might be written in Crawl Lua), the rest is pretty straightforward.
Spoiler: show
  Code:
#####################################
# enum values :/
: ATT_FRIENDLY = 4
: ATT_NEUTRAL = 1
: ATT_HOSTILE = 0
: LOS = 7
: if you.race() == "Barachi" then
:   LOS = 8
: end

#####################################

{
function ripairs(t)
  local function ripairs_it(t,i)
    i=i-1
    local v=t[i]
    if v==nil then return v end
    return i,v
  end
  return ripairs_it, t, #t+1
end

function is_player_ghost(name)
  if string.find(name, "'s ghost") or string.find(name, "' ghost") then
    return true
  end
  return false
end

local temp_ghost_whitelist = {}

function check_m_names(name)
  if c_persist.m_names == nil then
    return true
  end
  for i,mon_name in ripairs(c_persist.m_names) do
--  for i,mon_name in ipairs(c_persist.m_names) do
    if is_player_ghost(name) then
      local ghost_name = mon_name
      for i,ghost_name in ipairs(temp_ghost_whitelist) do
        if name == ghost_name then return false end
      end
      table.insert(temp_ghost_whitelist, ghost_name)
      return true
    end
    if name == mon_name then
      return false
    end
  end
  return true
end

function delta_to_vi(dx, dy)
  local d2v = {
    [-1] = { [-1] = 'y', [0] = 'h', [1] = 'b'},
    [0]  = { [-1] = 'k',            [1] = 'j'},
    [1]  = { [-1] = 'u', [0] = 'l', [1] = 'n'},
  } -- hack
  return d2v[dx][dy]
end

function sign(a)
  return a > 0 and 1 or a < 0 and -1 or 0
end

function abs(a)
  return a * sign(a)
end

function vector_move(dx, dy)
  local str = ''
  for i = 1, abs(dx) do
    str = str .. delta_to_vi(sign(dx), 0)
  end
  for i = 1, abs(dy) do
    str = str .. delta_to_vi(0, sign(dy))
  end
  return str
end

-- simple checks for a few easy and probably-dangerous things
-- proper threat assessment is a topic for a whole bot
function is_threatening(m)
  if m:attitude() > ATT_NEUTRAL then
    return false
  end
  if m:is_firewood() then
    if not string.find(m:name(), "ballistomycete") then
      return false
    end
  end
  if m:name() == "butterfly" then
    return false
  end
  if m:threat() > 1 then
    return true
  end
  if string.find(m:speed_description(), "fast") then
    return true
  end
  if m:is_unique() then
    return true
  end
  if string.find(m:name(), "'s ghost") or string.find(m:name(), "' ghost") then
    return true
  end
 
  return false
end

function not_quite_ttt()
  local safe_los = true
  for i = -LOS,LOS do
    for j = -LOS,LOS do
      m = monster.get_monster_at(i,j)
--      if m then
      if m and is_threatening(m) then   -- comment this out and uncomment above if you want to fire 'xv' on the first of *every* monster type to come into view; this will include things like plants
        safe_los = false
        local mon_name = m:name()
        if check_m_names(mon_name) then
          if not is_player_ghost(mon_name) then table.insert(c_persist.m_names, mon_name) end
          crawl.mpr("Found new monster! (" .. mon_name .. ")")
          crawl.process_keys("x" .. vector_move(i,j) .. "v")
        end
      end
    end
  end
  if safe_los then
    temp_ghost_whitelist = {}
  end
end

function ready()
  if you.turns() == 0 then
    c_persist.m_names = {}      -- comment this out if you don't want your 'xv' memory to reset upon creating a new character.
  end
  not_quite_ttt()
end
}

As far as usability goes, the above code isn't ideal: Autoexplore taps and movement taps will often cancel out of the 'v' window after it's been brought up, leaving you seeing a flash of an info window followed by your cursor being stolen into an e'x'amine targeter. I don't see a way to fix this within Crawl's Lua: The direction chooser runs its own inner loop that seems to preempt all other code, which seems to prevent Lua from breaking out of it. I haven't looked deeply into whether it's possible to hook something to escape out of this; the direction chooser code is labyrinthine.

One possibility might be to fire a --more-- with a message prior to firing the 'xv': This would notify the player that they're about to see an info window at the cost of some additional button spam through the mores. I don't really like that solution, so I didn't add it.

For this message the author Implojin has received thanks: 2
shmup, VeryAngryFelid

Return to Coding

Who is online

Users browsing this forum: No registered users and 1 guest

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.