Auto use staff of energy


Ask fellow adventurers how to stay alive in the deep, dark, dangerous dungeon below, or share your own accumulated wisdom.

Slime Squisher

Posts: 344

Joined: Tuesday, 14th April 2015, 19:56

Location: France

Post Sunday, 18th February 2018, 20:21

Auto use staff of energy

Hi, I'm playing a mummy caster and channelling is boring. I'd like to modify my rcfile to automatically use my staff of channelling when resting. I feel like this can be done with some lua and I'm willing to do it myself if it doesn't exist, but I don't know how to execute a function whenever I press 5, or how to check that the situation is safe in lua. I'd like to know if anyone has already done that or if someone could give me some pointers on how to do it with lua.
3 runes : MiMo^Ru, HOFi^Beogh, TrMo^Yredelemnul, GrFi^Ru, FoFi^Gozag, MiGl^Okawaru
4 runes : DDFi^Makhleb
5 runes : GrEE^Vehumet
15 runes : MiFi^Ru, NaWz^Sif Muna, GrWz^Sif Muna
I mostly play offline or online on CXC

Slime Squisher

Posts: 350

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

Post Sunday, 18th February 2018, 22:03

Re: Auto use staff of energy

Preliminary disclaimer: I am working from memory and lazily ripped code snippets from my local Stone Soup directory. In addition to adding the Lua to activate your staff, you may also need to slightly modify what I have written below to get it working.

Reference elliptic's qw.rc for implementation details. Here's a link to an old post that covers general rcfile Lua info: viewtopic.php?p=313397#p313397

Fingolfin wrote:I don't know how to execute a function whenever I press 5,

To do this, you will need to create an Lua function yourfunctionname() in your .rcfile or init.txt, then bind that function to a macro (either in-game or by editing macro.txt) by creating and saving a macro that executes ===yourfunctionname . In this case, you'd want to bind it to 5.

Fingolfin wrote:how to check that the situation is safe in lua. I'd like to know ... if someone could give me some pointers on how to do it with lua.

To do this, you'll need to write the necessary Lua to check your line of sight for threats and add it to your .rcfile or init.txt. Here is some skeleton Lua you can adapt, originally adapted from the ttt() function in qw.rc:

  Code:
#####################################
# enum values :/
: LOS = 7
: if you.race() == "Barachi" then
:   LOS = 8
: 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 on every monster to come into view; this will include things like plants
        safe_los = false
      end
    end
  end
  if safe_los then
  -- put your staff activation Lua here
 
  end
end
}

My code here is probably shit, so just assume that if my sample code is broken then it's my fault and there's a working version of the same thing you can adapt to accomplish what you want in qw.rc.

I hope you get this working, good luck. :)

For this message the author Implojin has received thanks:
Fingolfin

Slime Squisher

Posts: 344

Joined: Tuesday, 14th April 2015, 19:56

Location: France

Post Tuesday, 20th February 2018, 19:57

Re: Auto use staff of energy

Thanks a lot for your help. I have tried to adapt your code to my use case but I get the following error in function is_threatening(m):
  Code:
attempt to compare nil with number

The code I used :
  Code:
#####################################
# enum values :/
: LOS = 7
: if you.race() == "Barachi" then
:   LOS = 8
: 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 then
     if m:attitude() > ATT_NEUTRAL then                 -- the error triggers at this line
       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
   end
 
  return false
end

function auto_channel()
  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 on every monster to come into view; this will include things like plants
        safe_los = false
      end
    end
  end
  local mp, mmp = you.mp()
  if safe_los then
     if mp < mmp then
     -- put your staff activation Lua here
     crawl.process_keys("v" .. string.char(27) .. string.char(27) .. string.char(27))
   end
  end
end
}

Do you know what is going wrong?
3 runes : MiMo^Ru, HOFi^Beogh, TrMo^Yredelemnul, GrFi^Ru, FoFi^Gozag, MiGl^Okawaru
4 runes : DDFi^Makhleb
5 runes : GrEE^Vehumet
15 runes : MiFi^Ru, NaWz^Sif Muna, GrWz^Sif Muna
I mostly play offline or online on CXC

For this message the author Fingolfin has received thanks:
Implojin

Slime Squisher

Posts: 350

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

Post Tuesday, 20th February 2018, 22:07

Re: Auto use staff of energy

Yup, in my lazy copy-pasting I removed a bunch of extraneous stuff from my local ini, one of them was the attitude enums [oops!] which are necessary for the m:attitude() comparison. (Crawl's ATT_HOSTILE etc. enums aren't available from within its cLua binds so you have to define them yourself...)

Here's a slightly more cleaned up version that should work, I've also fixed up that threat function a bit since what I had originally pasted there would have gotten your character killed sooner or later.

  Code:
#####################################
# enum values :/
: ATT_FRIENDLY = 4
: ATT_NEUTRAL = 1
: ATT_HOSTILE = 0
: LOS = 7
: if you.race() == "Barachi" then
:   LOS = 8
: end

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

{

-- just a few outs for nondamaging things
-- proper threat assessment is a topic for a whole bot
function is_threatening(m)
  if m then
     if m:attitude() > ATT_NEUTRAL then                 -- the error triggers at this line
       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
 
  return true
  end
end

function auto_channel()
  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 on every monster to come into view; this will include things like plants
        safe_los = false
      end
    end
  end
  local mp, mmp = you.mp()
  if safe_los then
     if mp < mmp then
     -- put your staff activation Lua here
     crawl.process_keys("v" .. string.char(27) .. string.char(27) .. string.char(27))
   end
  end
end
}

For this message the author Implojin has received thanks:
Fingolfin

Slime Squisher

Posts: 344

Joined: Tuesday, 14th April 2015, 19:56

Location: France

Post Wednesday, 21st February 2018, 12:40

Re: Auto use staff of energy

Implojin wrote:Yup, in my lazy copy-pasting I removed a bunch of extraneous stuff from my local ini, one of them was the attitude enums [oops!] which are necessary for the m:attitude() comparison. (Crawl's ATT_HOSTILE etc. enums aren't available from within its cLua binds so you have to define them yourself...)

Here's a slightly more cleaned up version that should work, I've also fixed up that threat function a bit since what I had originally pasted there would have gotten your character killed sooner or later.

  Code:
#####################################
# enum values :/
: ATT_FRIENDLY = 4
: ATT_NEUTRAL = 1
: ATT_HOSTILE = 0
: LOS = 7
: if you.race() == "Barachi" then
:   LOS = 8
: end

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

{

-- just a few outs for nondamaging things
-- proper threat assessment is a topic for a whole bot
function is_threatening(m)
  if m then
     if m:attitude() > ATT_NEUTRAL then                 -- the error triggers at this line
       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
 
  return true
  end
end

function auto_channel()
  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 on every monster to come into view; this will include things like plants
        safe_los = false
      end
    end
  end
  local mp, mmp = you.mp()
  if safe_los then
     if mp < mmp then
     -- put your staff activation Lua here
     crawl.process_keys("v" .. string.char(27) .. string.char(27) .. string.char(27))
   end
  end
end
}

Thanks a lot for your help, the code works for a single channelling so I tried to adapt it to fire as long as you need mana. I tried a while loop and it triggers a Lua error : Cannot currently process new keys (turn is over)
Here's the code :
  Code:
#####################################
# enum values :/
: ATT_FRIENDLY = 4
: ATT_NEUTRAL = 1
: ATT_HOSTILE = 0
: LOS = 7
: if you.race() == "Barachi" then
:   LOS = 8
: end

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

{

-- just a few outs for nondamaging things
-- proper threat assessment is a topic for a whole bot
function is_threatening(m)
  if m then
     if m:attitude() > ATT_NEUTRAL then                 -- the error triggers at this line
       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
 
  return true
  end
end

function check_los()
   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 on every monster to come into view; this will include things like plants
        safe_los = false
      end
    end
  end
  return safe_los
end

function auto_channel()
  local safe_los = check_los()
  local mp, mmp = you.mp()
  while mp < mmp and safe_los do
    crawl.process_keys("v")
    crawl.flush_input()
    crawl.more_autoclear(true)
    mp, mmp = you.mp()
    safe_los = check_los()
  end
end
}

crawl.process_keys() doesn't seem to tell the game to end the turn so I am probably missing a single instruction to pass on to the next turn but I can't seem to find it. I tried searching in l-crawl.cc but with no result. Otherwise it should work.
3 runes : MiMo^Ru, HOFi^Beogh, TrMo^Yredelemnul, GrFi^Ru, FoFi^Gozag, MiGl^Okawaru
4 runes : DDFi^Makhleb
5 runes : GrEE^Vehumet
15 runes : MiFi^Ru, NaWz^Sif Muna, GrWz^Sif Muna
I mostly play offline or online on CXC

Slime Squisher

Posts: 350

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

Post Wednesday, 21st February 2018, 18:55

Re: Auto use staff of energy

Fingolfin wrote:crawl.process_keys() doesn't seem to tell the game to end the turn so I am probably missing a single instruction to pass on to the next turn but I can't seem to find it. I tried searching in l-crawl.cc but with no result. Otherwise it should work.

There's a clua hook in the input handler that you can use to run custom Lua each time a player turn becomes available, function ready() .

If that function exists in your rcfile, it will be called once per turn, prior to checking for any manual player input.

Rewrite your logic a little bit to use that and make your macro a state toggle and it should probably work.

(Yeah, it sucks that there's no documentation of Crawl's Lua functions and hooks.)
https://github.com/crawl/crawl/blob/mas ... n.cc#L1100
https://github.com/elliptic/qw/blob/master/qw.rc#L8475

git grep 'clua.call' , from within a local Crawl repository, should show you the names of most of the available functions you can hook into.

For this message the author Implojin has received thanks:
Fingolfin

Slime Squisher

Posts: 344

Joined: Tuesday, 14th April 2015, 19:56

Location: France

Post Wednesday, 21st February 2018, 23:25

Re: Auto use staff of energy

Implojin wrote:There's a clua hook in the input handler that you can use to run custom Lua each time a player turn becomes available, function ready() .

If that function exists in your rcfile, it will be called once per turn, prior to checking for any manual player input.

Rewrite your logic a little bit to use that and make your macro a state toggle and it should probably work.

That did it, thanks a lot !! I also added a check to see if you're not in a harmful cloud while channelling. It doesn't check if you're next to an acid wall though, and I checked in wizmode, using this macro next to an acid wall at MP will kill you. That's not really important though, just don't fire it up if you're next to an acid wall.

The macro will also check that you are wielding a staff of energy because it causes weird errors otherwise

I'm leaving the code here for future reference, maybe someone will find it useful, all you have to do to get it working is add it to your rcfile and macro a key to "===launch_auto_channel" (without the quotes).

Thanks again Implojin for all your precious help !

  Code:
#####################################
# enum values :/
: ATT_FRIENDLY = 4
: ATT_NEUTRAL = 1
: ATT_HOSTILE = 0
: LOS = 7
: if you.race() == "Barachi" then
:   LOS = 8
: end

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

{

-- just a few outs for nondamaging things
-- proper threat assessment is a topic for a whole bot
function is_threatening(m)
  if m then
     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
 
  return true
  end
end

function check_los()
   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 on every monster to come into view; this will include things like plants
        safe_los = false
      end
    end
  end
  return safe_los
end

local auto_channel = false

function ready()
   if auto_channel then
      local safe_los = check_los()
      local weap = items.equipped_at("Weapon")
      local is_wielding_energy_staff = false
      if weap then
         is_wielding_energy_staff = weap.name():find("staff of energy")
      end
      
      local safe_player_square = view.is_safe_square(0,0) and view.cloud_at(0,0) == nil
      local mp, mmp = you.mp()
      if mp < mmp and safe_los and safe_player_square and is_wielding_energy_staff then
         crawl.process_keys("v")
       crawl.flush_input()
       crawl.more_autoclear(true)
      else
         auto_channel = false
      end
   end
end

function launch_auto_channel()
  auto_channel = true
end
}
3 runes : MiMo^Ru, HOFi^Beogh, TrMo^Yredelemnul, GrFi^Ru, FoFi^Gozag, MiGl^Okawaru
4 runes : DDFi^Makhleb
5 runes : GrEE^Vehumet
15 runes : MiFi^Ru, NaWz^Sif Muna, GrWz^Sif Muna
I mostly play offline or online on CXC

For this message the author Fingolfin has received thanks: 2
Implojin, mattlistener

Return to Dungeon Crawling Advice

Who is online

Users browsing this forum: No registered users and 8 guests

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