wyvern.kernel.monsters
Class StandardAI

java.lang.Object
  extended byjava.lang.Thread
      extended bywyvern.kernel.commands.AbstractAI
          extended bywyvern.kernel.monsters.StandardAI
All Implemented Interfaces:
AI, java.lang.Runnable, Singleton

public class StandardAI
extends AbstractAI
implements Singleton

The most common AI for game monsters. This AI is customizable via predicates and other properties, to produce interesting and even unique behavior for different monsters using the AI.

The properties by which it's currently customizable are as follows. Note that they're all properties on the monster, not on the AI. The AI itself has no properties to customize it.

Version:
1.0, Nov 13, 1999
Author:
Steve Yegge

Field Summary
static boolean DEBUG
           
static int MAX_RADIUS
          Distance from a monster for which a player is considered to be "in range" (e.g. in view).
 
Fields inherited from class wyvern.kernel.commands.AbstractAI
commandables_, commandList_, queues_
 
Fields inherited from class java.lang.Thread
MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY
 
Fields inherited from interface wyvern.lib.AI
DEFAULT_MONSTER_INERTIA, DEFAULT_WANDER_RANGE
 
Method Summary
static AI add(Commandable m)
          Puts a monster under this AI's control.
 void addToHateList(Commandable defender, Commandable attacker)
          Adds the defender to the monster's I-hate-you list.
 boolean attackAdjacentPlayer(Commandable agent, Commandable[] targets)
          Looks for a player right next to us, so we can skip the search.
 boolean canWieldSomething(Commandable agent)
          Returns true if the monster wants to wield a weapon.
 void debug(java.lang.String msg)
           
 void emitMessages(Commandable agent, java.lang.String temper)
          Monster wants to speak its piece.
 boolean findPlayerToChase(Commandable agent, Commandable[] targets)
          Looks for a player nearby to move towards.
static AI getImpl()
           
static AI getInstance()
           
 Commandable[] getNearbyTargets(Commandable agent, java.util.Set hates, GameMap map)
          Returns a list of the targets close enough to chase.
static java.lang.String getProfilingInfo()
          Returns info about monsters under our control.
 Commandable lineOfSight(Commandable monster, Commandable[] targets)
          Goes through the target list and looks for one with an unobstructed view, and returns it.
 boolean lookForObjects(Commandable monster, GameMap map)
          Looks for nice things to pick up.
 void notifyAttacked(Commandable defender, Commandable attacker)
          Notification that one of our monsters has been attacked.
static void remove(Commandable m)
          Removes a monster from our control.
 void setAppropriateBehavior(Commandable monster)
          This function attempts to figure out which behavior to assign to a creature which doesn't currently have one.
protected  Point targetAdjacentMonster(Commandable monster, Commandable target)
          Looks for a player to target.
 void think(Commandable agent, EventQueue q)
          Decides what to do next.
 java.lang.String toString()
          Returns a String representation.
 boolean tryAttackingWithoutMoving(Commandable agent, Commandable[] targets)
          Attempts to perform an attack without moving - useful for stationary monsters, but also the first thing to try for moving monsters, since it's cheaper than pathfinding.
 boolean tryCastSpell(Commandable monster, Commandable[] targets, boolean lineOfSight)
          Attempts to cast a spell.
 boolean tryRangeWeapon(Commandable monster, Commandable[] targets)
          Attempts to fire a range weapon, throw something, use a wand or scroll, etc. instead of chasing a player.
 boolean tryStepBack(Commandable monster, Commandable target)
          In the specific case of a range-weapon-user or spellcaster that's adjacent to their target, we try to step away from the target.
 
Methods inherited from class wyvern.kernel.commands.AbstractAI
addCommandable, chooseRandomDir, getAverageTime, getCommand, getNumThinks, getTotalTime, isControlling, moveRandomly, registerCommand, removeCommandable, requestEvent, run, serviceQueues, thinkForQueue, unregisterCommand
 
Methods inherited from class java.lang.Thread
activeCount, checkAccess, countStackFrames, currentThread, destroy, dumpStack, enumerate, getContextClassLoader, getName, getPriority, getThreadGroup, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, resume, setContextClassLoader, setDaemon, setName, setPriority, sleep, sleep, start, stop, stop, suspend, yield
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

MAX_RADIUS

public static final int MAX_RADIUS
Distance from a monster for which a player is considered to be "in range" (e.g. in view). Dunno if we want this to be customizable per monster - maybe based on monster's intelligence?

See Also:
Constant Field Values

DEBUG

public static final boolean DEBUG
See Also:
Constant Field Values
Method Detail

getImpl

public static AI getImpl()

getInstance

public static AI getInstance()

setAppropriateBehavior

public void setAppropriateBehavior(Commandable monster)
This function attempts to figure out which behavior to assign to a creature which doesn't currently have one.

Parameters:
monster - the critter that needs a behavior object

add

public static AI add(Commandable m)
Puts a monster under this AI's control.

Parameters:
m - a monster to add
Returns:
the AI instance that the monster was added to

remove

public static void remove(Commandable m)
Removes a monster from our control.

Parameters:
m - the monster to remove

think

public void think(Commandable agent,
                  EventQueue q)
Decides what to do next. Called by superclass when q is ready.

Specified by:
think in interface AI
Specified by:
think in class AbstractAI
Parameters:
agent - the monster to think for
q - the monster's event queue

tryAttackingWithoutMoving

public boolean tryAttackingWithoutMoving(Commandable agent,
                                         Commandable[] targets)
Attempts to perform an attack without moving - useful for stationary monsters, but also the first thing to try for moving monsters, since it's cheaper than pathfinding.

Parameters:
agent - the monster
targets - the list of possible target players/monsters

tryRangeWeapon

public boolean tryRangeWeapon(Commandable monster,
                              Commandable[] targets)
Attempts to fire a range weapon, throw something, use a wand or scroll, etc. instead of chasing a player.

Parameters:
monster - the monster that's looking
targets - the list of possible target monsters/players
Returns:
true if we used a range weapon

tryCastSpell

public boolean tryCastSpell(Commandable monster,
                            Commandable[] targets,
                            boolean lineOfSight)
Attempts to cast a spell. If the monster has a "uses-spells" int property, the value is the chance the monster will use a spell on any given turn. If "uses-spells" is zero (the default), the monster will never cast spells, and if it's 100, the monster will never move, always preferring to cast a spell. The monster has to have a SpellList property listing the spells it's capable of casting.

Parameters:
monster - the monster
targets - possible players to zap
lineOfSight - true to check if we have a clear path to the player, false to cast in the direction of any player.
Returns:
true if we cast one

tryStepBack

public boolean tryStepBack(Commandable monster,
                           Commandable target)
In the specific case of a range-weapon-user or spellcaster that's adjacent to their target, we try to step away from the target.

Parameters:
monster - the monster
target - the target
Returns:
true if we stepped away

targetAdjacentMonster

protected Point targetAdjacentMonster(Commandable monster,
                                      Commandable target)
Looks for a player to target. Works via side-effect: if we find a player adjacent to us, remembers the player (as a property) so we can fire in that direction later.

Parameters:
monster - the monster
target - the target player/monster
Returns:
a point to fire at if the target is adjacent

lookForObjects

public boolean lookForObjects(Commandable monster,
                              GameMap map)
Looks for nice things to pick up.

Parameters:
monster - the monster that's looking
map - the monster's map

attackAdjacentPlayer

public final boolean attackAdjacentPlayer(Commandable agent,
                                          Commandable[] targets)
Looks for a player right next to us, so we can skip the search. Being a trivial-reject case, we try not to allocate any objects or perform any complex operations.

Parameters:
agent - the monster looking
targets - the non-null, nonempty set of nearby targets
Returns:
true if we found and attacked a player

findPlayerToChase

public boolean findPlayerToChase(Commandable agent,
                                 Commandable[] targets)
Looks for a player nearby to move towards.

Parameters:
agent - the monster
targets - the non-null, nonempty set of nearby targets
Returns:
true if we executed an action

getNearbyTargets

public Commandable[] getNearbyTargets(Commandable agent,
                                      java.util.Set hates,
                                      GameMap map)
Returns a list of the targets close enough to chase. Side effect: sets a property on the agent called "@a*-rect" containing the rectangle centered around the monster that it's willing to search.

Normally looks for players, but if the monster has the "pet-monster" boolean property, it will look for monsters to attack instead, along with any players it's pissed off at.

Parameters:
agent - the monster
hates - a list of monsters or players we hate (e.g. they attacked us), or null if n/a.
map - the monster's map
Returns:
a list of nearby targets, or null if none were found

canWieldSomething

public boolean canWieldSomething(Commandable agent)
Returns true if the monster wants to wield a weapon.

Parameters:
agent - the monster

emitMessages

public void emitMessages(Commandable agent,
                         java.lang.String temper)
Monster wants to speak its piece.

Parameters:
agent - the monster
temper - the current AI temper of the monster; can be null

lineOfSight

public Commandable lineOfSight(Commandable monster,
                               Commandable[] targets)
Goes through the target list and looks for one with an unobstructed view, and returns it. Used for firing missiles, casting spells, throwing things, etc.

Parameters:
monster - the monster that wants to fire something
targets - the list of potential targets
Returns:
one of the targets, or null if all are blocked

notifyAttacked

public void notifyAttacked(Commandable defender,
                           Commandable attacker)
Notification that one of our monsters has been attacked.

Specified by:
notifyAttacked in interface AI
Overrides:
notifyAttacked in class AbstractAI
Parameters:
defender - the monster being attacked
attacker - the attacker (could be a monster or player)

addToHateList

public void addToHateList(Commandable defender,
                          Commandable attacker)
Adds the defender to the monster's I-hate-you list.

Specified by:
addToHateList in interface AI
Overrides:
addToHateList in class AbstractAI

toString

public java.lang.String toString()
Returns a String representation.


debug

public void debug(java.lang.String msg)

getProfilingInfo

public static java.lang.String getProfilingInfo()
Returns info about monsters under our control.