Angband
Macros | Functions | Variables
mon-make.c File Reference

Monster creation / placement code. More...

#include "angband.h"
#include "alloc.h"
#include "game-world.h"
#include "init.h"
#include "mon-desc.h"
#include "mon-lore.h"
#include "mon-make.h"
#include "mon-timed.h"
#include "mon-util.h"
#include "obj-identify.h"
#include "obj-make.h"
#include "obj-pile.h"
#include "obj-tval.h"
#include "obj-util.h"
#include "player-history.h"
#include "player-quest.h"
#include "target.h"

Macros

#define GROUP_MAX   25
#define GROUP_DISTANCE   5

Functions

static void init_race_allocs (void)
static void cleanup_race_allocs (void)
void delete_monster_idx (int m_idx)
 Deletes a monster by index.
void delete_monster (int y, int x)
 Deletes the monster, if any, at the given location.
static void compact_monsters_aux (int i1, int i2)
 Move a monster from index i1 to index i2 in the monster list.
void compact_monsters (int num_to_compact)
 Compacts and reorders the monster list.
void wipe_mon_list (struct chunk *c, struct player *p)
 Deletes all the monsters when the player leaves the level.
s16b mon_pop (struct chunk *c)
 Returns the index of a "free" monster, or 0 if no slot is available.
void get_mon_num_prep (bool(*get_mon_num_hook)(struct monster_race *race))
 Apply a "monster restriction function" to the "monster allocation table".
static struct monster_raceget_mon_race_aux (long total, const alloc_entry *table)
 Helper function for get_mon_num().
struct monster_raceget_mon_num (int level)
 Chooses a monster race that seems "appropriate" to the given level.
int mon_create_drop_count (const struct monster_race *race, bool maximize)
 Return the number of things dropped by a monster.
static bool mon_create_drop (struct chunk *c, struct monster *mon, byte origin)
 Creates a specific monster's drop, including any drops specified in the monster.txt file.
s16b place_monster (struct chunk *c, int y, int x, struct monster *mon, byte origin)
 Attempts to place a copy of the given monster at the given position in the dungeon.
int mon_hp (const struct monster_race *race, aspect hp_aspect)
 Calculates hp for a monster.
static bool place_new_monster_one (struct chunk *c, int y, int x, struct monster_race *race, bool sleep, byte origin)
 Attempts to place a monster of the given race at the given location.
static bool place_new_monster_group (struct chunk *c, int y, int x, struct monster_race *race, bool sleep, int total, byte origin)
 Attempts to place a group of monsters of race r_idx around the given location.
static bool place_monster_base_okay (struct monster_race *race)
 Predicate function for get_mon_num_prep) Check to see if the monster race has the same base as place_monter_base.
bool place_friends (struct chunk *c, int y, int x, struct monster_race *race, struct monster_race *friends_race, int total, bool sleep, byte origin)
 Helper function to place monsters that appear as friends or escorts.
bool place_new_monster (struct chunk *c, int y, int x, struct monster_race *race, bool sleep, bool group_okay, byte origin)
 Attempts to place a monster of the given race at the given location.
bool pick_and_place_monster (struct chunk *c, int y, int x, int depth, bool sleep, bool group_okay, byte origin)
 Picks a monster race, makes a new monster of that race, then attempts to place it in the dungeon.
bool pick_and_place_distant_monster (struct chunk *c, struct loc loc, int dis, bool sleep, int depth)
 Picks a monster race, makes a new monster of that race, then attempts to place it in the dungeon at least dis away from the player.
void monster_death (struct monster *mon, bool stats)
 Handles the "death" of a monster.
bool mon_take_hit (struct monster *mon, int dam, bool *fear, const char *note)
 Decreases a monster's hit points by dam and handle monster death.

Variables

s16b num_repro
 Variables.
static s16b alloc_race_size
static struct alloc_entryalloc_race_table
static monster_baseplace_monster_base = NULL
struct init_module mon_make_module

Detailed Description

Monster creation / placement code.

Copyright (c) 1997-2007 Ben Harrison, James E. Wilson, Robert A. Koeneke

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.

Macro Definition Documentation

#define GROUP_DISTANCE   5

Referenced by place_friends().

#define GROUP_MAX   25

Referenced by place_new_monster_group().

Function Documentation

static void cleanup_race_allocs ( void  )
static

References mem_free().

void compact_monsters ( int  num_to_compact)

Compacts and reorders the monster list.

This function can be very dangerous, use with caution!

When num_to_compact is 0, we just reorder the monsters into a more compact order, eliminating any "holes" left by dead monsters. If num_to_compact is positive, then we delete at least that many monsters and then reorder. We try not to delete monsters that are high level or close to the player. Each time we make a full pass through the monster list, if we haven't deleted enough monsters, we relax our bounds a little to accept monsters of a slightly higher level, and monsters slightly closer to the player.

References cave, cave_monster(), cave_monster_max(), monster::cdis, compact_monsters_aux(), delete_monster(), monster_race::flags, monster::fx, monster::fy, monster_race::level, chunk::mon_max, msg, monster::race, randint0, and rf_has.

Referenced by process_world(), and wr_dungeon().

static void compact_monsters_aux ( int  i1,
int  i2 
)
static
void delete_monster ( int  y,
int  x 
)
void delete_monster_idx ( int  m_idx)
struct monster_race* get_mon_num ( int  level)
read

Chooses a monster race that seems "appropriate" to the given level.

This function uses the "prob2" field of the "monster allocation table", and various local information, to calculate the "prob3" field of the same table, which is then used to choose an "appropriate" monster, in a relatively efficient manner.

Note that "town" monsters will only be created in the town, and "normal" monsters will never be created in the town, unless the "level" is "modified", for example, by polymorph or summoning.

There is a small chance (1/50) of "boosting" the given depth by a small amount (up to four levels), except in the town.

It is (slightly) more likely to acquire a monster of the given level than one of a lower level. This is done by choosing several monsters appropriate to the given level and keeping the "hardest" one.

Note that if no monsters are "appropriate", then this function will fail, and return zero, but this should almost never happen.

References alloc_race_size, alloc_race_table, monster_race::cur_num, player::depth, monster_race::flags, get_mon_race_aux(), i, alloc_entry::index, monster_race::level, monster_race::max_num, MIN, one_in_, angband_constants::ood_monster_amount, angband_constants::ood_monster_chance, p, alloc_entry::prob3, r_info, randint0, rf_has, and z_info.

Referenced by build_nest(), build_pit(), get_chamber_monsters(), get_vault_monsters(), pick_and_place_monster(), place_new_monster(), poly_race(), spread_monsters(), and summon_specific().

void get_mon_num_prep ( bool(*)(struct monster_race *race)  get_mon_num_hook)

Apply a "monster restriction function" to the "monster allocation table".

This way, we can use get_mon_num() to get a level-appropriate monster that satisfies certain conditions (such as belonging to a particular monster family).

References alloc_race_size, i, alloc_entry::index, alloc_entry::prob1, alloc_entry::prob2, and r_info.

Referenced by build_nest(), build_pit(), get_vault_monsters(), mon_restrict(), place_new_monster(), and summon_specific().

static struct monster_race* get_mon_race_aux ( long  total,
const alloc_entry table 
)
staticread

Helper function for get_mon_num().

Scans the prepared monster allocation table and picks a random monster. Returns the index of a monster in table.

References alloc_race_size, i, alloc_entry::index, alloc_entry::prob3, r_info, randint0, and value.

Referenced by get_mon_num().

static void init_race_allocs ( void  )
static
static bool mon_create_drop ( struct chunk c,
struct monster mon,
byte  origin 
)
static
int mon_create_drop_count ( const struct monster_race race,
bool  maximize 
)

Return the number of things dropped by a monster.

Parameters
raceis the monster race.
maximizeshould be set to FALSE for a random number, TRUE to find out the maximum count.

References monster_race::flags, rand_range(), randint0, and rf_has.

Referenced by lore_append_drop(), and mon_create_drop().

int mon_hp ( const struct monster_race race,
aspect  hp_aspect 
)

Calculates hp for a monster.

This function assumes that the Rand_normal function has limits of +/- 4x std_dev. If that changes, this function will become inaccurate.

Parameters
raceis the race of the monster in question.
hp_aspectis the hp calc we want (min, max, avg, random).

References AVERAGE, monster_race::avg_hp, EXTREMIFY, MAXIMISE, MINIMISE, Rand_normal(), and RANDOMISE.

Referenced by best_spell_power(), and place_new_monster_one().

s16b mon_pop ( struct chunk c)

Returns the index of a "free" monster, or 0 if no slot is available.

This routine should almost never fail, but it can happen. The calling code must check for and handle a 0 return.

References cave_monster(), cave_monster_max(), character_dungeon, angband_constants::level_monster_max, chunk::mon_cnt, chunk::mon_max, msg, monster::race, and z_info.

Referenced by chunk_copy(), and place_monster().

bool mon_take_hit ( struct monster mon,
int  dam,
bool fear,
const char *  note 
)

Decreases a monster's hit points by dam and handle monster death.

Hack – we "delay" fear messages by passing around a "fear" flag.

We announce monster death (using an optional "death message" (note) if given, and a otherwise a generic killed/destroyed message).

Returns TRUE if the monster has been killed (and deleted).

TODO: Consider decreasing monster experience over time, say, by using "(m_exp * m_lev * (m_lev)) / (p_lev * (m_lev + n_killed))" instead of simply "(m_exp * m_lev) / (p_lev)", to make the first monster worth more than subsequent monsters. This would also need to induce changes in the monster recall code. XXX XXX XXX

References monster_race::base, become_aware(), buf, delete_monster_idx(), player::exp_frac, FALSE, monster_race::flags, format(), get_lore(), player_upkeep::health_who, history_add(), monster::hp, player::lev, monster_race::level, lookup_monster_base(), lore_update(), monster::m_timed, monster_race::max_num, MAX_SHORT, monster::maxhp, MDESC_DEFAULT, MDESC_DIED_FROM, monster_race::mexp, monster::mflag, mflag_has, monster::midx, mon_clear_timed(), mon_dec_timed(), mon_inc_timed(), MON_TMD_FLG_NOFAIL, MON_TMD_FLG_NOMESSAGE, monster_death(), monster_desc(), monster_is_unusual(), monster_race_track(), msgt(), my_strcap(), monster_lore::pkills, player_exp_gain(), PR_HEALTH, monster::race, randint0, randint1, player_upkeep::redraw, rf_has, strnfmt(), monster_lore::tkills, TRUE, and player::upkeep.

Referenced by project_m_player_attack(), py_attack_real(), and ranged_helper().

void monster_death ( struct monster mon,
bool  stats 
)

Handles the "death" of a monster.

Disperses treasures carried by the monster centered at the monster location. Note that objects dropped may disappear in crowded rooms.

Checks for "Quest" completion when a quest monster is killed.

Note that only the player can induce "monster_death()" on Uniques. Thus (for now) all Quest monsters should be Uniques.

If stats is true, then we skip updating the monster memory. This is used by stats-generation code, for efficiency.

References cave, drop_near(), monster_race::flags, monster::fx, monster::fy, object::held_m_idx, monster::held_obj, lore_treasure(), monster::mflag, mflag_has, monster::mimicked_obj, object::next, object_delete(), object::origin, pile_excise(), PR_MONLIST, quest_check(), monster::race, player_upkeep::redraw, rf_has, TRUE, tval_is_money(), and player::upkeep.

Referenced by mon_take_hit(), and project_m_monster_attack().

bool pick_and_place_distant_monster ( struct chunk c,
struct loc loc  ,
int  dis,
bool  sleep,
int  depth 
)

Picks a monster race, makes a new monster of that race, then attempts to place it in the dungeon at least dis away from the player.

The monster race chosen will be appropriate for dungeon level equal to depth.

If sleep is true, the monster is placed with its default sleep value, which is given in monster.txt.

Returns TRUE if we successfully place a monster.

References character_dungeon, distance(), FALSE, chunk::height, msg, OPT, pick_and_place_monster(), randint0, square_isempty(), square_ismon_restrict(), TRUE, chunk::width, loc::x, and loc::y.

Referenced by cavern_gen(), classic_gen(), gauntlet_gen(), hard_centre_gen(), labyrinth_gen(), lair_gen(), modified_gen(), moria_gen(), process_world(), and town_gen().

bool pick_and_place_monster ( struct chunk c,
int  y,
int  x,
int  depth,
bool  sleep,
bool  group_okay,
byte  origin 
)

Picks a monster race, makes a new monster of that race, then attempts to place it in the dungeon.

The monster race chosen will be appropriate for dungeon level equal to depth.

If sleep is true, the monster is placed with its default sleep value, which is given in monster.txt.

If group_okay is true, we allow the placing of a group, if the chosen monster appears with friends or an escort.

origin is the item origin to use for any monster drops (e.g. ORIGIN_DROP, ORIGIN_DROP_PIT, etc.)

Returns TRUE if we successfully place a monster.

References FALSE, get_mon_num(), and place_new_monster().

Referenced by build_vault(), get_chamber_monsters(), get_vault_monsters(), pick_and_place_distant_monster(), spread_monsters(), and vault_monsters().

bool place_friends ( struct chunk c,
int  y,
int  x,
struct monster_race race,
struct monster_race friends_race,
int  total,
bool  sleep,
byte  origin 
)
s16b place_monster ( struct chunk c,
int  y,
int  x,
struct monster mon,
byte  origin 
)

Attempts to place a copy of the given monster at the given position in the dungeon.

All of the monster placement routines eventually call this function. This is what actually puts the monster in the dungeon (i.e., it notifies the cave and sets the monsters position). The dungeon loading code also calls this function directly.

origin is the item origin to use for any monster drops (e.g. ORIGIN_DROP, ORIGIN_DROP_PIT, etc.) The dungeon loading code calls this with origin = 0, which prevents the monster's drops from being generated again.

Returns the m_idx of the newly copied monster, or 0 if the placement fails.

References apply_magic(), cave_monster(), monster_race::cur_num, player::depth, FALSE, monster_race::flags, floor_carry(), monster::fx, monster::fy, i, monster_mimic::kind, monster_race::level, lookup_kind(), make_gold(), monster::midx, monster_race::mimic_kinds, monster::mimicked_obj, object::mimicking_m_idx, square::mon, mon_create_drop(), mon_pop(), object_kind::name, monster_mimic::next, num_repro, object::number, object_new(), object_prep(), one_in_, object::origin, monster::race, RANDOMISE, rf_has, square_in_bounds(), square_monster(), chunk::squares, object_kind::sval, TRUE, tval_is_money_k(), update_mon(), and void().

Referenced by rd_monsters_aux().

static bool place_monster_base_okay ( struct monster_race race)
static

Predicate function for get_mon_num_prep) Check to see if the monster race has the same base as place_monter_base.

References monster_race::base, FALSE, monster_race::flags, rf_has, and TRUE.

Referenced by place_new_monster().

bool place_new_monster ( struct chunk c,
int  y,
int  x,
struct monster_race race,
bool  sleep,
bool  group_okay,
byte  origin 
)

Attempts to place a monster of the given race at the given location.

Note that certain monsters are placed with a large group of identical or similar monsters. However, if group_okay is false, then such monsters are placed by themselves.

If sleep is true, the monster is placed with its default sleep value, which is given in monster.txt.

origin is the item origin to use for any monster drops (e.g. ORIGIN_DROP, ORIGIN_DROP_PIT, etc.)

References monster_friends_base::base, damroll(), FALSE, monster_race::friends, monster_race::friends_base, get_mon_num(), get_mon_num_prep(), monster_race::level, monster_friends::next, monster_friends_base::next, monster_friends::number_dice, monster_friends_base::number_dice, monster_friends::number_side, monster_friends_base::number_side, monster_friends::percent_chance, monster_friends_base::percent_chance, place_friends(), place_monster_base_okay(), place_new_monster_one(), monster_friends::race, randint0, and TRUE.

Referenced by build_nest(), build_pit(), cave_generate(), do_cmd_wiz_named(), multiply_monster(), pick_and_place_monster(), project_m_apply_side_effects(), and summon_specific().

static bool place_new_monster_group ( struct chunk c,
int  y,
int  x,
struct monster_race race,
bool  sleep,
int  total,
byte  origin 
)
static

Attempts to place a group of monsters of race r_idx around the given location.

The number of monsters to place is total.

If sleep is true, the monster is placed with its default sleep value, which is given in monster.txt.

origin is the item origin to use for any monster drops (e.g. ORIGIN_DROP, ORIGIN_DROP_PIT, etc.)

References ddx_ddd, ddy_ddd, GROUP_MAX, i, place_new_monster_one(), square_isempty(), and TRUE.

Referenced by place_friends().

static bool place_new_monster_one ( struct chunk c,
int  y,
int  x,
struct monster_race race,
bool  sleep,
byte  origin 
)
static

Attempts to place a monster of the given race at the given location.

If sleep is true, the monster is placed with its default sleep value, which is given in monster.txt.

origin is the item origin to use for any monster drops (e.g. ORIGIN_DROP, ORIGIN_DROP_PIT, etc.)

To give the player a sporting chance, some especially dangerous monsters are marked as "FORCE_SLEEP" in monster.txt, which will cause them to be placed with low energy. This helps ensure that if such a monster suddenly appears in line-of-sight (due to a summon, for instance), the player gets a chance to move before they do.

This routine refuses to place out-of-depth "FORCE_DEPTH" monsters.

This is the only function which may place a monster in the dungeon, except for the savefile loading code, which calls place_monster() directly.

References monster_race::avg_hp, monster_race::cur_num, player::depth, FALSE, monster_race::flags, i, monster_race::level, monster::m_timed, MAX, monster_race::max_num, monster::maxhp, mon_hp(), chunk::mon_rating, msg, monster_race::name, OPT, monster_race::power, monster::race, randint1, RANDOMISE, rf_has, monster_race::sleep, square_in_bounds(), square_is_monster_walkable(), square_iswarded(), and square_monster().

Referenced by place_friends(), place_new_monster(), and place_new_monster_group().

void wipe_mon_list ( struct chunk c,
struct player p 
)

Deletes all the monsters when the player leaves the level.

This is an efficient method of simulating multiple calls to the "delete_monster()" function, with no visual effects.

Note that we do not delete the objects the monsters are carrying; that must be taken care of separately via wipe_o_list().

References cave_monster(), cave_monster_max(), monster_race::cur_num, monster::fx, monster::fy, health_track(), square::mon, chunk::mon_cnt, chunk::mon_max, num_repro, monster::race, chunk::squares, target_set_monster(), and player::upkeep.

Variable Documentation

s16b alloc_race_size
static
struct alloc_entry* alloc_race_table
static

Referenced by get_mon_num(), and init_race_allocs().

struct init_module mon_make_module
Initial value:
{
.name = "monster/mon-make",
}
s16b num_repro
monster_base* place_monster_base = NULL
static