Aardwolf kill script

This script can be used in e.g. KMuddy to automatically practice all known skills to attack mobs.

Once upon a time, when I played Aardwolf a bit. To make my life easier, I wrote a simple script to practice all known kill methods on mobs. This script chooses a random skill (some skills can be favored by specifying them multiple times in skill array) and attack the mob. It even tries it’s best to guess which mob you are figthing (if there are many) and when that mob was killed.

This script can be used in e.g. KMuddy to automatically practice all known skills to attack mobs.

Once upon a time, when I played Aardwolf a bit. To make my life easier, I wrote a simple script to practice all known kill methods on mobs. This script chooses a random skill (some skills can be favored by specifying them multiple times in skill array) and attack the mob. It even tries it’s best to guess which mob you are figthing (if there are many) and when that mob was killed.

#!/usr/bin/ruby -d
#
# MUD: AardWolf
# Client: KMuddy (possibly others)
# Author: Laas Toom
# Description: Script to automatically use random skill for attacking mobs
#   When multiple mobs are attacking, skript tries to figure out the mob's name
#   who attacked you last.
#
# USAGE: kill.rb  [skill1,skill2,...]
#
# Put this script to some MUD client (e.g. KMuddy) and set up alias
# to call this script with at least one argument - the mob name.
# Second and latter args are used to limit attacking skills
# (e.g. when a mob is more vurneable to some special attack
# or you want to practice this skill more).
#
# All skills known to character must be listed in this script
#
# NB! If MUD or client does not indicate server readyness with
# '3 ' prepended to output, set this to true
SERVER_ALWAYS_READY = false

# put all attack skills here, using syntax:
# "attack_cmd" => "server response word"
SKILLS={
  "circle" => "circle",
  "circle" => "circle",
  "kobold" => "Stench",
  "kick" => "kick",
  "burnt" => "Poison"
}

# so output reaches mud client
$stdout.sync = true

# add random method to array
class Array
  def random
    self[rand(self.size)]
  end
end

# a logger class
class Logger
  # logger is active only with DEBUG
  if $DEBUG
    def initialize
        @log = File.open("kill.log","w")
        @log.sync = true
    end

    # simple puts
    def puts(str)
      @log.puts str
    end

    # debugger
    def debug(str)
      @log.puts("DEBUG: #{str}")
    end
  else
    def puts(str)
    end
    def debug(str)
    end
  end

  def close
    if @log
      @log.close
    end
  end
end

# who we are killing
MOB = ARGV[0]
target = MOB

exit unless MOB

# If there's nobody to kill
NOBODY = Regexp.new(/They aren't here./)
DEATH = Regexp.new(/A .*?(w+) crumbles as s?he is battered to death!!/)
DEATH2 = Regexp.new(/The final deadly circle turns a .*?(w+) into food for the worms!/)
DEATH3 = Regexp.new(/A .*?(w+) is slain by a final deadly stab!!/)
MOB_FIGHTING = Regexp.new(/That monster has already been challenged! Find another./)
FLEE = Regexp.new(/You flee/)

# Which targets have already perhished
DEAD = {}

# If we have more arguments, use only those skills
if ARGV.size > 1
  pattern = "(#{ARGV[1..(ARGV.size-1)].join("|")})"
  SKILLS.delete_if{|k,v| k !~ /#{pattern}/}
end

done = false

LOG = Logger.new

LOG.puts "SELF: Starting combat: #{MOB}"

# method to detect end of fight
def detect_end(line)
  case line
  when DEATH,DEATH2,DEATH3
    DEAD[$1] = true
    # unless some targets are alive, return true
    return true unless DEAD.has_value?(false)
    LOG.puts "DEBUG: some targets still alive: #{DEAD.inspect}"
    # set new target to next alive
    DEAD.each_pair{|k,v|
      if v == false
        target = k
        break
      end
    }
    return false
  when NOBODY,FLEE,MOB_FIGHTING
    return true
  end
  return false
end

# init with a random skill
skill = SKILLS.keys.random

# is server ready for next command
server_ready = true
# has previous command finished
command_finished = true
# if we cicle first time
first_time = true

until done
  unless first_time
    line = $stdin.gets
    LOG.puts "SERVER: " + line.to_s

    # detect server readyness
    if line =~ /^3 / || SERVER_ALWAYS_READY
      server_ready = true
      LOG.debug "server_ready"
    end
    # detect if previous command finished
    if line =~ /Your #{SKILLS[skill]} .*[.!] [d+]/i
      command_finished = true
      LOG.debug "command_finished"
    end

    # try to figure most recent target
    # using damage line
    if line =~ /.*?(w+)(?:'s) w+ w+ you[.!] [d+]/
      LOG.debug "new target: #{target}" unless target == $1
      target = $1
    end
  end
  first_time = false

  # detect enf of combat
  break if detect_end(line)

  # unless previous attack has been finished, wait

  # unless we can send new command
  next unless server_ready && command_finished

  # select new skill to use
  skill = SKILLS.keys.random
  puts "#{skill} #{target}"
  LOG.puts "SELF: #{skill} #{target}"

  server_ready = false
  command_finished = false

end

LOG.puts "SELF: combat over, exiting."
LOG.close

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s