Angband
Functions
mon-move.c File Reference

Monster movement. More...

#include "angband.h"
#include "cave.h"
#include "game-world.h"
#include "init.h"
#include "monster.h"
#include "mon-attack.h"
#include "mon-desc.h"
#include "mon-group.h"
#include "mon-lore.h"
#include "mon-make.h"
#include "mon-predicate.h"
#include "mon-spell.h"
#include "mon-util.h"
#include "mon-timed.h"
#include "obj-desc.h"
#include "obj-ignore.h"
#include "obj-pile.h"
#include "obj-slays.h"
#include "obj-tval.h"
#include "obj-util.h"
#include "player-calcs.h"
#include "player-util.h"
#include "project.h"
#include "trap.h"

Functions

static bool monster_near_permwall (const struct monster *mon, struct chunk *c)
 

Routines to enable decisions on monster behaviour

More...
 
static bool monster_can_hear (struct chunk *c, struct monster *mon)
 Check if the monster can hear anything. More...
 
static bool monster_can_smell (struct chunk *c, struct monster *mon)
 Check if the monster can smell anything. More...
 
static int compare_monsters (const struct monster *mon1, const struct monster *mon2)
 Compare the "strength" of two monsters XXX XXX XXX. More...
 
static bool monster_can_kill (struct chunk *c, struct monster *mon, struct loc grid)
 Check if the monster can kill any monster on the relevant grid. More...
 
static bool monster_can_move (struct chunk *c, struct monster *mon, struct loc grid)
 Check if the monster can move any monster on the relevant grid. More...
 
static bool monster_hates_grid (struct chunk *c, struct monster *mon, struct loc grid)
 Check if the monster can occupy a grid safely. More...
 
static void get_move_find_range (struct monster *mon)
 

Monster movement routines These routines, culminating in get_move(), choose if and where a monster

will move on its turn

More...
 
static bool get_move_bodyguard (struct chunk *c, struct monster *mon)
 Choose the best direction for a bodyguard. More...
 
static bool get_move_advance (struct chunk *c, struct monster *mon, bool *track)
 Choose the best direction to advance toward the player, using sound or scent. More...
 
static bool get_move_find_safety (struct chunk *c, struct monster *mon)
 Choose a "safe" location near a monster for it to run toward. More...
 
static bool get_move_find_hiding (struct chunk *c, struct monster *mon)
 Choose a good hiding place near a monster for it to run toward. More...
 
static bool get_move_flee (struct chunk *c, struct monster *mon)
 Provide a location to flee to, but give the player a wide berth. More...
 
static int get_move_choose_direction (struct loc offset)
 Choose the basic direction of movement, and whether to bias left or right if the main direction is blocked. More...
 
static bool get_move (struct chunk *c, struct monster *mon, int *dir, bool *good)
 Choose "logical" directions for monster movement. More...
 
bool multiply_monster (struct chunk *c, const struct monster *mon)
 

Monster turn routines These routines, culminating in monster_turn(), decide how a monster uses

its turn

More...
 
static bool monster_turn_multiply (struct chunk *c, struct monster *mon)
 Attempt to reproduce, if possible. More...
 
static bool monster_turn_should_stagger (struct monster *mon)
 Check if a monster should stagger (that is, step at random) or not. More...
 
static bool monster_turn_can_move (struct chunk *c, struct monster *mon, const char *m_name, struct loc new, bool *did_something)
 Work out if a monster can move through the grid, if necessary bashing down doors in the way. More...
 
static bool monster_turn_attack_glyph (struct chunk *c, struct monster *mon, struct loc new)
 Try to break a glyph. More...
 
static bool monster_turn_try_push (struct chunk *c, struct monster *mon, const char *m_name, struct loc new)
 Try to push past / kill another monster. More...
 
void monster_turn_grab_objects (struct chunk *c, struct monster *mon, const char *m_name, struct loc new)
 Grab all objects from the grid. More...
 
static void monster_turn (struct chunk *c, struct monster *mon)
 Process a monster's turn. More...
 
static bool monster_check_active (struct chunk *c, struct monster *mon)
 

Processing routines that happen to a monster regardless of whether it

gets a turn, and/or to decide whether it gets a turn

More...
 
static void monster_reduce_sleep (struct chunk *c, struct monster *mon)
 Wake a monster or reduce its depth of sleep. More...
 
static bool process_monster_timed (struct chunk *c, struct monster *mon)
 Process a monster's timed effects, e.g. More...
 
static void regen_monster (struct monster *mon, int num)
 Monster regeneration of HPs. More...
 
void process_monsters (struct chunk *c, int minimum_energy)
 

Monster processing routines to be called by the main game loop

More...
 
void reset_monsters (void)
 Clear 'moved' status from all monsters. More...
 
void restore_monsters (void)
 Allow monsters on a frozen persistent level to recover. More...
 

Detailed Description

Monster movement.

Monster AI affecting movement and spells, process a monster (with spells and actions of all kinds, reproduction, effects of any terrain on monster movement, picking up and destroying objects), process all monsters.

Copyright (c) 1997 Ben Harrison, David Reeve Sward, Keldon Jones.

This work is free software; you can redistribute it and/or modify it under the terms of either:

a) the GNU General Public License as published by the Free Software Foundation, version 2, or

b) the "Angband licence": This software may be copied and distributed for educational, research, and not for profit purposes provided that this copyright and statement are included in all such copies. Other copyrights may also apply.

Function Documentation

◆ compare_monsters()

static int compare_monsters ( const struct monster mon1,
const struct monster mon2 
)
static

Compare the "strength" of two monsters XXX XXX XXX.

References monster_race::mexp, and monster::race.

Referenced by monster_can_kill(), and monster_can_move().

◆ get_move()

static bool get_move ( struct chunk c,
struct monster mon,
int dir,
bool *  good 
)
static

Choose "logical" directions for monster movement.

This function is responsible for deciding where the monster wants to move, and so is the core of monster "AI".

First, we work out how best to advance toward the player:

  • Try to head toward the player directly if we can pass through walls or if we can see them
  • Failing that follow the player by sound, or failing that by scent
  • If none of that works, just head in the general direction Then we look at possible reasons not to just advance:
  • If we're part of a pack, try to lure the player into the open
  • If we're afraid, try to find a safe place to run to, and if no safe place just run in the opposite direction to the advance move
  • If we can see the player and we're part of a group, try and surround them

The function then returns false if we're already where we want to be, and otherwise sets the chosen direction to step and returns true.

References cave_find_decoy(), monster::cdis, player::chp, ddgrid_ddd, monster_race::flags, angband_constants::flee_range, get_move_advance(), get_move_choose_direction(), get_move_find_hiding(), get_move_find_range(), get_move_find_safety(), get_move_flee(), target::grid, monster::grid, player::grid, group_monster_tracking(), i, loc(), loc_diff(), loc_is_zero(), loc_sum(), los(), angband_constants::max_sight, monster::mflag, mflag_off, mflag_on, player::mhp, monster::min_range, monster_passes_walls(), monster_taking_terrain_damage(), open, monster::race, randint0, rf_has, square_isempty(), square_ispassable(), square_isroom(), square_isview(), monster::target, and z_info.

Referenced by monster_turn().

◆ get_move_advance()

static bool get_move_advance ( struct chunk c,
struct monster mon,
bool *  track 
)
static

Choose the best direction to advance toward the player, using sound or scent.

Ghosts and rock-eaters generally just head straight for the player. Other monsters try sight, then current sound as saved in c->noise.grids[y][x], then current scent as saved in c->scent.grids[y][x].

This function assumes the monster is moving to an adjacent grid, and so the noise can be louder by at most 1. The monster target grid set by sound or scent tracking in this function will be a grid they can step to in one turn, so is the preferred option for get_move() unless there's some reason not to use it.

Tracking by 'scent' means that monsters end up near enough the player to switch to 'sound' (noise), or they end up somewhere the player left via teleport. Teleporting away from a location will cause the monsters who were chasing the player to converge on that location as long as the player is still near enough to "annoy" them without being close enough to chase directly.

References cave_find_decoy(), ddgrid_ddd, get_move_bodyguard(), target::grid, monster::grid, player::grid, heatmap::grids, monster::group_info, monster_race::hearing, i, loc_is_zero(), loc_sum(), MON_GROUP_BODYGUARD, monster_can_kill(), monster_can_move(), monster_hates_grid(), monster_near_permwall(), monster_passes_walls(), chunk::noise, PRIMARY_GROUP, monster::race, monster_group_info::role, chunk::scent, SKILL_STEALTH, player_state::skills, monster_race::smell, square_in_bounds(), square_isview(), player::state, target, monster::target, loc::x, and loc::y.

Referenced by get_move().

◆ get_move_bodyguard()

static bool get_move_bodyguard ( struct chunk c,
struct monster mon 
)
static

Choose the best direction for a bodyguard.

The idea is to stay close to the group leader, but attack the player if the chance arises

References cave, ddgrid_ddd, distance(), target::grid, monster::grid, player::grid, i, loc_sum(), los(), monster_can_kill(), monster_can_move(), monster_group_leader(), monster_hates_grid(), square_in_bounds(), and monster::target.

Referenced by get_move_advance().

◆ get_move_choose_direction()

static int get_move_choose_direction ( struct loc  offset)
static

Choose the basic direction of movement, and whether to bias left or right if the main direction is blocked.

Note that the input is an offset to the monster's current position, and the output direction is intended as an index into the side_dirs array.

References ABS, turn, loc::x, and loc::y.

Referenced by get_move().

◆ get_move_find_hiding()

static bool get_move_find_hiding ( struct chunk c,
struct monster mon 
)
static

Choose a good hiding place near a monster for it to run toward.

Pack monsters will use this to "ambush" the player and lure him out of corridors into open space so they can swarm him.

Return true if a good location is available.

References dist_offsets_x, dist_offsets_y, distance(), target::grid, monster::grid, player::grid, i, loc(), loc_sum(), PROJECT_STOP, projectable(), square_in_bounds_fully(), square_isempty(), square_isview(), and monster::target.

Referenced by get_move().

◆ get_move_find_range()

static void get_move_find_range ( struct monster mon)
static


Monster movement routines These routines, culminating in get_move(), choose if and where a monster

will move on its turn

Calculate minimum and desired combat ranges. -BR-

Afraid monsters will set this to their maximum flight distance. Currently this is recalculated every turn - if it becomes a significant overhead it could be calculated only when something has changed (monster HP, chance of escaping, etc)

References monster::best_range, monster::cdis, player::chp, monster_race::flags, angband_constants::flee_range, monster_race::freq_spell, monster::group_info, monster::hp, player::lev, monster_race::level, monster::m_timed, MAX, angband_constants::max_sight, monster::maxhp, player::mhp, monster::midx, monster::min_range, MON_GROUP_BODYGUARD, monster_breathes(), monster_loves_archery(), PRIMARY_GROUP, monster::race, rf_has, monster_group_info::role, angband_constants::turn_range, and z_info.

Referenced by get_move().

◆ get_move_find_safety()

static bool get_move_find_safety ( struct chunk c,
struct monster mon 
)
static

Choose a "safe" location near a monster for it to run toward.

A location is "safe" if it can be reached quickly and the player is not able to fire into it (it isn't a "clean shot"). So, this will cause monsters to "duck" behind walls. Hopefully, monsters will also try to run towards corridor openings if they are in a room.

This function may take lots of CPU time if lots of monsters are fleeing.

Return true if a safe location is available.

References dist_offsets_x, dist_offsets_y, distance(), monster_race::flags, target::grid, monster::grid, player::grid, heatmap::grids, i, loc(), loc_sum(), chunk::noise, monster::race, rf_has, square_feat(), square_in_bounds_fully(), square_isdamaging(), square_ispassable(), square_isview(), monster::target, loc::x, and loc::y.

Referenced by get_move().

◆ get_move_flee()

static bool get_move_flee ( struct chunk c,
struct monster mon 
)
static

Provide a location to flee to, but give the player a wide berth.

A monster may wish to flee to a location that is behind the player, but instead of heading directly for it, the monster should "swerve" around the player so that it has a smaller chance of getting hit.

References monster::best_range, monster::cdis, ddgrid_ddd, distance(), target::grid, monster::grid, heatmap::grids, i, loc(), loc_sum(), monster_can_hear(), monster_can_smell(), monster_taking_terrain_damage(), chunk::noise, square_in_bounds(), monster::target, loc::x, and loc::y.

Referenced by get_move().

◆ monster_can_hear()

static bool monster_can_hear ( struct chunk c,
struct monster mon 
)
static

◆ monster_can_kill()

static bool monster_can_kill ( struct chunk c,
struct monster mon,
struct loc  grid 
)
static

Check if the monster can kill any monster on the relevant grid.

References compare_monsters(), monster_race::flags, monster::race, rf_has, and square_monster().

Referenced by get_move_advance(), get_move_bodyguard(), and monster_turn_try_push().

◆ monster_can_move()

static bool monster_can_move ( struct chunk c,
struct monster mon,
struct loc  grid 
)
static

Check if the monster can move any monster on the relevant grid.

References compare_monsters(), monster_race::flags, monster::race, rf_has, and square_monster().

Referenced by get_move_advance(), get_move_bodyguard(), and monster_turn_try_push().

◆ monster_can_smell()

static bool monster_can_smell ( struct chunk c,
struct monster mon 
)
static

Check if the monster can smell anything.

References monster::grid, heatmap::grids, monster::race, chunk::scent, monster_race::smell, loc::x, and loc::y.

Referenced by get_move_flee(), and monster_check_active().

◆ monster_check_active()

static bool monster_check_active ( struct chunk c,
struct monster mon 
)
static


Processing routines that happen to a monster regardless of whether it

gets a turn, and/or to decide whether it gets a turn

Determine whether a monster is active or passive

References monster::cdis, monster::grid, monster_race::hearing, monster::hp, monster::maxhp, monster::mflag, mflag_has, mflag_off, mflag_on, monster_can_hear(), monster_can_smell(), monster_passes_walls(), monster_taking_terrain_damage(), monster::race, and square_isview().

Referenced by process_monsters().

◆ monster_hates_grid()

static bool monster_hates_grid ( struct chunk c,
struct monster mon,
struct loc  grid 
)
static

Check if the monster can occupy a grid safely.

References monster_race::flags, monster::race, rf_has, square_feat(), and square_isdamaging().

Referenced by get_move_advance(), get_move_bodyguard(), and monster_turn_can_move().

◆ monster_near_permwall()

static bool monster_near_permwall ( const struct monster mon,
struct chunk c 
)
static


Routines to enable decisions on monster behaviour

From Will Asher in DJA: Find whether a monster is near a permanent wall

this decides whether PASS_WALL & KILL_WALL monsters use the monster flow code

References monster::grid, player::grid, loc(), PROJECT_NONE, projectable(), randint0, square_in_bounds_fully(), square_isperm(), loc::x, and loc::y.

Referenced by get_move_advance().

◆ monster_reduce_sleep()

static void monster_reduce_sleep ( struct chunk c,
struct monster mon 
)
static

Wake a monster or reduce its depth of sleep.

Chance of waking up is dependent only on the player's stealth, but the amount of sleep reduction takes into account the monster's distance from the player. Currently straight line distance is used; possibly this should take into account dungeon structure.

References get_lore(), monster::grid, heatmap::grids, monster_lore::ignore, lore_update(), monster::m_timed, MDESC_CAPITAL, MDESC_IND_HID, mon_dec_timed(), MON_TMD_FLG_NOTIFY, monster_desc(), monster_is_obvious(), monster_wake(), msg, chunk::noise, player_of_has(), monster::race, randint0, SKILL_STEALTH, player_state::skills, player::state, monster_lore::wake, loc::x, and loc::y.

Referenced by process_monster_timed().

◆ monster_turn()

static void monster_turn ( struct chunk c,
struct monster mon 
)
static

Process a monster's turn.

In several cases, we directly update the monster lore

Note that a monster is only allowed to "reproduce" if there are a limited number of "reproducing" monsters on the current level. This should prevent the level from being "swamped" by reproducing monsters. It also allows a large mass of mice to prevent a louse from multiplying, but this is a small price to pay for a simple multiplication method.

XXX Monster fear is slightly odd, in particular, monsters will fixate on opening a door even if they cannot open it. Actually, the same thing happens to normal monsters when they hit a door

In addition, monsters which cannot open or bash down a door will still stand there trying to open it... XXX XXX XXX

Technically, need to check for monster in the way combined with that monster being in a wall (or door?) XXX

References become_aware(), ddd, ddgrid, disturb(), monster_lore::flags, monster_race::flags, get_lore(), get_move(), monster::grid, i, loc_sum(), monster::m_timed, make_attack_normal(), make_ranged_attack(), MDESC_CAPITAL, MDESC_IND_HID, mon_clear_timed(), MON_TMD_FLG_NOTIFY, monster_desc(), monster_group_rouse(), monster_is_camouflaged(), monster_is_in_view(), monster_is_visible(), monster_passes_walls(), monster_swap(), monster_turn_attack_glyph(), monster_turn_can_move(), monster_turn_grab_objects(), monster_turn_multiply(), monster_turn_should_stagger(), monster_turn_try_push(), OPT, monster::race, randint0, rf_has, rf_on, side_dirs, square_destroy_decoy(), square_destroy_trap(), square_isdecoyed(), square_isplayer(), square_isview(), square_iswarded(), square_iswebbed(), and square_monster().

Referenced by process_monsters().

◆ monster_turn_attack_glyph()

static bool monster_turn_attack_glyph ( struct chunk c,
struct monster mon,
struct loc  new 
)
static

◆ monster_turn_can_move()

static bool monster_turn_can_move ( struct chunk c,
struct monster mon,
const char *  m_name,
struct loc  new,
bool *  did_something 
)
static

◆ monster_turn_grab_objects()

void monster_turn_grab_objects ( struct chunk c,
struct monster mon,
const char *  m_name,
struct loc  new 
)

◆ monster_turn_multiply()

static bool monster_turn_multiply ( struct chunk c,
struct monster mon 
)
static

◆ monster_turn_should_stagger()

static bool monster_turn_should_stagger ( struct monster mon)
static

Check if a monster should stagger (that is, step at random) or not.

Always stagger when confused, but also deal with random movement for RAND_25 and RAND_50 monsters.

References CONF_ERRATIC_CHANCE, monster_lore::flags, monster_race::flags, get_lore(), monster_effect_level(), monster_is_visible(), monster::race, randint0, rf_has, and rf_on.

Referenced by monster_turn().

◆ monster_turn_try_push()

static bool monster_turn_try_push ( struct chunk c,
struct monster mon,
const char *  m_name,
struct loc  new 
)
static

◆ multiply_monster()

bool multiply_monster ( struct chunk c,
const struct monster mon 
)


Monster turn routines These routines, culminating in monster_turn(), decide how a monster uses

its turn

Lets the given monster attempt to reproduce.

Note that "reproduction" REQUIRES empty space.

Returns true if the monster successfully reproduced.

References monster::grid, i, place_new_monster(), monster::race, scatter(), and square_isempty().

Referenced by monster_turn_multiply(), and project_monster_handler_MON_CLONE().

◆ process_monster_timed()

static bool process_monster_timed ( struct chunk c,
struct monster mon 
)
static

Process a monster's timed effects, e.g.

decrease them.

Returns true if the monster is skipping its turn.

References monster_race::level, monster::m_timed, monster::mflag, mflag_has, mflag_on, mon_dec_timed(), MON_TMD_FLG_NOTIFY, monster_reduce_sleep(), one_in_, monster::race, randint1, and STUN_MISS_CHANCE.

Referenced by process_monsters().

◆ process_monsters()

void process_monsters ( struct chunk c,
int  minimum_energy 
)


Monster processing routines to be called by the main game loop

Process all the "live" monsters, once per game turn.

During each game turn, we scan through the list of all the "live" monsters, (backwards, so we can excise any "freshly dead" monsters), energizing each monster, and allowing fully energized monsters to move, attack, pass, etc.

This function and its children are responsible for a considerable fraction of the processor time in normal situations, greater if the character is resting.

References cave_monster(), cave_monster_max(), monster::energy, player_upkeep::generate_level, i, player::is_dead, monster::m_timed, monster::mflag, mflag_has, mflag_on, chunk::mon_current, monster_check_active(), monster_effect_level(), monster_is_mimicking(), monster_turn(), angband_constants::move_energy, monster::mspeed, process_monster_timed(), PU_MONSTERS, monster::race, regen_monster(), turn, turn_energy(), player_upkeep::update, player::upkeep, and z_info.

Referenced by run_game_loop().

◆ regen_monster()

static void regen_monster ( struct monster mon,
int  num 
)
static

◆ reset_monsters()

void reset_monsters ( void  )

Clear 'moved' status from all monsters.

Clear noise if appropriate.

References cave, cave_monster(), cave_monster_max(), i, monster::mflag, mflag_off, and monster_take_terrain_damage().

Referenced by run_game_loop().

◆ restore_monsters()

void restore_monsters ( void  )