52 static int dist_att(
int dir,
object *ob,
object *enemy,
object *part,
rv_vector *rv);
53 static int run_att(
int dir,
object *ob,
object *enemy,
object *part,
rv_vector *rv);
54 static int hitrun_att(
int dir,
object *ob,
object *enemy);
55 static int wait_att(
int dir,
object *ob,
object *enemy,
object *part,
rv_vector *rv);
65 static int talk_to_npc(
object *op,
object *npc,
const char *txt,
int *talked);
67 #define MIN_MON_RADIUS 3
88 if (npc->
owner == NULL)
90 else if (npc->
enemy == NULL)
191 LOG(
llevDebug,
"find_nearest_living_creature: map %s (%d,%d) has is_alive set but did not find a monster?\n", m->
path, nx, ny);
217 object *attacker, *tmp = NULL;
262 npc->
enemy = attacker;
348 for (i = 0; i < 15; i++) {
355 #define MAX_EXPLORE 5000
374 int current = 0, dir, max = 1, size, x, y, check_dir;
376 if (target->
map != source->
map)
382 path = calloc(size,
sizeof(
char));
386 explore_x[0] = target->
x;
387 explore_y[0] = target->
y;
389 while (current < max) {
390 for (check_dir = 0; check_dir < 8; check_dir++) {
391 dir =
absdir(default_dir+check_dir);
395 if (x == source->
x && y == source->
y) {
409 if (path[source->
map->
height*x+y] == 0) {
568 object *owner, *enemy, *part, *oph = op;
582 enemy = op->
enemy = NULL;
629 if ((op->
race != NULL)&& strcmp(op->
race,
"doppleganger") == 0) {
657 for (part = op; part != NULL; part = part->
more) {
667 dir =
absdir(dir+RANDOM()%3+RANDOM()%3-2);
703 else if (!
can_hit(part, enemy, &rv))
707 dir =
absdir(dir+RANDOM()%3+RANDOM()%3-2);
712 dir =
dist_att(dir, op, enemy, part, &rv);
716 dir =
run_att(dir, op, enemy, part, &rv);
724 dir =
wait_att(dir, op, enemy, part, &rv);
736 dir =
wait_att2(dir, op, enemy, part, &rv);
756 for (diff = 1; diff <= maxdiff; diff++) {
758 int m = 1-(RANDOM()&2);
789 if (nearest_player && nearest_player != enemy && !
can_hit(part, enemy, &rv)) {
791 enemy = nearest_player;
848 for (more = ob2->
more; more != NULL; more = more->
more) {
900 #define MAX_KNOWN_SPELLS 20
922 for (tmp = monster->
inv; tmp != NULL; tmp = tmp->
below)
936 return altern[RANDOM()%i];
979 dir =
absdir(dir+RANDOM()%3+RANDOM()%3-2);
992 if (!spell_item->
inv) {
993 LOG(
llevError,
"spellbook %s does not contain a spell?\n", spell_item->
name);
996 spell_item = spell_item->
inv;
1021 return cast_spell(part, part, dir, spell_item, NULL);
1062 dir =
absdir(dir+RANDOM()%3+RANDOM()%3-2);
1064 for (scroll = head->
inv; scroll; scroll = scroll->
below)
1116 object *skill, *owner;
1127 dir =
absdir(dir+RANDOM()%3+RANDOM()%3-2);
1135 for (skill = head->
inv; skill != NULL; skill = skill->
below)
1142 LOG(
llevDebug,
"Error: Monster %s (%d) has FLAG_READY_SKILL without skill.\n", head->
name, head->
count);
1165 object *wand, *owner;
1166 int at_least_one = 0;
1177 dir =
absdir(dir+RANDOM()%3+RANDOM()%3-2);
1179 for (wand = head->
inv; wand != NULL; wand = wand->
below) {
1212 LOG(
llevError,
"Error: Monster %s (%d) HAS_READY_RANG() without wand/horn/rod.\n", head->
name, head->
count);
1257 while (x != pl->
x || y != pl->
y || map != pl->
map) {
1262 LOG(
llevError,
"monster_use_bow: no map but still path exists??\n");
1267 if (owner && owner->
x == x && owner->
y == y && owner->
map == map)
1275 dir =
absdir(dir+RANDOM()%3+RANDOM()%3-2);
1278 return fire_bow(head, NULL, dir, 0, part->
x, part->
y);
1297 for (other_weap = who->
inv; other_weap != NULL; other_weap = other_weap->
below)
1301 if (other_weap == NULL)
1337 object *other_armour;
1340 for (other_armour = who->
inv; other_armour != NULL; other_armour = other_armour->
below)
1344 if (other_armour == NULL)
1397 for (tmp = monster->
below; tmp != NULL; tmp = next) {
1399 next_tag = next ? next->
count : 0;
1440 else switch (item->
type) {
1489 if (((!(monster->
pick_up&32)) && flag) || ((monster->
pick_up&32) && (!flag)))
1503 for (tmp = monster->
below; tmp != NULL; tmp = next) {
1505 switch (tmp->
type) {
1538 && mon->
arch != NULL
1556 for (bow = mon->
inv; bow != NULL; bow = bow->
below)
1592 }
else if (item->
type ==
BOW) {
1638 for (x = -3; x < 4; x++)
1639 for (y = -3; y < 4; y++) {
1684 int inrange =
can_hit(part, enemy, rv);
1709 return dist_att(dir, ob, enemy, part, rv);
1719 static const int circle [12] = { 3, 3, 4, 5, 5, 6, 7, 7, 8, 1, 1, 2 };
1728 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 };
1786 for (i = 0; i < 5; i++)
1833 int i, mflags, talked = 0;
1838 snprintf(buf,
sizeof(buf),
"%s says: %s", op->
name, txt);
1860 if (orig_map != op->
map) {
1861 LOG(
llevDebug,
"Warning: Forced to swap out very recent map - MAX_OBJECTS should probably be increased\n");
1883 static int do_talk_npc(
object *op,
object *npc,
const char *txt,
int *talked) {
1902 else if (!*talked) {
1904 snprintf(buf,
sizeof(buf),
"%s says: %s", op->
name, txt);
1920 reply = reply->
next;
1937 snprintf(buf,
sizeof(buf),
"%s says: %s", name, cp);
1952 static int talk_to_npc(
object *op,
object *npc,
const char *txt,
int *talked) {
1962 for (cobj = npc->
inv; cobj != NULL; cobj = cobj->
below) {
1990 for (tmp = op->
inv; tmp; tmp = tmp->
below) {
2004 LOG(
llevDebug,
"%s chooses to throw: %s (%d)\n", op->
name, !(tmp) ?
"(nothing)" : what, tmp ? tmp->
count : -1);
2024 if (!op || !enemy || !op->
map || !enemy->
map)
2065 bonus -= sk_hide->
level;
2067 LOG(
llevError,
"can_detect_enemy() got hidden player w/o hiding skill!\n");
2072 bonus -= enemy->
level;
2075 hide_discovery += bonus*5;
2081 radius = radius/2, hide_discovery = hide_discovery/3;
2089 radius += op->map->darkness/2;
2091 radius -= op->map->darkness/2;
2096 if (radius < MIN_MON_RADIUS && op->map->darkness < 5 && rv->distance <= 1)
2112 if ((
int)rv->distance <= radius) {
2114 if (!enemy->invisible)
2118 if (enemy->hide && (rv->distance <= 1) && (RANDOM()%100 <= hide_discovery)) {
2123 "You are discovered by %s!",
2124 "You are discovered by %s!",
2127 }
else if (enemy->invisible) {
2135 if ((RANDOM()%50) <= hide_discovery) {
2136 if (enemy->type ==
PLAYER) {
2141 "You see %s noticing your position.",
2142 "You see %s noticing your position.",
2183 x1 = abs(x-op->
x)*abs(x-op->
x);
2184 y1 = abs(y-op->
y)*abs(y-op->
y);
2200 object *looker = op->
head ? op->
head : op;
2222 "Your light reveals your hiding spot!",
2226 }
else if (enemy->
hide)
static int move_randomly(object *op)
int find_dir_2(int x, int y)
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, sint16 x, sint16 y, sint16 *nx, sint16 *ny)
int get_dialog_message(object *op, const char *text, struct_dialog_message **message, struct_dialog_reply **reply)
#define NUM_BODY_LOCATIONS
static int hitrun_att(int dir, object *ob, object *enemy)
static void monster_do_living(object *op)
int fire_bow(object *op, object *arrow, int dir, int wc_mod, sint16 sx, sint16 sy)
sstring add_refcount(sstring str)
int makes_invisible_to(object *pl, object *mon)
static void circ2_move(object *ob)
void drain_wand_charge(object *wand)
void npc_say(object *npc, const char *cp)
static int check_good_weapon(object *who, object *item)
void get_search_arr(int *search_arr)
sint8 get_attr_value(const living *stats, int attr)
void free_string(sstring str)
#define MSG_TYPE_SKILL_FAILURE
short freearr_x[SIZEOFFREE]
int can_see_enemy(object *op, object *enemy)
void monster_check_apply(object *mon, object *item)
void draw_ext_info(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *message, const char *oldmessage)
object * get_pet_enemy(object *pet, rv_vector *rv)
#define OUT_OF_REAL_MAP(M, X, Y)
int manual_apply(object *op, object *tmp, int aflag)
static int run_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv)
#define MSG_TYPE_COMMUNICATION_SAY
void remove_friendly_object(object *op)
method_ret ob_apply(object *op, object *applier, int aflags)
int player_can_view(object *pl, object *op)
int path_to_player(object *mon, object *pl, unsigned mindiff)
void draw_ext_info_format(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *new_format, const char *old_format,...)
static int monster_use_scroll(object *head, object *part, object *pl, int dir, rv_vector *rv)
int can_detect_enemy(object *op, object *enemy, rv_vector *rv)
static int talk_to_npc(object *op, object *npc, const char *txt, int *talked)
short freearr_y[SIZEOFFREE]
static void pace2_movev(object *ob)
#define FLAG_SEE_INVISIBLE
struct obj * chosen_skill
void remove_ob(object *op)
static int wait_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv)
int dirdiff(int dir1, int dir2)
void do_hidden_move(object *op)
#define FLAG_READY_SCROLL
int skill_attack(object *tmp, object *pl, int dir, const char *string, object *skill)
#define FLAG_CAN_USE_SKILL
void drain_rod_charge(object *rod)
#define FLAG_UNAGGRESSIVE
void get_rangevector(object *op1, const object *op2, rv_vector *retval, int flags)
object * get_nearest_player(object *mon)
int compute_path(object *source, object *target, int default_dir)
#define WILL_APPLY_TREASURE
static int can_hit(object *ob1, object *ob2, rv_vector *rv)
static int monster_should_cast_spell(object *monster, object *spell_ob)
static void rand_move(object *ob)
object * get_owner(object *op)
int is_true_undead(object *op)
#define GET_MAP_LIGHT(M, X, Y)
object * check_enemy(object *npc, rv_vector *rv)
static object * monster_choose_random_spell(object *monster)
mapstruct * get_map_from_coord(mapstruct *m, sint16 *x, sint16 *y)
#define GET_MAP_MOVE_BLOCK(M, X, Y)
int do_skill(object *op, object *part, object *skill, int dir, const char *string)
int can_pick(const object *who, const object *item)
void pet_move(object *ob)
int can_apply_object(object *who, object *op)
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)
object * insert_ob_in_ob(object *op, object *where)
object * find_mon_throw_ob(object *op)
int stand_in_light(object *op)
static int check_good_armour(object *who, object *item)
static int monster_use_range(object *head, object *part, object *pl, int dir)
void animate_object(object *op, int dir)
sint16 resist[NROFATTACKS]
int has_carried_lights(const object *op)
static void pace_movev(object *ob)
sint8 body_info[NUM_BODY_LOCATIONS]
#define MSG_TYPE_DIALOG_MAGIC_MOUTH
int snprintf(char *dest, int max, const char *format,...)
void check_doors(object *op, mapstruct *m, int x, int y)
static void pace2_moveh(object *ob)
#define WILL_APPLY_HANDLE
static int monster_use_bow(object *head, object *part, object *pl, int dir)
#define MSG_TYPE_COMMUNICATION
static int monster_move_no_enemy(object *op)
int should_arena_attack(object *pet, object *owner, object *target)
static object * find_enemy(object *npc, rv_vector *rv)
static int monster_use_skill(object *head, object *part, object *pl, int dir)
void check_earthwalls(object *op, mapstruct *m, int x, int y)
int move_object(object *op, int dir)
int execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
int move_monster(object *op)
sint16 SP_level_spellpoint_cost(object *caster, object *spell, int flags)
static int do_talk_npc(object *op, object *npc, const char *txt, int *talked)
#define SP_SUMMON_MONSTER
struct struct_dialog_reply * replies
static void circ1_move(object *ob)
#define GET_MAP_OB(M, X, Y)
static void monster_check_pickup(object *monster)
static int monster_cast_spell(object *head, object *part, object *pl, int dir, rv_vector *rv)
void LOG(LogLevel logLevel, const char *format,...)
static int dist_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv)
static int check_wakeup(object *op, object *enemy, rv_vector *rv)
void make_visible(object *op)
#define was_destroyed(op, old_tag)
void npc_call_help(object *op)
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)
static int monster_can_pick(object *monster, object *item)
object * find_skill_by_number(object *who, int skillno)
void free_object(object *ob)
#define MSG_TYPE_DIALOG_NPC
static int wait_att2(int dir, object *ob, object *enemy, object *part, rv_vector *rv)
static int disthit_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv)
object * find_nearest_living_creature(object *npc)
void ext_info_map(int color, const mapstruct *map, uint8 type, uint8 subtype, const char *str1, const char *str2)
int hit_player(object *op, int dam, object *hitter, uint32 type, int full_hit)
static void pace_moveh(object *ob)
int cast_spell(object *op, object *caster, int dir, object *spell_ob, char *stringarg)
void communicate(object *op, const char *txt)
int ob_blocked(const object *ob, mapstruct *m, sint16 x, sint16 y)
void follow_owner(object *ob, object *owner)