#ifndef MONPLACE_H
#define MONPLACE_H
#include "coord.h"
#include "enum.h"
#include "dungeon.h"
#include "fixvec.h"
enum band_type
{
BAND_NO_BAND = 0,
BAND_KOBOLDS,
BAND_ORCS,
BAND_ORC_WARRIOR,
BAND_ORC_KNIGHT,
BAND_KILLER_BEES, BAND_FLYING_SKULLS,
BAND_SLIME_CREATURES,
BAND_YAKS,
BAND_UGLY_THINGS,
BAND_HELL_HOUNDS, BAND_JACKALS,
BAND_HELL_KNIGHTS,
BAND_ORC_HIGH_PRIEST,
BAND_GNOLLS, BAND_BUMBLEBEES = 16,
BAND_CENTAURS,
BAND_YAKTAURS,
BAND_INSUBSTANTIAL_WISPS,
BAND_OGRE_MAGE, BAND_DEATH_YAKS,
BAND_NECROMANCER,
BAND_BALRUG,
BAND_CACODEMON,
BAND_EXECUTIONER, BAND_HELLWING,
BAND_DEEP_ELF_FIGHTER,
BAND_DEEP_ELF_KNIGHT,
BAND_DEEP_ELF_HIGH_PRIEST,
BAND_KOBOLD_DEMONOLOGIST, BAND_NAGAS,
BAND_WAR_DOGS,
BAND_GREY_RATS,
BAND_GREEN_RATS,
BAND_ORANGE_RATS, BAND_SHEEP,
BAND_GHOULS,
BAND_DEEP_TROLLS,
BAND_HOGS,
BAND_HELL_HOGS, BAND_GIANT_MOSQUITOES,
BAND_BOGGARTS,
BAND_BLINK_FROGS,
BAND_SKELETAL_WARRIORS,
BAND_DRACONIAN, BAND_PANDEMONIUM_DEMON,
BAND_HARPIES,
BAND_ILSUIW,
BAND_AZRAEL,
BAND_DUVESSA, BAND_KHUFU,
NUM_BANDS };
enum demon_class_type
{
DEMON_LESSER, DEMON_COMMON, DEMON_GREATER, DEMON_RANDOM };
enum holy_being_class_type
{
HOLY_BEING_WARRIOR };
enum dragon_class_type
{
DRAGON_LIZARD,
DRAGON_DRACONIAN,
DRAGON_DRAGON
};
enum proximity_type {
PROX_ANYWHERE,
PROX_CLOSE_TO_PLAYER,
PROX_AWAY_FROM_PLAYER,
PROX_NEAR_STAIRS
};
enum mgen_flag_type
{
MG_PERMIT_BANDS = 0x01,
MG_FORCE_PLACE = 0x02,
MG_FORCE_BEH = 0x04,
MG_PLAYER_MADE = 0x08,
MG_PATROLLING = 0x10
};
struct mgen_data
{
monster_type cls;
monster_type base_type;
beh_type behaviour;
int abjuration_duration;
int summon_type;
coord_def pos;
unsigned short foe;
unsigned flags;
god_type god;
int number;
int colour;
int power;
proximity_type proximity;
level_area_type level_type;
unsigned map_mask;
std::string mname;
mgen_data(monster_type mt = RANDOM_MONSTER,
beh_type beh = BEH_HOSTILE,
int abj = 0,
int st = 0,
const coord_def &p = coord_def(-1, -1),
unsigned short mfoe = MHITNOT,
unsigned monflags = 0,
god_type which_god = GOD_NO_GOD,
monster_type base = MONS_NO_MONSTER,
int monnumber = 0,
int moncolour = BLACK,
int monpower = you.your_level,
proximity_type prox = PROX_ANYWHERE,
level_area_type ltype = you.level_type,
std::string monname = "")
: cls(mt), base_type(base), behaviour(beh),
abjuration_duration(abj), summon_type(st), pos(p), foe(mfoe),
flags(monflags), god(which_god), number(monnumber), colour(moncolour),
power(monpower), proximity(prox), level_type(ltype), map_mask(0),
mname(monname)
{
ASSERT(summon_type == 0 || (abj >= 1 && abj <= 6)
|| mt == MONS_BALL_LIGHTNING);
}
bool permit_bands() const { return (flags & MG_PERMIT_BANDS); }
bool force_place() const { return (flags & MG_FORCE_PLACE); }
bool needs_patrol_point() const { return (flags & MG_PATROLLING); }
bool use_position() const { return in_bounds(pos); }
bool summoned() const { return (abjuration_duration > 0); }
static mgen_data sleeper_at(monster_type what,
const coord_def &where,
unsigned flags = 0)
{
return mgen_data(what, BEH_SLEEP, 0, 0, where, MHITNOT, flags);
}
static mgen_data hostile_at(monster_type what,
const coord_def &where,
int abj_deg = 0,
unsigned flags = 0,
bool alert = false,
god_type god = GOD_NO_GOD,
int summon_type = 0)
{
return mgen_data(what, BEH_HOSTILE, abj_deg, summon_type, where,
alert ? MHITYOU : MHITNOT,
flags, god);
}
};
int create_monster(mgen_data mg, bool fail_msg = true);
int mons_place(mgen_data mg);
int place_monster(mgen_data mg, bool force_pos = false);
monster_type pick_local_zombifiable_monster_type(int power);
class level_id;
monster_type pick_random_monster(const level_id &place);
monster_type pick_random_monster(const level_id &place,
int power,
int &lev_mons);
bool player_will_anger_monster(monster_type type, bool *holy = NULL,
bool *unholy = NULL, bool *lawful = NULL,
bool *antimagical = NULL);
bool player_will_anger_monster(monsters *mon, bool *holy = NULL,
bool *unholy = NULL, bool *lawful = NULL,
bool *antimagical = NULL);
bool player_angers_monster(monsters *mon);
bool empty_surrounds( const coord_def& where, dungeon_feature_type spc_wanted,
int radius, bool allow_centre, coord_def& empty );
monster_type summon_any_demon(demon_class_type dct);
monster_type summon_any_holy_being(holy_being_class_type hbct);
monster_type summon_any_dragon(dragon_class_type dct);
bool drac_colour_incompatible(int drac, int colour);
void mark_interesting_monst(monsters* monster,
beh_type behaviour = BEH_SLEEP);
bool feat_compatible(dungeon_feature_type grid_wanted,
dungeon_feature_type actual_grid);
bool monster_habitable_grid(const monsters *m,
dungeon_feature_type actual_grid);
bool monster_habitable_grid(monster_type montype,
dungeon_feature_type actual_grid,
int flies = -1,
bool paralysed = false);
bool monster_can_submerge(const monsters *mons, dungeon_feature_type grid);
coord_def find_newmons_square(int mons_class, const coord_def &p);
coord_def find_newmons_square_contiguous(monster_type mons_class,
const coord_def &start,
int maxdistance = 3);
void spawn_random_monsters();
void set_vault_mon_list(const std::vector<mons_spec> &list);
void get_vault_mon_list(std::vector<mons_spec> &list);
void setup_vault_mon_list();
int mons_tracking_range(const monsters *mon);
class monster_pathfind
{
public:
monster_pathfind();
virtual ~monster_pathfind();
void set_range(int r);
coord_def next_pos(const coord_def &p) const;
bool init_pathfind(const monsters *mon, coord_def dest,
bool diag = true, bool msg = false,
bool pass_unmapped = false);
bool init_pathfind(coord_def src, coord_def dest,
bool diag = true, bool msg = false);
bool start_pathfind(bool msg = false);
std::vector<coord_def> backtrack(void);
std::vector<coord_def> calc_waypoints(void);
protected:
bool calc_path_to_neighbours(void);
bool traversable(coord_def p);
int travel_cost(coord_def npos);
bool mons_traversable(coord_def p);
int mons_travel_cost(coord_def npos);
int estimated_cost(coord_def npos);
void add_new_pos(coord_def pos, int total);
void update_pos(coord_def pos, int total);
bool get_best_position(void);
const monsters *mons;
coord_def start, target, pos;
bool allow_diagonals;
bool traverse_unmapped;
int range;
int min_length;
int max_length;
int dist[GXM][GYM];
int prev[GXM][GYM];
FixedVector<std::vector<coord_def>, GXM * GYM> hash;
};
#endif