55 #define MIN_MON_RADIUS 3 81 else if (npc->
enemy == NULL)
111 || npc->
enemy == owner))
184 LOG(
llevDebug,
"monster_find_nearest_living_creature: map %s (%d,%d) has is_alive set but did not find a monster?\n", m->
path, nx, ny);
210 object *attacker, *tmp = NULL;
350 if (talked && strlen(talked) > 0) {
367 for (i = 0; i < 15; i++) {
375 #define MAX_EXPLORE 5000 394 unsigned short *distance;
396 int current = 0, dir, max = 1, x, y, i;
398 if (target->
map != source->
map)
407 const int size = cur_map->
width * map_height;
422 for (i = 1; i <= 8; ++i)
452 distance = malloc(size *
sizeof(*distance));
453 if (distance == NULL) {
467 memset(distance, 255,
sizeof(*distance) * size);
469 distance[map_height * target->
x + target->
y] = 0;
470 explore_x[0] = target->
x;
471 explore_y[0] = target->
y;
480 for (i = 1; i < 8; ++i) {
486 for (i = 0; i < 8; ++i) {
487 unsigned short new_distance;
492 dir =
absdir(default_dir+4+dirs[i]);
496 if (x == source->
x && y == source->
y) {
505 assert(map_height * x + y >= 0);
506 assert(map_height * x + y < size);
509 distance[map_height * explore_x[current] + explore_y[current]]
513 + ((dir & 1) == 0 ? 3 : 2);
516 if (distance[map_height * x + y] <= new_distance)
521 if (distance[map_height * x + y] == 65535 &&
ob_blocked(source, cur_map, x, y))
526 distance[map_height * x + y] = 1;
541 distance[map_height * x + y] = new_distance;
551 }
while (current < max);
701 object *owner, *enemy, *part;
765 if (op->
race != NULL && strcmp(op->
race,
"doppleganger") == 0) {
894 for (diff = 1; diff <= maxdiff; diff++) {
927 if (nearest_player && nearest_player != enemy && !
monster_can_hit(part, enemy, &rv)) {
929 enemy = nearest_player;
986 for (more = ob2->
more; more != NULL; more = more->
more) {
1018 assert(spell_ob != NULL);
1039 #define MAX_KNOWN_SPELLS 20 1075 return altern[
RANDOM()%i];
1111 if (owner != NULL) {
1128 if (spell_item == NULL) {
1134 if (!spell_item->
inv) {
1135 LOG(
llevError,
"spellbook %s does not contain a spell?\n", spell_item->
name);
1138 spell_item = spell_item->
inv;
1163 return cast_spell(part, part, dir, spell_item, NULL);
1197 if (owner != NULL) {
1274 if (owner != NULL) {
1299 LOG(
llevDebug,
"Error: Monster %s (%d) has FLAG_READY_SKILL without skill.\n", head->
name, head->
count);
1323 int at_least_one = 0;
1331 if (owner != NULL) {
1342 if (wand->type ==
WAND) {
1345 if (wand->stats.food <= 0)
1355 if (wand->type ==
ROD) {
1358 if (wand->stats.hp <
MAX(wand->inv->stats.sp, wand->inv->stats.grace))
1376 LOG(
llevError,
"Error: Monster %s (%d) HAS_READY_RANG() without wand/horn/rod.\n", head->
name, head->
count);
1422 while (x != pl->
x || y != pl->
y || map != pl->
map) {
1427 LOG(
llevError,
"monster_use_bow: no map but still path exists??\n");
1432 if (owner && owner->
x == x && owner->
y == y && owner->
map == map)
1443 return fire_bow(head, NULL, dir, 0, part->
x, part->
y);
1459 val += item->
magic*3;
1485 if (other_weap == NULL)
1511 val += item->
magic*3;
1528 object *other_armour;
1532 if (other_armour == NULL)
1566 && mon->
arch != NULL
1620 }
else if (item->
type ==
BOW) {
1682 for (part = monster; part != NULL; part = part->
more)
1693 if (tmp->weight > 0) {
1698 nrof = (weight_limit-monster->
weight-monster->
carrying)/tmp->weight;
1702 nrof =
MAX(1, tmp->nrof);
1743 else switch (item->
type) {
1793 if (((!(monster->
pick_up&32)) && flag) || ((monster->
pick_up&32) && (!flag)))
1806 switch (tmp->type) {
1828 if (!monster->
head) {
1841 const int help_radius = 3;
1842 for (
int x = -help_radius; x <= help_radius; x++)
1843 for (
int y = -help_radius; y <= help_radius; y++) {
1975 static const int circle [12] = { 3, 3, 4, 5, 5, 6, 7, 7, 8, 1, 1, 2 };
1988 static const int circle[20] = { 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 1, 1, 1, 2, 2 };
2062 for (i = 0; i < 5; i++) {
2094 if (tmp->type ==
DOOR) {
2218 if (orig_map != op->
map) {
2219 LOG(
llevDebug,
"Warning: Forced to swap out very recent map\n");
2231 snprintf(own,
sizeof(own),
"You say: %s", txt);
2232 snprintf(others,
sizeof(others),
"%s says: %s", op->
name, txt);
2286 value[0] =
'3' + rand() % 6;
2295 reply = reply->
next;
2336 if (info->
who == npc)
2365 LOG(
llevDebug,
"%s chooses to throw: %s (%d)\n", op->
name, what, tmp->count);
2396 if (!op || !enemy || !op->
map || !enemy->
map)
2435 if (sk_hide != NULL)
2436 bonus -= sk_hide->
level;
2438 LOG(
llevError,
"monster_can_detect_enemy() got hidden player w/o hiding skill!\n");
2443 bonus -= enemy->
level;
2446 hide_discovery += bonus*5;
2452 radius = radius/2, hide_discovery = hide_discovery/3;
2467 if (radius < MIN_MON_RADIUS && op->map->darkness < 5 && rv->
distance <= 1)
2489 if (enemy->
hide && rv->
distance <= 1 &&
RANDOM()%100 <= (
unsigned int)hide_discovery) {
2494 "You are discovered by %s!",
2505 if (
RANDOM()%50 <= (
unsigned int)hide_discovery) {
2511 "You see %s noticing your position.",
2556 x1 = abs(x-op->
x)*abs(x-op->
x);
2557 y1 = abs(y-op->
y)*abs(y-op->
y);
2576 object *looker =
HEAD(op);
2598 "Your light reveals your hiding spot!");
2601 }
else if (enemy->
hide)
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
int get_dialog_message(object *op, const char *text, struct_dialog_message **message, struct_dialog_reply **reply)
#define NUM_BODY_LOCATIONS
int apply_manual(object *op, object *tmp, int aflag)
static int monster_use_scroll(object *head, object *part, object *pl, int dir)
static int monster_check_good_armour(object *who, object *item)
void monster_npc_say(object *npc, const char *cp)
static int monster_hitrun_att(int dir, object *ob, object *enemy)
static int monster_should_cast_spell(object *spell_ob)
sstring add_refcount(sstring str)
int makes_invisible_to(object *pl, object *mon)
object * object_find_by_type_applied(const object *who, int type)
void pets_follow_owner(object *ob, object *owner)
void monster_do_living(object *op)
void drain_wand_charge(object *wand)
#define MSG_TYPE_DIALOG_MAGIC_EAR
static int monster_get_weapon_quality(const object *item)
sstring stringbuffer_finish_shared(StringBuffer *sb)
void fatal(enum fatal_error err)
void pets_move(object *ob)
StringBuffer * stringbuffer_new(void)
void get_search_arr(int *search_arr)
void free_string(sstring str)
static const char * get_reply_text_other(reply_type rt)
int monster_compute_path(object *source, object *target, int default_dir)
mapstruct * get_map_from_coord(mapstruct *m, int16_t *x, int16_t *y)
const char * object_get_value(const object *op, const char *const key)
sstring replies[MAX_REPLIES]
static object * monster_find_enemy(object *npc, rv_vector *rv)
short freearr_x[SIZEOFFREE]
int16_t SP_level_spellpoint_cost(object *caster, object *spell, int flags)
sstring replies_words[MAX_REPLIES]
static int monster_cast_spell(object *head, object *part, object *pl, int dir)
#define OUT_OF_REAL_MAP(M, X, Y)
int apply_can_apply_object(const object *who, const object *op)
int8_t get_attr_value(const living *stats, int attr)
void remove_friendly_object(object *op)
#define MSG_TYPE_DIALOG_NPC
uint32_t get_weight_limit(int stat)
int player_can_view(object *pl, object *op)
int path_to_player(object *mon, object *pl, unsigned mindiff)
static int monster_talk_to_npc(object *npc, talk_info *info)
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
int plugin_event_say(object *npc, talk_info *talk)
static int monster_wait_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv)
short freearr_y[SIZEOFFREE]
static void monster_pace2_moveh(object *ob)
static int monster_dist_att(int dir, object *enemy, object *part, rv_vector *rv)
#define FLAG_SEE_INVISIBLE
static void monster_circ1_move(object *ob)
struct obj * chosen_skill
int object_set_value(object *op, const char *key, const char *value, int add_key)
void object_free_drop_inventory(object *ob)
int dirdiff(int dir1, int dir2)
void do_hidden_move(object *op)
int monster_can_see_enemy(object *op, object *enemy)
static void monster_rand_move(object *ob)
int get_randomized_dir(int dir)
static int monster_get_armour_quality(const object *item)
int object_can_pick(const object *who, const object *item)
object * object_insert_in_ob(object *op, object *where)
#define FLAG_READY_SCROLL
#define FLAG_CAN_USE_SKILL
void drain_rod_charge(object *rod)
#define FLAG_UNAGGRESSIVE
static StringBuffer * monster_format_say(const object *npc, const char *message)
int ob_blocked(const object *ob, mapstruct *m, int16_t x, int16_t y)
void monster_do_say(const mapstruct *map, const char *message)
static int monster_check_good_weapon(object *who, object *item)
object * get_nearest_player(object *mon)
int pets_should_arena_attack(object *pet, object *owner, object *target)
#define WILL_APPLY_TREASURE
void monster_check_apply_all(object *monster)
object * monster_find_nearest_living_creature(object *npc)
static int monster_can_hit(object *ob1, object *ob2, rv_vector *rv)
static int monster_wait_att2(int dir, rv_vector *rv)
static void monster_pace2_movev(object *ob)
#define MSG_TYPE_COMMUNICATION_SAY
void ext_info_map_except(int color, const mapstruct *map, const object *op, uint8_t type, uint8_t subtype, const char *str1)
int is_true_undead(object *op)
#define MSG_TYPE_COMMUNICATION
object * monster_find_throw_ob(object *op)
void monster_communicate(object *op, const char *txt)
#define GET_MAP_LIGHT(M, X, Y)
void monster_check_earthwalls(object *op, mapstruct *m, int x, int y)
static object * monster_choose_random_spell(object *monster)
#define GET_MAP_MOVE_BLOCK(M, X, Y)
int do_skill(object *op, object *part, object *skill, int dir, const char *string)
static int monster_disthit_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv)
#define MSG_TYPE_SKILL_FAILURE
static int monster_move_randomly(object *op)
static void monster_pace_moveh(object *ob)
object * object_find_by_type_and_race(const object *who, int type, const char *race)
int on_same_map(const object *op1, const object *op2)
#define CAN_APPLY_NOT_MASK
#define QUERY_FLAG(xyz, p)
#define CLEAR_FLAG(xyz, p)
const Animations * animation
int fire_bow(object *op, object *arrow, int dir, int wc_mod, int16_t sx, int16_t sy)
void skill_attack(object *tmp, object *pl, int dir, const char *string, object *skill)
static int monster_use_range(object *head, object *part, object *pl, int dir)
void animate_object(object *op, int dir)
int16_t resist[NROFATTACKS]
int has_carried_lights(const object *op)
void monster_check_doors(object *op, mapstruct *m, int x, int y)
object * object_find_by_type_subtype(const object *who, int type, int subtype)
int8_t body_info[NUM_BODY_LOCATIONS]
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
#define WILL_APPLY_HANDLE
static const char * get_reply_text_own(reply_type rt)
static int monster_use_bow(object *head, object *part, object *pl, int dir)
static void monster_check_apply(object *mon, object *item)
static int monster_move_no_enemy(object *op)
void object_set_enemy(object *op, object *enemy)
static int monster_use_skill(object *head, object *part, object *pl, int dir)
void monster_npc_call_help(object *op)
int move_object(object *op, int dir)
#define SP_SUMMON_MONSTER
struct struct_dialog_reply * replies
static int monster_run_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv)
object * monster_check_enemy(object *npc, rv_vector *rv)
sstring add_string(const char *str)
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
int monster_move(object *op)
static void monster_check_pickup(object *monster)
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
sstring npc_msgs[MAX_NPC]
void LOG(LogLevel logLevel, const char *format,...)
int monster_stand_in_light(object *op)
static void monster_pace_movev(object *ob)
void make_visible(object *op)
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
static void monster_apply_below(object *monster)
int can_see_monsterP(mapstruct *m, int x, int y, int dir)
struct struct_dialog_reply * next
void query_name(const object *op, char *buf, size_t size)
#define FOR_BELOW_PREPARE(op_, it_)
static int monster_can_pick(object *monster, object *item)
object * find_skill_by_number(object *who, int skillno)
object * pets_get_enemy(object *pet, rv_vector *rv)
int hit_player(object *op, int dam, object *hitter, uint32_t type, int full_hit)
int get_rangevector(object *op1, const object *op2, rv_vector *retval, int flags)
void ext_info_map(int color, const mapstruct *map, uint8_t type, uint8_t subtype, const char *str1)
void fix_object(object *op)
static int monster_do_talk_npc(object *npc, talk_info *info)
static void monster_circ2_move(object *ob)
object * object_get_owner(object *op)
char * stringbuffer_finish(StringBuffer *sb)
#define FOR_BELOW_FINISH()
int monster_can_detect_enemy(object *op, object *enemy, rv_vector *rv)
#define FOR_INV_PREPARE(op_, it_)
int cast_spell(object *op, object *caster, int dir, object *spell_ob, char *stringarg)
void object_remove(object *op)
static int monster_check_wakeup(object *op, object *enemy, rv_vector *rv)