Crossfire Server, Trunk  R20576
monster.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2013 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
20 #include "global.h"
21 
22 #include <assert.h>
23 #include <stdlib.h>
24 #include <string.h>
25 
26 #include "skills.h"
27 #include "spells.h"
28 #include "sproto.h"
29 
30 static int monster_can_hit(object *ob1, object *ob2, rv_vector *rv);
31 static int monster_cast_spell(object *head, object *part, object *pl, int dir);
32 static int monster_use_scroll(object *head, object *part, object *pl, int dir);
33 static int monster_use_skill(object *head, object *part, object *pl, int dir);
34 static int monster_use_range(object *head, object *part, object *pl, int dir);
35 static int monster_use_bow(object *head, object *part, object *pl, int dir);
36 static void monster_check_pickup(object *monster);
37 static int monster_can_pick(object *monster, object *item);
38 static void monster_apply_below(object *monster);
39 static int monster_dist_att(int dir, object *enemy, object *part, rv_vector *rv);
40 static int monster_run_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv);
41 static int monster_hitrun_att(int dir, object *ob, object *enemy);
42 static int monster_wait_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv);
43 static int monster_disthit_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv);
44 static int monster_wait_att2(int dir, rv_vector *rv);
45 static void monster_circ1_move(object *ob);
46 static void monster_circ2_move(object *ob);
47 static void monster_pace_movev(object *ob);
48 static void monster_pace_moveh(object *ob);
49 static void monster_pace2_movev(object *ob);
50 static void monster_pace2_moveh(object *ob);
51 static void monster_rand_move(object *ob);
52 static int monster_talk_to_npc(object *npc, talk_info *info);
53 
55 #define MIN_MON_RADIUS 3
56 
71 object *monster_check_enemy(object *npc, rv_vector *rv) {
72  object *owner;
73 
74  /* if this is pet, let him attack the same enemy as his owner
75  * TODO: when there is no ower enemy, try to find a target,
76  * which CAN attack the owner. */
77  owner = object_get_owner(npc);
78  if ((npc->attack_movement&HI4) == PETMOVE) {
79  if (owner == NULL)
80  object_set_enemy(npc, NULL);
81  else if (npc->enemy == NULL)
82  object_set_enemy(npc, owner->enemy);
83  }
84 
85  /* periodically, a monster may change its target. Also, if the object
86  * has been destroyed, etc, clear the enemy.
87  * TODO: this should be changed, because it invokes to attack forced or
88  * attacked monsters to leave the attacker alone, before it is destroyed
89  */
90  /* i had removed the random target leave, this invokes problems with friendly
91  * objects, getting attacked and defending herself - they don't try to attack
92  * again then but perhaps get attack on and on
93  * If we include a aggravated flag in , we can handle evil vs evil and good vs good
94  * too. */
95 
96  if (npc->enemy) {
97  /* I broke these if's apart to better be able to see what
98  * the grouping checks are. Code is the same.
99  */
100  if (QUERY_FLAG(npc->enemy, FLAG_REMOVED)
101  || QUERY_FLAG(npc->enemy, FLAG_FREED)
102  || !on_same_map(npc, npc->enemy)
103  || npc == npc->enemy
104  || QUERY_FLAG(npc, FLAG_NEUTRAL)
105  || QUERY_FLAG(npc->enemy, FLAG_NEUTRAL))
106  object_set_enemy(npc, NULL);
107 
108  else if (QUERY_FLAG(npc, FLAG_FRIENDLY) && (
109  (QUERY_FLAG(npc->enemy, FLAG_FRIENDLY) && !pets_should_arena_attack(npc, owner, npc->enemy))
110  || (npc->enemy->type == PLAYER && !pets_should_arena_attack(npc, owner, npc->enemy))
111  || npc->enemy == owner))
112  object_set_enemy(npc, NULL);
113  else if (!QUERY_FLAG(npc, FLAG_FRIENDLY)
114  && (!QUERY_FLAG(npc->enemy, FLAG_FRIENDLY) && npc->enemy->type != PLAYER))
115  object_set_enemy(npc, NULL);
116 
117  /* I've noticed that pets could sometimes get an arrow as the
118  * target enemy - this code below makes sure the enemy is something
119  * that should be attacked. My guess is that the arrow hits
120  * the creature/owner, and so the creature then takes that
121  * as the enemy to attack.
122  */
123  else if (!QUERY_FLAG(npc->enemy, FLAG_MONSTER)
124  && !QUERY_FLAG(npc->enemy, FLAG_GENERATOR)
125  && npc->enemy->type != PLAYER
126  && npc->enemy->type != GOLEM)
127  object_set_enemy(npc, NULL);
128  }
129  return monster_can_detect_enemy(npc, npc->enemy, rv) ? npc->enemy : NULL;
130 }
131 
153  int i, mflags;
154  int16_t nx, ny;
155  mapstruct *m;
156  int search_arr[SIZEOFFREE];
157 
158  get_search_arr(search_arr);
159  for (i = 0; i < SIZEOFFREE; i++) {
160  /* modified to implement smart searching using search_arr
161  * guidance array to determine direction of search order
162  */
163  nx = npc->x+freearr_x[search_arr[i]];
164  ny = npc->y+freearr_y[search_arr[i]];
165  m = npc->map;
166 
167  mflags = get_map_flags(m, &m, nx, ny, &nx, &ny);
168  if (mflags&P_OUT_OF_MAP)
169  continue;
170 
171  if (mflags&P_IS_ALIVE) {
172  object *creature;
173 
174  creature = NULL;
175  FOR_MAP_PREPARE(m, nx, ny, tmp)
176  if (QUERY_FLAG(tmp, FLAG_MONSTER)
177  || QUERY_FLAG(tmp, FLAG_GENERATOR)
178  || tmp->type == PLAYER) {
179  creature = tmp;
180  break;
181  }
182  FOR_MAP_FINISH();
183  if (!creature) {
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);
185  } else {
186  if (can_see_monsterP(m, nx, ny, i))
187  return creature;
188  }
189  } /* is something living on this space */
190  }
191  return NULL; /* nothing found */
192 }
193 
209 static object *monster_find_enemy(object *npc, rv_vector *rv) {
210  object *attacker, *tmp = NULL;
211 
212  attacker = npc->attacked_by; /* save this for later use. This can be a attacker. */
213  npc->attacked_by = NULL; /* always clear the attacker entry */
214 
215  /* if we berserk, we don't care about others - we attack all we can find */
216  if (QUERY_FLAG(npc, FLAG_BERSERK)) {
218  if (tmp == NULL)
219  return NULL;
220  if (!get_rangevector(npc, tmp, rv, 0))
221  return NULL;
222  return tmp;
223  }
224 
225  /* Here is the main enemy selection.
226  * We want this: if there is an enemy, attack him until its not possible or
227  * one of both is dead.
228  * If we have no enemy and we are...
229  * a monster: try to find a player, a pet or a friendly monster
230  * a friendly: only target a monster which is targeting you first or targeting a player
231  * a neutral: fight a attacker (but there should be none), then do nothing
232  * a pet: attack player enemy or a monster
233  */
234 
235  /* pet move */
236  if ((npc->attack_movement&HI4) == PETMOVE) {
237  tmp = pets_get_enemy(npc, rv);
238  if (tmp == NULL)
239  return NULL;
240  if (!get_rangevector(npc, tmp, rv, 0))
241  return NULL;
242  return tmp;
243  }
244 
245  /* we check our old enemy. */
246  tmp = monster_check_enemy(npc, rv);
247  if (tmp == NULL) {
248  if (attacker) { /* if we have an attacker, check him */
249  /* we want be sure this is the right one! */
250  if (attacker->count == npc->attacked_by_count) {
251  /* TODO: thats not finished */
252  /* we don't want a fight evil vs evil or good against non evil */
253  if (QUERY_FLAG(npc, FLAG_NEUTRAL)
254  || QUERY_FLAG(attacker, FLAG_NEUTRAL) /* neutral */
255  || (QUERY_FLAG(npc, FLAG_FRIENDLY) && QUERY_FLAG(attacker, FLAG_FRIENDLY))
256  || (!QUERY_FLAG(npc, FLAG_FRIENDLY) && (!QUERY_FLAG(attacker, FLAG_FRIENDLY) && attacker->type != PLAYER)))
257  CLEAR_FLAG(npc, FLAG_SLEEP); /* skip it, but lets wakeup */
258  else if (on_same_map(npc, attacker)) { /* thats the only thing we must know... */
259  CLEAR_FLAG(npc, FLAG_SLEEP); /* well, NOW we really should wake up! */
260  object_set_enemy(npc, attacker);
261  if (!get_rangevector(npc, attacker, rv, 0))
262  return NULL;
263  return attacker; /* yes, we face our attacker! */
264  }
265  }
266  }
267 
268  /* we have no legal enemy or attacker, so we try to target a new one */
269  if (!QUERY_FLAG(npc, FLAG_UNAGGRESSIVE)
270  && !QUERY_FLAG(npc, FLAG_FRIENDLY)
271  && !QUERY_FLAG(npc, FLAG_NEUTRAL)) {
273  if (npc->enemy)
274  tmp = monster_check_enemy(npc, rv);
275  }
276  }
277 
278  return tmp;
279 }
280 
296 static int monster_check_wakeup(object *op, object *enemy, rv_vector *rv) {
297  int radius = MAX(op->stats.Wis, MIN_MON_RADIUS);
298 
299  /* Trim work - if no enemy, no need to do anything below */
300  if (!enemy)
301  return 0;
302 
303  /* blinded monsters can only find nearby objects to attack */
304  if (QUERY_FLAG(op, FLAG_BLIND))
305  radius = MIN_MON_RADIUS;
306 
307  /* This covers the situation where the monster is in the dark
308  * and has an enemy. If the enemy has no carried light (or isnt
309  * glowing!) then the monster has trouble finding the enemy.
310  * Remember we already checked to see if the monster can see in
311  * the dark. */
312  else if (op->map
313  && op->map->darkness > 0
314  && enemy
315  && !enemy->invisible
316  && !monster_stand_in_light(enemy)
318  int dark = radius/(op->map->darkness);
319 
320  radius = (dark > MIN_MON_RADIUS) ? (dark+1) : MIN_MON_RADIUS;
321  } else if (!QUERY_FLAG(op, FLAG_SLEEP))
322  return 1;
323 
324  /* enemy should already be on this map, so don't really need to check
325  * for that.
326  */
327  if (rv->distance < (unsigned)(QUERY_FLAG(enemy, FLAG_STEALTH) ? radius/2+1 : radius)) {
328  CLEAR_FLAG(op, FLAG_SLEEP);
329  return 1;
330  }
331  return 0;
332 }
333 
342 static int monster_move_randomly(object *op) {
343  int i;
344  sstring talked;
345  char value[2];
346 
347  /* timeout before moving */
348  if (QUERY_FLAG(op, FLAG_UNAGGRESSIVE)) {
349  talked = object_get_value(op, "talked_to");
350  if (talked && strlen(talked) > 0) {
351  i = atoi(talked);
352  i--;
353 
354  if (i != 0) {
355  value[1] = '\0';
356  value[0] = '0' + i;
357  object_set_value(op, "talked_to", value, 1);
358  return 1;
359  }
360 
361  /* finished timeout talked to */
362  object_set_value(op, "talked_to", "", 1);
363  }
364  }
365 
366  /* Give up to 15 chances for a monster to move randomly */
367  for (i = 0; i < 15; i++) {
368  if (move_object(op, RANDOM()%8+1))
369  return 1;
370  }
371  return 0;
372 }
373 
375 #define MAX_EXPLORE 5000
376 
393 int monster_compute_path(object *source, object *target, int default_dir) {
394  unsigned short *distance;
395  int explore_x[MAX_EXPLORE], explore_y[MAX_EXPLORE], dirs[8];
396  int current = 0, dir, max = 1, x, y, i;
397 
398  if (target->map != source->map)
399  return default_dir;
400 
401  // These shouldn't change during the calculation, so store them once to avoid dereferencing.
402  mapstruct * cur_map = source->map; // Not constant to silence some warnings.
403  const uint16_t map_height = cur_map->height;
404  /*printf("monster_compute_path (%d, %d) => (%d, %d)\n", source->x, source->y, target->x, target->y);*/
405 
406  // Leave width like this because it is used just this once.
407  const int size = cur_map->width * map_height;
408 
419  if (!source->more) // Skip multitile monsters, since this does not work right for them
420  {
421  dir = -1; // Set a sentinel. -1 = no escape, 0 = many ways out, [1, 8] = one way out in dir
422  for (i = 1; i <= 8; ++i)
423  {
424  x = source->x + freearr_x[i];
425  y = source->y + freearr_y[i];
426  if (OUT_OF_REAL_MAP(cur_map, x, y))
427  continue;
428  if (ob_blocked(source, cur_map, x, y))
429  continue;
430  // We have a way out. Make note of it
431  if (dir < 0)
432  dir = i;
433  // We have many ways out -- do the pathing part of the function
434  else
435  {
436  dir = 0;
437  break;
438  }
439  }
440  // If dir > 0, we have our direction to go, as it is our only choice.
441  if (dir > 0)
442  return dir;
443  // If dir < 0, then we have no way to go. Return default_dir.
444  if (dir < 0)
445  return default_dir;
446  }
447 
448  /* We are setting all the values manually anyway,
449  * so there's no reason to use calloc().
450  * malloc() is more efficient here for that reason.
451  */
452  distance = malloc(size * sizeof(*distance));
453  if (distance == NULL) {
455  }
456  /*
457  * 999 seems to be an arbitrary intializer.
458  * 65535 can be set more efficiently.
459  *
460  for (dir = 0; dir < size; ++dir) {
461  distance[dir] = 999;
462  }
463  *
464  * To set to 65535 efficiently, though, I need to memset each byte to 255.
465  * each element is two bytes,
466  */
467  memset(distance, 255, sizeof(*distance) * size);
468 
469  distance[map_height * target->x + target->y] = 0;
470  explore_x[0] = target->x;
471  explore_y[0] = target->y;
472 
473  /* The first time through, current = 0 and max = 1.
474  * This will evaluate to true, so we might as well use a do-while loop.
475  */
476  do {
477  /* Fisher–Yates shuffle the directions, "inside-out" algorithm
478  * from http://en.wikipedia.org/wiki/Fisher-Yates_shuffle */
479  dirs[0] = 1;
480  for (i = 1; i < 8; ++i) {
481  x = RANDOM() % (i+1);
482  dirs[i] = dirs[x];
483  dirs[x] = i+1;
484  }
485 
486  for (i = 0; i < 8; ++i) {
487  unsigned short new_distance;
488 
489  /*
490  * dirs[i] is the direction we wish to check.
491  */
492  dir = absdir(default_dir+4+dirs[i]);
493  x = explore_x[current]+freearr_x[dir];
494  y = explore_y[current]+freearr_y[dir];
495 
496  if (x == source->x && y == source->y) {
497  free(distance);
498  return absdir(dir+4);
499  }
500 
501  if (OUT_OF_REAL_MAP(cur_map, x, y))
502  continue;
503 
504  // Move these up, so we can reduce calls to ob_blocked with their info.
505  assert(map_height * x + y >= 0);
506  assert(map_height * x + y < size);
507 
508  new_distance =
509  distance[map_height * explore_x[current] + explore_y[current]]
510  /* Mod 2 is equivalent to checking only the 1's bit (1 or 0), but & 1 is faster.
511  * Also, dir & 1 == 0 is true if we have a diagonal dir.
512  */
513  + ((dir & 1) == 0 ? 3 : 2);
514 
515  // If already known blocked or arrivable in less distance, we skip
516  if (distance[map_height * x + y] <= new_distance)
517  continue;
518  // If we have a non-default value here, we will have lready done ob_blocked on it.
519  // So, only call ob_blocked if we are staring at 65535.
520  // If we are not looking at an untested space, then we will skip this block and avoid ob_blocked
521  if (distance[map_height * x + y] == 65535 && ob_blocked(source, cur_map, x, y))
522  {
523  // Mark as something we can't otherwise get -- the goal is to cache what spaces are blocked.
524  // At least, this call to monster_compute_path will remember this spot is blocked.
525  // This should cut our calls to ob_blocked some.
526  distance[map_height * x + y] = 1;
527  // The value of 1 also allows for walls to be considered already checked, but since we do not add to the
528  // explore array, this makes them hit the condition above if they are checked again without going through walls.
529  continue;
530  }
531 
532  /*LOG(llevDebug, "check %d, %d dist = %d, nd = %d\n", x, y, distance[source->map->height*x+y], new_distance);*/
533 
534  /* This condition is now always true, since we bail before we get here if this is false.
535  if (distance[map_height * x + y] > new_distance) {
536  */
537  assert(max < MAX_EXPLORE);
538  explore_x[max] = x;
539  explore_y[max] = y;
540 
541  distance[map_height * x + y] = new_distance;
542  /* printf("explore[%d] => (%d, %d) %u\n", max, x, y, new_distance);*/
543  ++max;
544  if (max == MAX_EXPLORE) {
545  free(distance);
546  return default_dir;
547  }
548  //}
549  }
550  ++current;
551  } while (current < max);
552 
553  /*LOG(llevDebug, "no path\n");*/
554  free(distance);
555  return default_dir;
556 }
557 
564 void monster_do_living(object *op) {
565  assert(op);
566  assert(QUERY_FLAG(op, FLAG_MONSTER));
567 
568  /* generate hp, if applicable */
569  if (op->stats.Con > 0 && op->stats.hp < op->stats.maxhp) {
570  /* last heal is in funny units. Dividing by speed puts
571  * the regeneration rate on a basis of time instead of
572  * #moves the monster makes. The scaling by 8 is
573  * to capture 8th's of a hp fraction regens
574  *
575  * Cast to int32_t before comparing to maxhp since otherwise an (int16_t)
576  * overflow might produce monsters with negative hp.
577  */
578 
579  op->last_heal += (int)((float)(8*op->stats.Con)/FABS(op->speed));
580  op->stats.hp = MIN((int32_t)op->stats.hp+op->last_heal/32, op->stats.maxhp); /* causes Con/4 hp/tick */
581  op->last_heal %= 32;
582 
583  /* So if the monster has gained enough HP that they are no longer afraid */
584  if (QUERY_FLAG(op, FLAG_RUN_AWAY)
585  && op->stats.hp >= (int16_t)((int32_t)op->run_away * op->stats.maxhp / 100))
587  /*
588  * This should already be covered by the MIN() check above.
589 
590  if (op->stats.hp > op->stats.maxhp)
591  op->stats.hp = op->stats.maxhp;
592  */
593  }
594 
595  /* generate sp, if applicable */
596  if (op->stats.Pow > 0 && op->stats.sp < op->stats.maxsp) {
597  /* last_sp is in funny units. Dividing by speed puts
598  * the regeneration rate on a basis of time instead of
599  * #moves the monster makes. The scaling by 8 is
600  * to capture 8th's of a sp fraction regens
601  *
602  * Cast to int32_t before comparing to maxhp since otherwise an (int16_t)
603  * overflow might produce monsters with negative sp.
604  */
605 
606  op->last_sp += (int)((float)(8*op->stats.Pow)/FABS(op->speed));
607  op->stats.sp = MIN(op->stats.sp+op->last_sp/128, op->stats.maxsp); /* causes Pow/16 sp/tick */
608  op->last_sp %= 128;
609  }
610 
611  /* this should probably get modified by many more values.
612  * (eg, creatures resistance to fear, level, etc. )
613  */
614  if (QUERY_FLAG(op, FLAG_SCARED) && !(RANDOM()%20)) {
615  CLEAR_FLAG(op, FLAG_SCARED); /* Time to regain some "guts"... */
616  }
617 }
618 
627 static int monster_move_no_enemy(object *op) {
628  assert(QUERY_FLAG(op, FLAG_MONSTER));
629 
630  if (QUERY_FLAG(op, FLAG_ONLY_ATTACK)) {
631  object_remove(op);
633  return 1;
634  }
635 
636  /* Probably really a bug for a creature to have both
637  * stand still and a movement type set.
638  */
639  if (!QUERY_FLAG(op, FLAG_STAND_STILL)) {
640  if (op->attack_movement&HI4) {
641  switch (op->attack_movement&HI4) {
642  case PETMOVE:
643  pets_move(op);
644  break;
645 
646  case CIRCLE1:
647  monster_circ1_move(op);
648  break;
649 
650  case CIRCLE2:
651  monster_circ2_move(op);
652  break;
653 
654  case PACEV:
655  monster_pace_movev(op);
656  break;
657 
658  case PACEH:
659  monster_pace_moveh(op);
660  break;
661 
662  case PACEV2:
664  break;
665 
666  case PACEH2:
668  break;
669 
670  case RANDO:
671  monster_rand_move(op);
672  break;
673 
674  case RANDO2:
676  break;
677  }
678  return 0;
679  }
680 
681  if (QUERY_FLAG(op, FLAG_RANDOM_MOVE))
683  } /* stand still */
684 
685  return 0;
686 }
687 
699 int monster_move(object *op) {
700  int dir, diff;
701  object *owner, *enemy, *part;
702  rv_vector rv;
703 
704  /* Monsters not on maps don't do anything. These monsters are things
705  * Like royal guards in city dwellers inventories.
706  */
707  if (!op->map)
708  return 0;
709 
710  if (QUERY_FLAG(op, FLAG_NO_ATTACK)) { /* we never ever attack */
711  object_set_enemy(op, NULL);
712  enemy = NULL;
713  } else {
714  enemy = monster_find_enemy(op, &rv);
715  if (enemy != NULL) {
716  /* we have an enemy, just tell him we want him dead */
717  enemy->attacked_by = op; /* our ptr */
718  enemy->attacked_by_count = op->count; /* our tag */
719  }
720  }
721 
722  monster_do_living(op);
723 
724  if (QUERY_FLAG(op, FLAG_SLEEP)
725  || QUERY_FLAG(op, FLAG_BLIND)
726  || (op->map->darkness > 0 && !QUERY_FLAG(op, FLAG_SEE_IN_DARK) && !QUERY_FLAG(op, FLAG_SEE_INVISIBLE))) {
727  if (!monster_check_wakeup(op, enemy, &rv))
728  return 0;
729  }
730 
731  /* check if monster pops out of hidden spot */
732  if (op->hide)
733  do_hidden_move(op);
734 
735  if (op->pick_up)
737 
738  if (op->will_apply)
739  monster_apply_below(op); /* Check for items to apply below */
740 
741  /* If we don't have an enemy, do special movement or the like */
742  if (!enemy) {
743  return monster_move_no_enemy(op);
744  } /* no enemy */
745 
746  /* We have an enemy. Block immediately below is for pets */
747  if ((op->attack_movement&HI4) == PETMOVE) {
748  owner = object_get_owner(op);
749  if (owner != NULL && !on_same_map(op, owner)) {
750  pets_follow_owner(op, owner);
751  /* If the pet was unable to follow the owner, free it */
752  if (QUERY_FLAG(op, FLAG_REMOVED) && FABS(op->speed) > MIN_ACTIVE_SPEED) {
755  return 1;
756  }
757  return 0;
758  }
759  }
760 
761  /* doppleganger code to change monster facing to that of the nearest
762  * player. Hmm. The code is here, but no monster in the current
763  * arch set uses it.
764  */
765  if (op->race != NULL && strcmp(op->race, "doppleganger") == 0) {
766  op->face = enemy->face;
767  if (op->name)
768  free_string(op->name);
769  add_refcount(op->name = enemy->name);
770  }
771 
772  /* Calculate range information for closest body part - this
773  * is used for the 'skill' code, which isn't that smart when
774  * it comes to figuring it out - otherwise, giants throw boulders
775  * into themselves.
776  */
777  if (!get_rangevector(op, enemy, &rv, 0))
778  return 0;
779  if (op->direction != rv.direction) {
780  op->direction = rv.direction;
781  op->facing = op->direction;
782  if (op->animation_id)
783  animate_object(op, op->direction);
784  }
785 
786  // We are looking at movement -- if monster was paralyzed, they aren't anymore
787  if (QUERY_FLAG(op, FLAG_PARALYZED)) {
789  }
790 
791  /* Move the check for scared up here - if the monster was scared,
792  * we were not doing any of the logic below, so might as well save
793  * a few cpu cycles.
794  */
795  if (!QUERY_FLAG(op, FLAG_SCARED)) {
796  dir = rv.direction;
797 
798  /* Was two if statements assigning to the same variable
799  * We can get the same effect by reversing the order and making an else-if
800  */
801  if (QUERY_FLAG(op, FLAG_CONFUSED))
802  dir = get_randomized_dir(dir);
803  else if (QUERY_FLAG(op, FLAG_RUN_AWAY))
804  dir = absdir(dir+4);
805 
806  if (QUERY_FLAG(op, FLAG_CAST_SPELL) && !(RANDOM()%3)) {
807  if (monster_cast_spell(op, rv.part, enemy, dir))
808  return 0;
809  }
810 
811  if (QUERY_FLAG(op, FLAG_READY_SCROLL) && !(RANDOM()%3)) {
812  if (monster_use_scroll(op, rv.part, enemy, dir))
813  return 0;
814  }
815 
816  if (QUERY_FLAG(op, FLAG_READY_RANGE) && !(RANDOM()%3)) {
817  if (monster_use_range(op, rv.part, enemy, dir))
818  return 0;
819  }
820  if (QUERY_FLAG(op, FLAG_READY_SKILL) && !(RANDOM()%3)) {
821  if (monster_use_skill(op, rv.part, enemy, rv.direction))
822  return 0;
823  }
824  if (QUERY_FLAG(op, FLAG_READY_BOW) && !(RANDOM()%2)) {
825  if (monster_use_bow(op, rv.part, enemy, dir))
826  return 0;
827  }
828  } /* If not scared */
829 
830 
831  /* code below is for when we didn't use a range attack or a skill, so
832  * either move or hit with hth attack. */
833 
834  part = rv.part;
835  dir = rv.direction;
836 
837  /* This first clause used to happen after the other two, but would trample dir.
838  * Moved to before them as another check to slightly reduce calls to monster_compute_path
839  */
840  if (QUERY_FLAG(op, FLAG_CONFUSED))
841  dir = get_randomized_dir(dir);
842  else if (QUERY_FLAG(op, FLAG_SCARED) || QUERY_FLAG(op, FLAG_RUN_AWAY))
843  dir = absdir(dir+4);
844  else if (!monster_can_hit(part, enemy, &rv))
845  dir = monster_compute_path(op, enemy, rv.direction);
846 
847  if ((op->attack_movement&LO4) && !QUERY_FLAG(op, FLAG_SCARED)) {
848  switch (op->attack_movement&LO4) {
849  case DISTATT:
850  dir = monster_dist_att(dir, enemy, part, &rv);
851  break;
852 
853  case RUNATT:
854  dir = monster_run_att(dir, op, enemy, part, &rv);
855  break;
856 
857  case HITRUN:
858  dir = monster_hitrun_att(dir, op, enemy);
859  break;
860 
861  case WAITATT:
862  dir = monster_wait_att(dir, op, enemy, part, &rv);
863  break;
864 
865  case RUSH: /* default - monster normally moves towards player */
866  case ALLRUN:
867  break;
868 
869  case DISTHIT:
870  dir = monster_disthit_att(dir, op, enemy, part, &rv);
871  break;
872 
873  case WAIT2:
874  dir = monster_wait_att2(dir, &rv);
875  break;
876 
877  default:
878  LOG(llevDebug, "Illegal low mon-move: %d\n", op->attack_movement&LO4);
879  }
880  }
881 
882  if (!dir)
883  return 0;
884 
885  if (!QUERY_FLAG(op, FLAG_STAND_STILL)) {
886  if (move_object(op, dir)) /* Can the monster move directly toward player? */
887  return 0;
888 
889  if (QUERY_FLAG(op, FLAG_SCARED)
890  || !monster_can_hit(part, enemy, &rv)
891  || QUERY_FLAG(op, FLAG_RUN_AWAY)) {
892  /* Try move around corners if !close */
893  int maxdiff = (QUERY_FLAG(op, FLAG_ONLY_ATTACK) || RANDOM()&1) ? 1 : 2;
894  for (diff = 1; diff <= maxdiff; diff++) {
895  /* try different detours */
896  int m = 1-(RANDOM()&2); /* Try left or right first? */
897  if (move_object(op, absdir(dir+diff*m))
898  || move_object(op, absdir(dir-diff*m)))
899  return 0;
900  }
901  }
902  } /* if monster is not standing still */
903 
904  /*
905  * Eneq(@csd.uu.se): Patch to make RUN_AWAY or SCARED monsters move a random
906  * direction if they can't move away.
907  */
908  if (!QUERY_FLAG(op, FLAG_ONLY_ATTACK)
910  if (monster_move_randomly(op))
911  return 0;
912 
913  /*
914  * Try giving the monster a new enemy - the player that is closest
915  * to it. In this way, it won't just keep trying to get to a target
916  * that is inaccessible.
917  * This could be more clever - it should go through a list of several
918  * enemies, as it is now, you could perhaps get situations where there
919  * are two players flanking the monster at close distance, but which
920  * the monster can't get to, and a third one at a far distance that
921  * the monster could get to - as it is, the monster won't look at that
922  * third one.
923  */
924  if (!QUERY_FLAG(op, FLAG_FRIENDLY) && enemy == op->enemy) {
925  object *nearest_player = get_nearest_player(op);
926 
927  if (nearest_player && nearest_player != enemy && !monster_can_hit(part, enemy, &rv)) {
928  object_set_enemy(op, NULL);
929  enemy = nearest_player;
930  }
931  }
932 
933  if (!QUERY_FLAG(op, FLAG_SCARED) && monster_can_hit(part, enemy, &rv)) {
934  /* The adjustement to wc that was here before looked totally bogus -
935  * since wc can in fact get negative, that would mean by adding
936  * the current wc, the creature gets better? Instead, just
937  * add a fixed amount - nasty creatures that are runny away should
938  * still be pretty nasty.
939  */
940  if (QUERY_FLAG(op, FLAG_RUN_AWAY)) {
941  part->stats.wc += 10;
942  skill_attack(enemy, part, 0, NULL, NULL);
943  part->stats.wc -= 10;
944  } else
945  skill_attack(enemy, part, 0, NULL, NULL);
946  } /* if monster is in attack range */
947 
948  if (QUERY_FLAG(part, FLAG_FREED)) /* Might be freed by ghost-attack or hit-back */
949  return 1;
950 
951  if (QUERY_FLAG(op, FLAG_ONLY_ATTACK)) {
952  object_remove(op);
954  return 1;
955  }
956  return 0;
957 }
958 
973 static int monster_can_hit(object *ob1, object *ob2, rv_vector *rv) {
974  object *more;
975  rv_vector rv1;
976 
977  if (QUERY_FLAG(ob1, FLAG_CONFUSED) && !(RANDOM()%3))
978  return 0;
979 
980  if (abs(rv->distance_x) < 2 && abs(rv->distance_y) < 2)
981  return 1;
982 
983  /* check all the parts of ob2 - just because we can't get to
984  * its head doesn't mean we don't want to pound its feet
985  */
986  for (more = ob2->more; more != NULL; more = more->more) {
987  if (get_rangevector(ob1, more, &rv1, 0)
988  && abs(rv1.distance_x) < 2 && abs(rv1.distance_y) < 2)
989  return 1;
990  }
991  return 0;
992 }
993 
1016 static int monster_should_cast_spell(object *spell_ob) {
1017  /* The caller is responsible for making sure that *spell_ob is defined. */
1018  assert(spell_ob != NULL);
1019 
1020  if (spell_ob->subtype == SP_BOLT
1021  || spell_ob->subtype == SP_BULLET
1022  || spell_ob->subtype == SP_EXPLOSION
1023  || spell_ob->subtype == SP_CONE
1024  || spell_ob->subtype == SP_BOMB
1025  || spell_ob->subtype == SP_SMITE
1026  || spell_ob->subtype == SP_MAGIC_MISSILE
1027  || spell_ob->subtype == SP_SUMMON_GOLEM
1028  || spell_ob->subtype == SP_MAGIC_WALL
1029  || spell_ob->subtype == SP_SUMMON_MONSTER
1030  || spell_ob->subtype == SP_MOVING_BALL
1031  || spell_ob->subtype == SP_SWARM
1032  || spell_ob->subtype == SP_INVISIBLE)
1033  return 1;
1034 
1035  return 0;
1036 }
1037 
1039 #define MAX_KNOWN_SPELLS 20
1040 
1056 static object *monster_choose_random_spell(object *monster) {
1057  object *altern[MAX_KNOWN_SPELLS];
1058  int i = 0;
1059 
1060  FOR_INV_PREPARE(monster, tmp)
1061  if (tmp->type == SPELLBOOK || tmp->type == SPELL) {
1062  /* Check and see if it's actually a useful spell.
1063  * If its a spellbook, the spell is actually the inventory item.
1064  * if it is a spell, then it is just the object itself.
1065  */
1066  if (monster_should_cast_spell(tmp->type == SPELLBOOK ? tmp->inv : tmp)) {
1067  altern[i++] = tmp;
1068  if (i == MAX_KNOWN_SPELLS)
1069  break;
1070  }
1071  }
1072  FOR_INV_FINISH();
1073  if (!i)
1074  return NULL;
1075  return altern[RANDOM()%i];
1076 }
1077 
1094 static int monster_cast_spell(object *head, object *part, object *pl, int dir) {
1095  object *spell_item;
1096  object *owner;
1097  rv_vector rv1;
1098 
1099  /* If you want monsters to cast spells over friends, this spell should
1100  * be removed. It probably should be in most cases, since monsters still
1101  * don't care about residual effects (ie, casting a cone which may have a
1102  * clear path to the player, the side aspects of the code will still hit
1103  * other monsters)
1104  */
1105  dir = path_to_player(part, pl, 0);
1106  if (dir == 0)
1107  return 0;
1108 
1109  if (QUERY_FLAG(head, FLAG_FRIENDLY)) {
1110  owner = object_get_owner(head);
1111  if (owner != NULL) {
1112  if (get_rangevector(head, owner, &rv1, 0x1)
1113  && dirdiff(dir, rv1.direction) < 2) {
1114  return 0; /* Might hit owner with spell */
1115  }
1116  }
1117  }
1118 
1119  if (QUERY_FLAG(head, FLAG_CONFUSED))
1120  dir = get_randomized_dir(dir);
1121 
1122  /* If the monster hasn't already chosen a spell, choose one
1123  * I'm not sure if it really make sense to pre-select spells (events
1124  * could be different by the time the monster goes again).
1125  */
1126  if (head->spellitem == NULL) {
1127  spell_item = monster_choose_random_spell(head);
1128  if (spell_item == NULL) {
1129  LOG(llevMonster, "Turned off spells in %s\n", head->name);
1130  CLEAR_FLAG(head, FLAG_CAST_SPELL); /* Will be turned on when picking up book */
1131  return 0;
1132  }
1133  if (spell_item->type == SPELLBOOK) {
1134  if (!spell_item->inv) {
1135  LOG(llevError, "spellbook %s does not contain a spell?\n", spell_item->name);
1136  return 0;
1137  }
1138  spell_item = spell_item->inv;
1139  }
1140  } else
1141  spell_item = head->spellitem;
1142 
1143  if (!spell_item)
1144  return 0;
1145 
1146  /* Best guess this is a defensive/healing spell */
1147  if (spell_item->range <= 1 || spell_item->stats.dam < 0)
1148  dir = 0;
1149 
1150  /* Monster doesn't have enough spell-points */
1151  if (head->stats.sp < SP_level_spellpoint_cost(head, spell_item, SPELL_MANA))
1152  return 0;
1153 
1154  if (head->stats.grace < SP_level_spellpoint_cost(head, spell_item, SPELL_GRACE))
1155  return 0;
1156 
1157  head->stats.sp -= SP_level_spellpoint_cost(head, spell_item, SPELL_MANA);
1158  head->stats.grace -= SP_level_spellpoint_cost(head, spell_item, SPELL_GRACE);
1159 
1160  /* set this to null, so next time monster will choose something different */
1161  head->spellitem = NULL;
1162 
1163  return cast_spell(part, part, dir, spell_item, NULL);
1164 }
1165 
1180 static int monster_use_scroll(object *head, object *part, object *pl, int dir) {
1181  object *scroll;
1182  object *owner;
1183  rv_vector rv1;
1184 
1185  /* If you want monsters to cast spells over friends, this spell should
1186  * be removed. It probably should be in most cases, since monsters still
1187  * don't care about residual effects (ie, casting a cone which may have a
1188  * clear path to the player, the side aspects of the code will still hit
1189  * other monsters)
1190  */
1191  dir = path_to_player(part, pl, 0);
1192  if (dir == 0)
1193  return 0;
1194 
1195  if (QUERY_FLAG(head, FLAG_FRIENDLY)) {
1196  owner = object_get_owner(head);
1197  if (owner != NULL) {
1198  if (get_rangevector(head, owner, &rv1, 0x1)
1199  && dirdiff(dir, rv1.direction) < 2) {
1200  return 0; /* Might hit owner with spell */
1201  }
1202  }
1203  }
1204 
1205  if (QUERY_FLAG(head, FLAG_CONFUSED))
1206  dir = get_randomized_dir(dir);
1207 
1208  scroll = NULL;
1209  FOR_INV_PREPARE(head, tmp)
1210  if (tmp->type == SCROLL && monster_should_cast_spell(tmp->inv)) {
1211  scroll = tmp;
1212  break;
1213  }
1214  FOR_INV_FINISH();
1215 
1216  /* Used up all his scrolls, so nothing do to */
1217  if (!scroll) {
1219  return 0;
1220  }
1221 
1222  /* Spell should be cast on caster (ie, heal, strength) */
1223  if (scroll->inv->range == 0)
1224  dir = 0;
1225 
1226  /* Face the direction that we want to cast. */
1227  head->direction = dir;
1228  head->facing = head->direction;
1229  if (head->animation_id)
1230  animate_object(head, head->direction);
1231 
1232  ob_apply(scroll, part, 0);
1233  return 1;
1234 }
1235 
1264 static int monster_use_skill(object *head, object *part, object *pl, int dir) {
1265  object *owner;
1266  int found;
1267 
1268  dir = path_to_player(part, pl, 0);
1269  if (dir == 0)
1270  return 0;
1271 
1272  if (QUERY_FLAG(head, FLAG_FRIENDLY)) {
1273  owner = object_get_owner(head);
1274  if (owner != NULL) {
1275  rv_vector rv;
1276 
1277  if (get_rangevector(head, owner, &rv, 0) && dirdiff(dir, rv.direction) < 1)
1278  return 0; /* Might hit owner with skill -thrown rocks for example ?*/
1279  }
1280  }
1281  if (QUERY_FLAG(head, FLAG_CONFUSED))
1282  dir = get_randomized_dir(dir);
1283 
1284  /* skill selection - monster will use the next unused skill.
1285  * well...the following scenario will allow the monster to
1286  * toggle between 2 skills. One day it would be nice to make
1287  * more skills available to monsters.
1288  */
1289  found = 0;
1290  FOR_INV_PREPARE(head, skill)
1291  if (skill->type == SKILL && skill != head->chosen_skill) {
1292  head->chosen_skill = skill;
1293  found = 1;
1294  break;
1295  }
1296  FOR_INV_FINISH();
1297 
1298  if (!found && !head->chosen_skill) {
1299  LOG(llevDebug, "Error: Monster %s (%d) has FLAG_READY_SKILL without skill.\n", head->name, head->count);
1301  return 0;
1302  }
1303  /* use skill */
1304  return do_skill(head, part, head->chosen_skill, dir, NULL);
1305 }
1306 
1321 static int monster_use_range(object *head, object *part, object *pl, int dir) {
1322  object *owner;
1323  int at_least_one = 0;
1324 
1325  dir = path_to_player(part, pl, 0);
1326  if (dir == 0)
1327  return 0;
1328 
1329  if (QUERY_FLAG(head, FLAG_FRIENDLY)) {
1330  owner = object_get_owner(head);
1331  if (owner != NULL) {
1332  rv_vector rv;
1333 
1334  if (get_rangevector(head, owner, &rv, 0) && dirdiff(dir, rv.direction) < 2)
1335  return 0; /* Might hit owner with spell */
1336  }
1337  }
1338  if (QUERY_FLAG(head, FLAG_CONFUSED))
1339  dir = get_randomized_dir(dir);
1340 
1341  FOR_INV_PREPARE(head, wand) {
1342  if (wand->type == WAND) {
1343  /* Found a wand, let's see if it has charges left */
1344  at_least_one = 1;
1345  if (wand->stats.food <= 0)
1346  continue;
1347 
1348  cast_spell(head, wand, dir, wand->inv, NULL);
1349  drain_wand_charge(wand);
1350 
1351  /* Success */
1352  return 1;
1353  }
1354 
1355  if (wand->type == ROD) {
1356  /* Found rod/horn, let's use it if possible */
1357  at_least_one = 1;
1358  if (wand->stats.hp < MAX(wand->inv->stats.sp, wand->inv->stats.grace))
1359  continue;
1360 
1361  /* drain charge before casting spell - can be a case where the
1362  * spell destroys the monster, and rod, so if done after, results
1363  * in crash.
1364  */
1365  drain_rod_charge(wand);
1366  cast_spell(head, wand, dir, wand->inv, NULL);
1367 
1368  /* Success */
1369  return 1;
1370  }
1371  } FOR_INV_FINISH();
1372 
1373  if (at_least_one)
1374  return 0;
1375 
1376  LOG(llevError, "Error: Monster %s (%d) HAS_READY_RANG() without wand/horn/rod.\n", head->name, head->count);
1378  return 0;
1379 }
1380 
1397 static int monster_use_bow(object *head, object *part, object *pl, int dir) {
1398  object *owner;
1399  rv_vector rv;
1400  int16_t x, y;
1401  mapstruct *map;
1402 
1403  if (!get_rangevector(part, pl, &rv, 1))
1404  return 0;
1405  if (rv.distance > 100)
1406  /* Too far */
1407  return 0;
1408  if (rv.distance_x != 0 && rv.distance_y != 0 && abs(rv.distance_x) != abs(rv.distance_y))
1409  /* Player must be on same horizontal, vertical or diagonal line. */
1410  return 0;
1411  dir = rv.direction;
1412 
1413  if (QUERY_FLAG(head, FLAG_FRIENDLY))
1414  owner = object_get_owner(head);
1415  else
1416  owner = NULL;
1417 
1418  /* The monster can possibly fire, let's see if the path is ok for an arrow. */
1419  x = part->x;
1420  y = part->y;
1421  map = part->map;
1422  while (x != pl->x || y != pl->y || map != pl->map) {
1423  x += freearr_x[dir];
1424  y += freearr_y[dir];
1425  map = get_map_from_coord(map, &x, &y);
1426  if (!map) {
1427  LOG(llevError, "monster_use_bow: no map but still path exists??\n");
1428  return 0;
1429  }
1430  if ((GET_MAP_MOVE_BLOCK(map, x, y)&MOVE_FLY_LOW) == MOVE_FLY_LOW)
1431  return 0;
1432  if (owner && owner->x == x && owner->y == y && owner->map == map)
1433  /* Don't hit owner! */
1434  return 0;
1435  }
1436 
1437  /* Finally, path is clear, can fire. */
1438 
1439  if (QUERY_FLAG(head, FLAG_CONFUSED))
1440  dir = get_randomized_dir(dir);
1441 
1442  /* in server/player.c */
1443  return fire_bow(head, NULL, dir, 0, part->x, part->y);
1444 }
1445 
1454 static int monster_get_weapon_quality(const object *item) {
1455  int val;
1456  int i;
1457 
1458  val = item->stats.dam;
1459  val += item->magic*3;
1460  /* Monsters don't really get benefits from things like regen rates
1461  * from items. But the bonus for their stats are very important.
1462  */
1463  for (i = 0; i < NUM_STATS; i++)
1464  val += get_attr_value(&item->stats, i)*2;
1465  return val;
1466 }
1467 
1480 static int monster_check_good_weapon(object *who, object *item) {
1481  object *other_weap;
1482  int val;
1483 
1484  other_weap = object_find_by_type_applied(who, item->type);
1485  if (other_weap == NULL) /* No other weapons */
1486  return 1;
1487 
1488  /* Rather than go through and apply the new one, and see if it is
1489  * better, just do some simple checks
1490  * Put some multipliers for things that hvae several effects,
1491  * eg, magic affects both damage and wc, so it has more weight
1492  */
1493 
1495  return val > 0;
1496 }
1497 
1506 static int monster_get_armour_quality(const object *item) {
1507  int val;
1508 
1509  val = item->stats.ac;
1510  val += item->resist[ATNR_PHYSICAL]/5;
1511  val += item->magic*3;
1512  return val;
1513 }
1514 
1527 static int monster_check_good_armour(object *who, object *item) {
1528  object *other_armour;
1529  int val, i;
1530 
1531  other_armour = object_find_by_type_applied(who, item->type);
1532  if (other_armour == NULL) /* No other armour, use the new */
1533  return 1;
1534 
1535  val = monster_get_armour_quality(item)-monster_get_armour_quality(other_armour);
1536 
1537  /* for the other protections, do weigh them very much in the equation -
1538  * it is the armor protection which is most important, because there is
1539  * no good way to know what the player may attack the monster with.
1540  * So if the new item has better protection than the old, give that higher
1541  * value. If the reverse, then decrease the value of this item some.
1542  */
1543  for (i = 1; i < NROFATTACKS; i++) {
1544  if (item->resist[i] > other_armour->resist[i])
1545  val++;
1546  else if (item->resist[i] < other_armour->resist[i])
1547  val--;
1548  }
1549 
1550  /* Very few armours have stats, so not much need to worry about those. */
1551 
1552  return val > 0;
1553 }
1554 
1562 static void monster_check_apply(object *mon, object *item) {
1563  int flag = 0;
1564 
1565  if (item->type == SPELLBOOK
1566  && mon->arch != NULL
1567  && (QUERY_FLAG(&mon->arch->clone, FLAG_CAST_SPELL))) {
1568  SET_FLAG(mon, FLAG_CAST_SPELL);
1569  return;
1570  }
1571 
1572  /* If for some reason, this item is already applied, no more work to do */
1573  if (QUERY_FLAG(item, FLAG_APPLIED))
1574  return;
1575 
1576  /* Might be better not to do this - if the monster can fire a bow,
1577  * it is possible in his wanderings, he will find one to use. In
1578  * which case, it would be nice to have ammo for it.
1579  */
1580  if (QUERY_FLAG(mon, FLAG_USE_BOW) && item->type == ARROW) {
1581  /* Check for the right kind of bow */
1582  object *bow;
1583 
1584  bow = object_find_by_type_and_race(mon, BOW, item->race);
1585  if (bow != NULL) {
1586  SET_FLAG(mon, FLAG_READY_BOW);
1587  LOG(llevMonster, "Found correct bow for arrows.\n");
1588  return; /* nothing more to do for arrows */
1589  }
1590  }
1591 
1592  if (item->type == TREASURE && mon->will_apply&WILL_APPLY_TREASURE)
1593  flag = 1;
1594  /* Eating food gets hp back */
1595  else if (item->type == FOOD && mon->will_apply&WILL_APPLY_FOOD)
1596  flag = 1;
1597  else if (item->type == SCROLL && QUERY_FLAG(mon, FLAG_USE_SCROLL)) {
1598  if (!item->inv)
1599  LOG(llevDebug, "Monster %d having scroll %d with empty inventory!\n", mon->count, item->count);
1600  else if (monster_should_cast_spell(item->inv))
1602  /* Don't use it right now */
1603  return;
1604  } else if (item->type == WEAPON)
1605  flag = monster_check_good_weapon(mon, item);
1606  else if (IS_ARMOR(item) || IS_SHIELD(item))
1607  flag = monster_check_good_armour(mon, item);
1608  /* Should do something more, like make sure this is a better item */
1609  else if (item->type == RING)
1610  flag = 1;
1611  else if (item->type == WAND || item->type == ROD) {
1612  /* We never really 'ready' the wand/rod/horn, because that would mean the
1613  * weapon would get undone.
1614  */
1615  if (!(apply_can_apply_object(mon, item)&CAN_APPLY_NOT_MASK)) {
1616  SET_FLAG(mon, FLAG_READY_RANGE);
1617  SET_FLAG(item, FLAG_APPLIED);
1618  }
1619  return;
1620  } else if (item->type == BOW) {
1621  /* We never really 'ready' the bow, because that would mean the
1622  * weapon would get undone.
1623  */
1624  if (!(apply_can_apply_object(mon, item)&CAN_APPLY_NOT_MASK))
1625  SET_FLAG(mon, FLAG_READY_BOW);
1626  return;
1627  } else if (item->type == SKILL) {
1628  /*
1629  * skills are specials: monsters must have the 'FLAG_READY_SKILL' flag set,
1630  * else they can't use the skill...
1631  * Skills also don't need to get applied, so return now.
1632  */
1633  SET_FLAG(mon, FLAG_READY_SKILL);
1634  return;
1635  }
1636 
1637  /* if we don't match one of the above types, return now.
1638  * apply_can_apply_object() will say that we can apply things like flesh,
1639  * bolts, and whatever else, because it only checks against the
1640  * body_info locations.
1641  */
1642  if (!flag)
1643  return;
1644 
1645  /* Check to see if the monster can use this item. If not, no need
1646  * to do further processing. Note that apply_can_apply_object() already checks
1647  * for the CAN_USE flags.
1648  */
1650  return;
1651 
1652  /* should only be applying this item, not unapplying it.
1653  * also, ignore status of curse so they can take off old armour.
1654  * monsters have some advantages after all.
1655  */
1657  return;
1658 }
1659 
1679 static void monster_check_pickup(object *monster) {
1680  object *part;
1681 
1682  for (part = monster; part != NULL; part = part->more)
1683  FOR_BELOW_PREPARE(part, tmp) {
1684  if (monster_can_pick(monster, tmp)) {
1685  uint32_t nrof;
1686 
1687  if (tmp->weight > 0) {
1688  int32_t weight_limit;
1689 
1690  weight_limit = get_weight_limit(monster->stats.Str);
1691  if (weight_limit >= monster->weight-monster->carrying)
1692  nrof = (weight_limit-monster->weight-monster->carrying)/tmp->weight;
1693  else
1694  nrof = 0;
1695  } else
1696  nrof = MAX(1, tmp->nrof);
1697  if (nrof >= 1) {
1698  object *tmp2;
1699 
1700  tmp2 = object_split(tmp, MIN(nrof, MAX(1, tmp->nrof)), NULL, 0);
1701  tmp2 = object_insert_in_ob(tmp2, monster);
1702  (void)monster_check_apply(monster, tmp2);
1703  }
1704  }
1705  } FOR_BELOW_FINISH();
1706 }
1707 
1717 static int monster_can_pick(object *monster, object *item) {
1718  int flag = 0;
1719  int i;
1720 
1721  if (!object_can_pick(monster, item))
1722  return 0;
1723 
1724  if (QUERY_FLAG(item, FLAG_UNPAID))
1725  return 0;
1726 
1727  if (monster->pick_up&64) /* All */
1728  flag = 1;
1729 
1730  else {
1731  if (IS_WEAPON(item))
1732  flag = (monster->pick_up&8) || QUERY_FLAG(monster, FLAG_USE_WEAPON);
1733  else if (IS_ARMOR(item))
1734  flag = (monster->pick_up&16) || QUERY_FLAG(monster, FLAG_USE_ARMOUR);
1735  else if (IS_SHIELD(item))
1736  flag = (monster->pick_up&16) || QUERY_FLAG(monster, FLAG_USE_SHIELD);
1737  else switch (item->type) {
1738  case MONEY:
1739  case GEM:
1740  flag = monster->pick_up&2;
1741  break;
1742 
1743  case FOOD:
1744  flag = monster->pick_up&4;
1745  break;
1746 
1747  case SKILL:
1748  flag = QUERY_FLAG(monster, FLAG_CAN_USE_SKILL);
1749  break;
1750 
1751  case RING:
1752  flag = QUERY_FLAG(monster, FLAG_USE_RING);
1753  break;
1754 
1755  case WAND:
1756  case ROD:
1757  flag = QUERY_FLAG(monster, FLAG_USE_RANGE);
1758  break;
1759 
1760  case SPELLBOOK:
1761  flag = (monster->arch != NULL && QUERY_FLAG(&monster->arch->clone, FLAG_CAST_SPELL));
1762  break;
1763 
1764  case SCROLL:
1765  flag = QUERY_FLAG(monster, FLAG_USE_SCROLL);
1766  break;
1767 
1768  case BOW:
1769  case ARROW:
1770  flag = QUERY_FLAG(monster, FLAG_USE_BOW);
1771  break;
1772  }
1773  if (!flag && QUERY_FLAG(item, FLAG_IS_THROWN) && object_find_by_type_subtype(monster, SKILL, SK_THROWING) != NULL)
1774  flag = (monster->pick_up&8) || QUERY_FLAG(monster, FLAG_USE_WEAPON);
1775  /* Simplistic check - if the monster has a location to equip it, he will
1776  * pick it up. Note that this doesn't handle cases where an item may
1777  * use several locations.
1778  */
1779  for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
1780  if (monster->body_info[i] && item->body_info[i]) {
1781  flag = 1;
1782  break;
1783  }
1784  }
1785  }
1786 
1787  if (((!(monster->pick_up&32)) && flag) || ((monster->pick_up&32) && (!flag)))
1788  return 1;
1789  return 0;
1790 }
1791 
1798 static void monster_apply_below(object *monster) {
1799  FOR_BELOW_PREPARE(monster, tmp) {
1800  switch (tmp->type) {
1801  case CF_HANDLE:
1802  case TRIGGER:
1803  if (monster->will_apply&WILL_APPLY_HANDLE)
1804  apply_manual(monster, tmp, 0);
1805  break;
1806 
1807  case TREASURE:
1808  if (monster->will_apply&WILL_APPLY_TREASURE)
1809  apply_manual(monster, tmp, 0);
1810  break;
1811  }
1812  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
1813  break;
1814  } FOR_BELOW_FINISH();
1815 }
1816 
1821 void monster_check_apply_all(object *monster) {
1822  FOR_INV_PREPARE(monster, inv)
1823  monster_check_apply(monster, inv);
1824  FOR_INV_FINISH();
1825 }
1826 
1831 void monster_npc_call_help(object *op) {
1832  int x, y, mflags;
1833  int16_t sx, sy;
1834  mapstruct *m;
1835 
1836  for (x = -3; x < 4; x++)
1837  for (y = -3; y < 4; y++) {
1838  m = op->map;
1839  sx = op->x+x;
1840  sy = op->y+y;
1841  mflags = get_map_flags(m, &m, sx, sy, &sx, &sy);
1842  /* If nothing alive on this space, no need to search the space. */
1843  if ((mflags&P_OUT_OF_MAP) || !(mflags&P_IS_ALIVE))
1844  continue;
1845 
1846  FOR_MAP_PREPARE(m, sx, sy, npc)
1848  object_set_enemy(npc, op->enemy);
1849  FOR_MAP_FINISH();
1850  }
1851 }
1852 
1861 static int monster_dist_att(int dir, object *enemy, object *part, rv_vector *rv) {
1862  if (monster_can_hit(part, enemy, rv))
1863  return dir;
1864  if (rv->distance < 10)
1865  return absdir(dir+4);
1866  else if (rv->distance > 18)
1867  return dir;
1868  return 0;
1869 }
1870 
1880 static int monster_run_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv) {
1881  if ((monster_can_hit(part, enemy, rv) && ob->move_status < 20) || ob->move_status < 20) {
1882  ob->move_status++;
1883  return (dir);
1884  } else if (ob->move_status > 20)
1885  ob->move_status = 0;
1886  return absdir(dir+4);
1887 }
1888 
1896 static int monster_hitrun_att(int dir, object *ob, object *enemy) {
1897  if (ob->move_status++ < 25)
1898  return dir;
1899  else if (ob->move_status < 50)
1900  return absdir(dir+4);
1901  ob->move_status = 0;
1902  return absdir(dir+4);
1903 }
1904 
1914 static int monster_wait_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv) {
1915  int inrange = monster_can_hit(part, enemy, rv);
1916 
1917  if (ob->move_status || inrange)
1918  ob->move_status++;
1919 
1920  if (ob->move_status == 0)
1921  return 0;
1922  else if (ob->move_status < 10)
1923  return dir;
1924  else if (ob->move_status < 15)
1925  return absdir(dir+4);
1926  ob->move_status = 0;
1927  return 0;
1928 }
1929 
1939 static int monster_disthit_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv) {
1940  /* The logic below here looked plain wrong before. Basically, what should
1941  * happen is that if the creatures hp percentage falls below run_away,
1942  * the creature should run away (dir+4)
1943  * I think its wrong for a creature to have a zero maxhp value, but
1944  * at least one map has this set, and whatever the map contains, the
1945  * server should try to be resilant enough to avoid the problem
1946  */
1947  if (ob->stats.maxhp && (ob->stats.hp*100)/ob->stats.maxhp < ob->run_away)
1948  return absdir(dir+4);
1949  return monster_dist_att(dir, enemy, part, rv);
1950 }
1951 
1958 static int monster_wait_att2(int dir, rv_vector *rv) {
1959  if (rv->distance < 9)
1960  return absdir(dir+4);
1961  return 0;
1962 }
1963 
1968 static void monster_circ1_move(object *ob) {
1969  static const int circle [12] = { 3, 3, 4, 5, 5, 6, 7, 7, 8, 1, 1, 2 };
1970 
1971  if (++ob->move_status > 11)
1972  ob->move_status = 0;
1973  if (!(move_object(ob, circle[ob->move_status])))
1974  (void)move_object(ob, RANDOM()%8+1);
1975 }
1976 
1981 static void monster_circ2_move(object *ob) {
1982  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 };
1983 
1984  if (++ob->move_status > 19)
1985  ob->move_status = 0;
1986  if (!(move_object(ob, circle[ob->move_status])))
1987  (void)move_object(ob, RANDOM()%8+1);
1988 }
1989 
1994 static void monster_pace_movev(object *ob) {
1995  if (ob->move_status++ > 6)
1996  ob->move_status = 0;
1997  if (ob->move_status < 4)
1998  (void)move_object(ob, 5);
1999  else
2000  (void)move_object(ob, 1);
2001 }
2002 
2007 static void monster_pace_moveh(object *ob) {
2008  if (ob->move_status++ > 6)
2009  ob->move_status = 0;
2010  if (ob->move_status < 4)
2011  (void)move_object(ob, 3);
2012  else
2013  (void)move_object(ob, 7);
2014 }
2015 
2020 static void monster_pace2_movev(object *ob) {
2021  if (ob->move_status++ > 16)
2022  ob->move_status = 0;
2023  if (ob->move_status < 6)
2024  (void)move_object(ob, 5);
2025  else if (ob->move_status < 8)
2026  return;
2027  else if (ob->move_status < 13)
2028  (void)move_object(ob, 1);
2029 }
2030 
2035 static void monster_pace2_moveh(object *ob) {
2036  if (ob->move_status++ > 16)
2037  ob->move_status = 0;
2038  if (ob->move_status < 6)
2039  (void)move_object(ob, 3);
2040  else if (ob->move_status < 8)
2041  return;
2042  else if (ob->move_status < 13)
2043  (void)move_object(ob, 7);
2044 }
2045 
2050 static void monster_rand_move(object *ob) {
2051  int i;
2052 
2053  if (ob->move_status < 1
2054  || ob->move_status > 8
2055  || !(move_object(ob, ob->move_status || !(RANDOM()%9))))
2056  for (i = 0; i < 5; i++) {
2057  ob->move_status = RANDOM()%8+1;
2058  if (move_object(ob, ob->move_status))
2059  return;
2060  }
2061 }
2062 
2070 void monster_check_earthwalls(object *op, mapstruct *m, int x, int y) {
2071  FOR_MAP_PREPARE(m, x, y, tmp)
2072  if (tmp->type == EARTHWALL) {
2073  hit_player(tmp, op->stats.dam, op, AT_PHYSICAL, 1);
2074  return;
2075  }
2076  FOR_MAP_FINISH();
2077 }
2078 
2086 void monster_check_doors(object *op, mapstruct *m, int x, int y) {
2087  FOR_MAP_PREPARE(m, x, y, tmp)
2088  if (tmp->type == DOOR) {
2089  hit_player(tmp, op->stats.dam, op, AT_PHYSICAL, 1);
2090  return;
2091  }
2092  FOR_MAP_FINISH();
2093 }
2094 
2100 void monster_do_say(const mapstruct *map, const char *message) {
2102  message);
2103 }
2104 
2111 static StringBuffer *monster_format_say(const object* npc, const char *message) {
2112  char name[MAX_BUF];
2113  StringBuffer *buf;
2114 
2115  query_name(npc, name, sizeof(name));
2116  buf = stringbuffer_new();
2117  stringbuffer_append_printf(buf, "%s says: %s", name, message);
2118  return buf;
2119 }
2120 
2126 static const char *get_reply_text_own(reply_type rt) {
2127  switch (rt) {
2128  case rt_say:
2129  return "say";
2130  case rt_reply:
2131  return "reply";
2132  case rt_question:
2133  return "ask";
2134  }
2135  assert(0);
2136  return NULL;
2137 }
2138 
2144 static const char *get_reply_text_other(reply_type rt) {
2145  switch (rt) {
2146  case rt_say:
2147  return "says";
2148  case rt_reply:
2149  return "replies";
2150  case rt_question:
2151  return "asks";
2152  }
2153  assert(0);
2154  return NULL;
2155 }
2156 
2182 void monster_communicate(object *op, const char *txt) {
2183  int i, mflags;
2184  int16_t x, y;
2185  mapstruct *mp, *orig_map = op->map;
2186  char own[MAX_BUF], others[MAX_BUF];
2187  talk_info info;
2188 
2189  info.text = txt;
2190  info.message = NULL;
2191  info.replies_count = 0;
2192  info.who = op;
2193  info.npc_msg_count = 0;
2194 
2195  /* Note that this loop looks pretty inefficient to me - we look and try to talk
2196  * to every object within 2 spaces. It would seem that if we trim this down to
2197  * only try to talk to objects with npc->msg set, things would be a lot more efficient,
2198  * but I'm not sure if there are any objects out there that don't have a message and instead
2199  * rely sorely on events - MSW 2009-04-14
2200  */
2201  for (i = 0; i <= SIZEOFFREE2; i++) {
2202  mp = op->map;
2203  x = op->x+freearr_x[i];
2204  y = op->y+freearr_y[i];
2205 
2206  mflags = get_map_flags(mp, &mp, x, y, &x, &y);
2207  if (mflags&P_OUT_OF_MAP)
2208  continue;
2209 
2210  FOR_MAP_PREPARE(mp, x, y, npc) {
2211  monster_talk_to_npc(npc, &info);
2212  if (orig_map != op->map) {
2213  LOG(llevDebug, "Warning: Forced to swap out very recent map - MAX_OBJECTS should probably be increased\n");
2214  return;
2215  }
2216  } FOR_MAP_FINISH();
2217  }
2218 
2219  /* First, what the player says. */
2220  if (info.message != NULL) {
2221  snprintf(own, sizeof(own), "You %s: %s", get_reply_text_own(info.message_type), info.message);
2222  snprintf(others, sizeof(others), "%s %s: %s", op->name, get_reply_text_other(info.message_type), info.message);
2223  free_string(info.message);
2224  } else {
2225  snprintf(own, sizeof(own), "You say: %s", txt);
2226  snprintf(others, sizeof(others), "%s says: %s", op->name, txt);
2227  }
2230 
2231  /* Then NPCs can actually talk. */
2232  for (i = 0; i < info.npc_msg_count; i++) {
2233  monster_do_say(orig_map, info.npc_msgs[i]);
2234  free_string(info.npc_msgs[i]);
2235  }
2236 
2237  /* Finally, the replies the player can use. */
2238  if (info.replies_count > 0) {
2240  for (i = 0; i < info.replies_count; i++) {
2242  free_string(info.replies_words[i]);
2243  free_string(info.replies[i]);
2244  }
2245  }
2246 }
2247 
2256 static int monster_do_talk_npc(object *npc, talk_info *info) {
2257  struct_dialog_reply *reply;
2258  struct_dialog_message *message;
2259 
2260  if (!get_dialog_message(npc, info->text, &message, &reply))
2261  return 0;
2262 
2263  if (reply) {
2264  info->message = add_string(reply->message);
2265  info->message_type = reply->type;
2266  }
2267 
2268  if (npc->type == MAGIC_EAR) {
2270  use_trigger(npc);
2271  } else {
2272  char value[2];
2273 
2274  if (info->npc_msg_count < MAX_NPC) {
2276  info->npc_msg_count++;
2277  }
2278 
2279  /* mark that the npc was talked to, so it won't move randomly later on */
2280  value[0] = '3' + rand() % 6;
2281  value[1] = '\0';
2282  object_set_value(npc, "talked_to", value, 1);
2283 
2284  reply = message->replies;
2285  while (reply && info->replies_count < MAX_REPLIES) {
2286  info->replies[info->replies_count] = add_string(reply->message);
2287  info->replies_words[info->replies_count] = add_string(reply->reply);
2288  info->replies_count++;
2289  reply = reply->next;
2290  }
2291  }
2292 
2293  return 1;
2294 }
2295 
2301 void monster_npc_say(object *npc, const char *cp) {
2302  char *message;
2303  StringBuffer *buf = monster_format_say(npc, cp);
2304 
2305  message = stringbuffer_finish(buf);
2306  monster_do_say(npc->map, message);
2307  free(message);
2308 }
2309 
2318 static int monster_talk_to_npc(object *npc, talk_info *info) {
2319  /* Move this commone area up here - shouldn't cost much extra cpu
2320  * time, and makes the function more readable */
2321  /* Lauwenmark: Handle for plugin say event */
2322  if (plugin_event_say(npc, info) != 0)
2323  return 0;
2324  /* Lauwenmark - Here we let the objects inside inventories hear and answer, too. */
2325  /* This allows the existence of "intelligent" weapons you can discuss with */
2326  FOR_INV_PREPARE(npc, cobj)
2327  if (plugin_event_say(cobj, info) != 0)
2328  return 0;
2329  FOR_INV_FINISH();
2330  if (info->who == npc)
2331  return 0;
2332  return monster_do_talk_npc(npc, info);
2333 }
2334 
2347 object *monster_find_throw_ob(object *op) {
2348  /* New throw code: look through the inventory. Grap the first legal is_thrown
2349  * marked item and throw it to the enemy.
2350  */
2351 
2352  FOR_INV_PREPARE(op, tmp) {
2353  /* Can't throw invisible objects or items that are applied */
2354  if (!tmp->invisible && !QUERY_FLAG(tmp, FLAG_APPLIED) && QUERY_FLAG(tmp, FLAG_IS_THROWN)) {
2355 #ifdef DEBUG_THROW
2356  char what[MAX_BUF];
2357 
2358  query_name(tmp, what, MAX_BUF);
2359  LOG(llevDebug, "%s chooses to throw: %s (%d)\n", op->name, what, tmp->count);
2360 #endif
2361  return tmp;
2362  }
2363  } FOR_INV_FINISH();
2364 
2365 #ifdef DEBUG_THROW
2366  LOG(llevDebug, "%s chooses to throw nothing\n", op->name);
2367 #endif
2368  return NULL;
2369 }
2370 
2386 int monster_can_detect_enemy(object *op, object *enemy, rv_vector *rv) {
2387  int radius = MIN_MON_RADIUS, hide_discovery;
2388 
2389  /* null detection for any of these condtions always */
2390  if (!op || !enemy || !op->map || !enemy->map)
2391  return 0;
2392 
2393  /* If the monster (op) has no way to get to the enemy, do nothing */
2394  if (!get_rangevector(op, enemy, rv, 0))
2395  return 0;
2396 
2397  /* Monsters always ignore the DM */
2398  if (op->type != PLAYER && QUERY_FLAG(enemy, FLAG_WIZ))
2399  return 0;
2400 
2401  /* simple check. Should probably put some range checks in here. */
2402  if (monster_can_see_enemy(op, enemy))
2403  return 1;
2404 
2405  /* The rest of this is for monsters. Players are on their own for
2406  * finding enemies!
2407  */
2408  if (op->type == PLAYER)
2409  return 0;
2410 
2411  /* Quality invisible? Bah, we wont see them w/o SEE_INVISIBLE
2412  * flag (which was already checked) in can_see_enmy (). Lets get out of here
2413  */
2414  if (enemy->invisible && (!enemy->contr || (!enemy->contr->tmp_invis && !enemy->contr->hidden)))
2415  return 0;
2416 
2417  /* use this for invis also */
2418  hide_discovery = op->stats.Int/5;
2419 
2420  /* Determine Detection radii */
2421  if (!enemy->hide) /* to detect non-hidden (eg dark/invis enemy) */
2422  radius = MAX(op->stats.Wis/5+1, MIN_MON_RADIUS);
2423  else { /* a level/INT/Dex adjustment for hiding */
2424  object *sk_hide;
2425  int bonus = (op->level/2)+(op->stats.Int/5);
2426 
2427  if (enemy->type == PLAYER) {
2428  sk_hide = find_skill_by_number(enemy, SK_HIDING);
2429  if (sk_hide != NULL)
2430  bonus -= sk_hide->level;
2431  else {
2432  LOG(llevError, "monster_can_detect_enemy() got hidden player w/o hiding skill!\n");
2433  make_visible(enemy);
2434  radius = MAX(radius, MIN_MON_RADIUS);
2435  }
2436  } else /* enemy is not a player */
2437  bonus -= enemy->level;
2438 
2439  radius += bonus/5;
2440  hide_discovery += bonus*5;
2441  } /* else creature has modifiers for hiding */
2442 
2443  /* Radii stealth adjustment. Only if you are stealthy
2444  * will you be able to sneak up closer to creatures */
2445  if (QUERY_FLAG(enemy, FLAG_STEALTH))
2446  radius = radius/2, hide_discovery = hide_discovery/3;
2447 
2448  /* Radii adjustment for enemy standing in the dark */
2449  if (op->map->darkness > 0 && !monster_stand_in_light(enemy)) {
2450  /* on dark maps body heat can help indicate location with infravision
2451  * undead don't have body heat, so no benefit detecting them.
2452  */
2453  if (QUERY_FLAG(op, FLAG_SEE_IN_DARK) && !is_true_undead(enemy))
2454  radius += op->map->darkness/2;
2455  else
2456  radius -= op->map->darkness/2;
2457 
2458  /* op next to a monster (and not in complete darkness)
2459  * the monster should have a chance to see you.
2460  */
2461  if (radius < MIN_MON_RADIUS && op->map->darkness < 5 && rv->distance <= 1)
2462  radius = MIN_MON_RADIUS;
2463  } /* if on dark map */
2464 
2465  /* Lets not worry about monsters that have incredible detection
2466  * radii, we only need to worry here about things the player can
2467  * (potentially) see. This is 13, as that is the maximum size the player
2468  * may have for their map - in that way, creatures at the edge will
2469  * do something. Note that the distance field in the
2470  * vector is real distance, so in theory this should be 18 to
2471  * find that.
2472  */
2473  if (radius > 13)
2474  radius = 13;
2475 
2476  /* Enemy in range! Now test for detection */
2477  if ((int)rv->distance <= radius) {
2478  /* ah, we are within range, detected? take cases */
2479  if (!enemy->invisible) /* enemy in dark squares... are seen! */
2480  return 1;
2481 
2482  /* hidden or low-quality invisible */
2483  if (enemy->hide && rv->distance <= 1 && RANDOM()%100 <= (unsigned int)hide_discovery) {
2484  make_visible(enemy);
2485  /* inform players of new status */
2486  if (enemy->type == PLAYER && player_can_view(enemy, op))
2488  "You are discovered by %s!",
2489  op->name);
2490  return 1; /* detected enemy */
2491  } else if (enemy->invisible) {
2492  /* Change this around - instead of negating the invisible, just
2493  * return true so that the mosnter that managed to detect you can
2494  * do something to you. Decreasing the duration of invisible
2495  * doesn't make a lot of sense IMO, as a bunch of stupid creatures
2496  * can then basically negate the spell. The spell isn't negated -
2497  * they just know where you are!
2498  */
2499  if (RANDOM()%50 <= (unsigned int)hide_discovery) {
2500  if (enemy->type == PLAYER) {
2501  char name[MAX_BUF];
2502 
2503  query_name(op, name, MAX_BUF);
2505  "You see %s noticing your position.",
2506  name);
2507  }
2508  return 1;
2509  }
2510  }
2511  } /* within range */
2512 
2513  /* Wasn't detected above, so still hidden */
2514  return 0;
2515 }
2516 
2526 int monster_stand_in_light(object *op) {
2527  int16_t nx, ny;
2528  mapstruct *m;
2529 
2530  if (!op)
2531  return 0;
2532  if (op->glow_radius > 0)
2533  return 1;
2534 
2535  if (op->map) {
2536  int x, y, x1, y1;
2537 
2538  /* Check the spaces with the max light radius to see if any of them
2539  * have lights, and if any of them light the player enough, then return 1.
2540  */
2541  for (x = op->x-MAX_LIGHT_RADII; x <= op->x+MAX_LIGHT_RADII; x++) {
2542  for (y = op->y-MAX_LIGHT_RADII; y <= op->y+MAX_LIGHT_RADII; y++) {
2543  m = op->map;
2544  nx = x;
2545  ny = y;
2546 
2547  if (get_map_flags(m, &m, nx, ny, &nx, &ny)&P_OUT_OF_MAP)
2548  continue;
2549 
2550  x1 = abs(x-op->x)*abs(x-op->x);
2551  y1 = abs(y-op->y)*abs(y-op->y);
2552  if (isqrt(x1+y1) < GET_MAP_LIGHT(m, nx, ny))
2553  return 1;
2554  }
2555  }
2556  }
2557  return 0;
2558 }
2559 
2569 int monster_can_see_enemy(object *op, object *enemy) {
2570  object *looker = HEAD(op);
2571 
2572  /* safety */
2573  if (!looker || !enemy || !QUERY_FLAG(looker, FLAG_ALIVE))
2574  return 0;
2575 
2576  /* we dont give a full treatment of xrays here (shorter range than normal,
2577  * see through walls). Should we change the code elsewhere to make you
2578  * blind even if you can xray?
2579  */
2580  if (QUERY_FLAG(looker, FLAG_BLIND) && !QUERY_FLAG(looker, FLAG_XRAYS))
2581  return 0;
2582 
2583  /* checking for invisible things */
2584  if (enemy->invisible) {
2585  /* HIDDEN ENEMY. by definition, you can't see hidden stuff!
2586  * However, if you carry any source of light, then the hidden
2587  * creature is seeable (and stupid) */
2588  if (has_carried_lights(enemy)) {
2589  if (enemy->hide) {
2590  make_visible(enemy);
2592  "Your light reveals your hiding spot!");
2593  }
2594  return 1;
2595  } else if (enemy->hide)
2596  return 0;
2597 
2598  /* Invisible enemy. Break apart the check for invis undead/invis looker
2599  * into more simple checks - the QUERY_FLAG doesn't return 1/0 values,
2600  * and making it a conditional makes the code pretty ugly.
2601  */
2602  if (!QUERY_FLAG(looker, FLAG_SEE_INVISIBLE)) {
2603  if (makes_invisible_to(enemy, looker))
2604  return 0;
2605  }
2606  } else if (looker->type == PLAYER) /* for players, a (possible) shortcut */
2607  if (player_can_view(looker, enemy))
2608  return 1;
2609 
2610  /* ENEMY IN DARK MAP. Without infravision, the enemy is not seen
2611  * unless they carry a light or stand in light. Darkness doesnt
2612  * inhibit the undead per se (but we should give their archs
2613  * CAN_SEE_IN_DARK, this is just a safety
2614  * we care about the enemy maps status, not the looker.
2615  * only relevant for tiled maps, but it is possible that the
2616  * enemy is on a bright map and the looker on a dark - in that
2617  * case, the looker can still see the enemy
2618  */
2619  if (enemy->map->darkness > 0
2620  && !monster_stand_in_light(enemy)
2621  && (!QUERY_FLAG(looker, FLAG_SEE_IN_DARK) || !is_true_undead(looker) || !QUERY_FLAG(looker, FLAG_XRAYS)))
2622  return 0;
2623 
2624  return 1;
2625 }
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Sends message to player(s).
Definition: main.c:315
Error, serious thing.
Definition: logger.h:11
char path[HUGE_BUF]
Filename of the map.
Definition: map.h:365
int get_dialog_message(object *op, const char *text, struct_dialog_message **message, struct_dialog_reply **reply)
Tries to find a message matching the said text.
Definition: dialog.c:209
int8_t Int
Definition: living.h:35
#define NUM_BODY_LOCATIONS
Number of body locations.
Definition: object.h:13
One player.
Definition: player.h:92
#define FLAG_SEE_IN_DARK
if set ob not effected by darkness
Definition: define.h:338
int apply_manual(object *op, object *tmp, int aflag)
Main apply handler.
Definition: apply.c:510
static int monster_use_scroll(object *head, object *part, object *pl, int dir)
Tries to make a (part of a) monster apply a spell.
Definition: monster.c:1180
#define FLAG_IS_FLOOR
Can&#39;t see what&#39;s underneath this object.
Definition: define.h:303
int npc_msg_count
How many NPCs reacted to the text being said.
Definition: dialog.h:59
#define FLAG_UNPAID
Object hasn&#39;t been paid for yet.
Definition: define.h:236
int8_t ac
Armour Class, how hard to hit, the lower the better.
Definition: living.h:37
static int monster_check_good_armour(object *who, object *item)
Checks if using armor &#39;item&#39; would be better for &#39;who&#39;.
Definition: monster.c:1527
#define SP_BOLT
Definition: spells.h:78
Spell-related defines: spellpath, subtypes, ...
See Ring.
Definition: object.h:185
#define RANDO
The monster will go in a random direction until it is stopped by an obstacle, then it chooses another...
Definition: define.h:550
This is used by get_rangevector to determine where the other creature is.
Definition: map.h:380
void monster_npc_say(object *npc, const char *cp)
Simple function to have some NPC say something.
Definition: monster.c:2301
#define FLAG_SLEEP
NPC is sleeping.
Definition: define.h:308
const char * race
Human, goblin, dragon, etc.
Definition: object.h:318
uint16_t attack_movement
What kind of attack movement.
Definition: object.h:391
#define MAX_LIGHT_RADII
Max radii for &#39;light&#39; object, really large values allow objects that can slow down the game...
Definition: define.h:466
#define FLAG_USE_SCROLL
(Monster) can read scroll
Definition: define.h:292
static int monster_hitrun_att(int dir, object *ob, object *enemy)
Return the next direction the monster should move for a specific movement type.
Definition: monster.c:1896
static int monster_should_cast_spell(object *spell_ob)
Checks if a monster should cast a spell.
Definition: monster.c:1016
tag_t attacked_by_count
The tag of attacker, so we can be sure.
Definition: object.h:383
#define SET_FLAG(xyz, p)
Definition: define.h:223
sstring add_refcount(sstring str)
This will increase the refcount of the string str.
Definition: shstr.c:210
#define SP_CONE
Definition: spells.h:81
int makes_invisible_to(object *pl, object *mon)
This checks to see if &#39;pl&#39; is invisible to &#39;mon&#39;.
Definition: spell_effect.c:740
object * object_find_by_type_applied(const object *who, int type)
Find applied object in inventory.
Definition: object.c:3974
#define FABS(x)
Decstations have trouble with fabs()...
Definition: define.h:22
See Scroll.
Definition: object.h:221
object * part
Part we found.
Definition: map.h:385
void pets_follow_owner(object *ob, object *owner)
A pet is trying to follow its owner.
Definition: pets.c:293
uint16_t animation_id
An index into the animation array.
Definition: object.h:416
#define NDI_WHITE
Definition: newclient.h:222
void monster_do_living(object *op)
For a monster, regenerate hp and sp, potentially clear scared status.
Definition: monster.c:564
#define FLAG_USE_ARMOUR
(Monster) can wear armour/shield/helmet
Definition: define.h:296
#define FLAG_STAND_STILL
NPC will not (ever) move.
Definition: define.h:309
int message_type
A reply_type value for message.
Definition: dialog.h:55
void drain_wand_charge(object *wand)
Drains a charge from a wand.
Definition: spell_util.c:829
See Food.
Definition: object.h:112
#define MSG_TYPE_DIALOG_MAGIC_EAR
Magic ear.
Definition: newclient.h:467
See Projectile.
Definition: object.h:117
#define FLAG_FRIENDLY
Will help players.
Definition: define.h:246
static int monster_get_weapon_quality(const object *item)
Returns the "quality" value of a weapon of a monster.
Definition: monster.c:1454
sstring stringbuffer_finish_shared(StringBuffer *sb)
Deallocate the string buffer instance and return the string as a shared string.
Definition: stringbuffer.c:85
#define PACEV2
The monster will pace as above but the length of the pace area is longer and the monster stops before...
Definition: define.h:559
sstring message
If not NULL, what the player will be displayed as said.
Definition: dialog.h:54
void fatal(enum fatal_error err)
fatal() is meant to be called whenever a fatal signal is intercepted.
Definition: utils.c:596
object * mon
Definition: comet_perf.c:74
int8_t range
Range of the spell.
Definition: object.h:405
#define SP_MOVING_BALL
Definition: spells.h:109
struct obj * who
Player saying something.
Definition: dialog.h:52
void pets_move(object *ob)
Handles a pet&#39;s movement.
Definition: pets.c:329
#define SPELL_GRACE
Definition: spells.h:59
StringBuffer * stringbuffer_new(void)
Create a new string buffer.
Definition: stringbuffer.c:57
void get_search_arr(int *search_arr)
New function to make monster searching more efficient, and effective! This basically returns a random...
Definition: object.c:3501
int32_t last_heal
Last healed.
Definition: object.h:357
#define FLAG_READY_RANGE
(Monster) has a range attack readied...
Definition: define.h:299
void free_string(sstring str)
This will reduce the refcount, and if it has reached 0, str will be freed.
Definition: shstr.c:280
static const char * get_reply_text_other(reply_type rt)
Return the verb for the player&#39;s dialog type seen from others (third person).
Definition: monster.c:2144
int monster_compute_path(object *source, object *target, int default_dir)
Computes a path from source to target.
Definition: monster.c:393
mapstruct * get_map_from_coord(mapstruct *m, int16_t *x, int16_t *y)
This is basically the same as out_of_map above(), but instead we return NULL if no map is valid (coor...
Definition: map.c:2368
See Spellbook.
Definition: object.h:203
const char * object_get_value(const object *op, const char *const key)
Get an extra value by key.
Definition: object.c:4246
See Money.
Definition: object.h:137
sstring replies[MAX_REPLIES]
Description for replies_words.
Definition: dialog.h:58
static object * monster_find_enemy(object *npc, rv_vector *rv)
Tries to find an enmy for npc.
Definition: monster.c:209
object clone
An object from which to do object_copy()
Definition: object.h:470
int16_t invisible
How much longer the object will be invis.
Definition: object.h:360
short freearr_x[SIZEOFFREE]
X offset when searching around a spot.
Definition: object.c:65
#define MSG_TYPE_DIALOG
NPCs, magic mouths, and altars.
Definition: newclient.h:375
int16_t SP_level_spellpoint_cost(object *caster, object *spell, int flags)
Scales the spellpoint cost of a spell by it&#39;s increased effectiveness.
Definition: spell_util.c:277
See Weapon.
Definition: object.h:119
int isqrt(int n)
Compute the square root.
Definition: utils.c:585
#define MIN_MON_RADIUS
Minimum monster detection radius.
Definition: monster.c:55
#define IS_WEAPON(op)
Definition: define.h:162
#define FLAG_CONFUSED
Will also be unable to cast spells.
Definition: define.h:312
int32_t last_sp
As last_heal, but for spell points.
Definition: object.h:358
#define FLAG_STEALTH
Will wake monsters with less range.
Definition: define.h:313
#define FLAG_RANDOM_MOVE
NPC will move randomly.
Definition: define.h:310
#define MAX_EXPLORE
Maximum map size to consider when finding a path in monster_compute_path().
Definition: monster.c:375
uint8_t subtype
Subtype of object.
Definition: object.h:339
sstring replies_words[MAX_REPLIES]
Available reply words.
Definition: dialog.h:57
See Rod.
Definition: object.h:109
#define FLAG_USE_WEAPON
(Monster) can wield weapons
Definition: define.h:297
uint8_t hide
The object is hidden, not invisible.
Definition: object.h:387
static int monster_cast_spell(object *head, object *part, object *pl, int dir)
Tries to make a (part of a) monster cast a spell.
Definition: monster.c:1094
char * message
What the player will actually say for this reply.
Definition: dialog.h:20
#define OUT_OF_REAL_MAP(M, X, Y)
Checks if a square is out of the map.
Definition: map.h:217
int apply_can_apply_object(const object *who, const object *op)
Checks to see if &#39;who&#39; can apply object &#39;op&#39;.
Definition: apply.c:942
#define FLAG_NO_ATTACK
monster don&#39;t attack
Definition: define.h:363
int8_t get_attr_value(const living *stats, int attr)
Gets the value of a stat.
Definition: living.c:313
void remove_friendly_object(object *op)
Removes the specified object from the linked list of friendly objects.
Definition: friend.c:56
#define MSG_TYPE_DIALOG_NPC
A message from the npc.
Definition: newclient.h:465
#define MAX(x, y)
Definition: compat.h:20
method_ret ob_apply(object *op, object *applier, int aflags)
Applies an object.
Definition: ob_methods.c:42
#define CIRCLE1
If the upper four bits of move_type / attack_movement are set to this number, the monster will move i...
Definition: define.h:532
int16_t sp
Spell points.
Definition: living.h:41
uint32_t get_weight_limit(int stat)
Definition: living.c:2273
int player_can_view(object *pl, object *op)
Check the player los field for viewability of the object op.
Definition: player.c:4146
int path_to_player(object *mon, object *pl, unsigned mindiff)
Returns the direction to the player, if valid.
Definition: player.c:629
Global type definitions and header inclusions.
#define PETMOVE
If the upper four bits of attack_movement are set to this number, the monster follows a player until ...
Definition: define.h:517
#define AP_APPLY
Item is to be applied.
Definition: define.h:610
uint32_t hidden
If True, player (DM) is hidden from view.
Definition: player.h:132
struct obj * enemy
Monster/player to follow even if not closest.
Definition: object.h:381
#define FLAG_USE_RING
(Monster) can use rings, boots, gauntlets, etc
Definition: define.h:298
static int monster_talk_to_npc(object *npc, talk_info *info)
Give an object the chance to handle something being said.
Definition: monster.c:2318
int distance_y
Y delta.
Definition: map.h:383
int absdir(int d)
Computes an absolute direction.
Definition: object.c:3637
#define HITRUN
Run to then hit player then run away cyclicly.
Definition: define.h:509
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Sends message to player(s).
Definition: main.c:310
See Wand & Staff.
Definition: object.h:220
int plugin_event_say(object *npc, talk_info *talk)
Definition: plugins.c:375
static int monster_wait_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv)
Return the next direction the monster should move for a specific movement type.
Definition: monster.c:1914
int16_t maxsp
Max spell points.
Definition: living.h:42
#define MIN(x, y)
Definition: compat.h:17
int8_t Con
Definition: living.h:35
#define FLAG_REMOVED
Object is not in any map or invenory.
Definition: define.h:232
int16_t hp
Hit Points.
Definition: living.h:39
short freearr_y[SIZEOFFREE]
Y offset when searching around a spot.
Definition: object.c:71
static void monster_pace2_moveh(object *ob)
Move the monster in a specified movement pattern.
Definition: monster.c:2035
One reply a NPC can expect.
Definition: dialog.h:18
See Magic Ear.
Definition: object.h:131
static int monster_dist_att(int dir, object *enemy, object *part, rv_vector *rv)
Return the direction the monster should move or look to attack an enemy.
Definition: monster.c:1861
#define NDI_NAVY
Definition: newclient.h:223
uint16_t height
Width and height of map.
Definition: map.h:347
#define FLAG_SEE_INVISIBLE
Will see invisible player.
Definition: define.h:253
Throwing.
Definition: skills.h:44
static void monster_circ1_move(object *ob)
Move the monster in a specified movement pattern.
Definition: monster.c:1968
#define FLAG_READY_SKILL
(Monster or Player) has a skill readied
Definition: define.h:334
struct obj * chosen_skill
The skill chosen to use.
Definition: object.h:386
int object_set_value(object *op, const char *key, const char *value, int add_key)
Updates the key in op to value.
Definition: object.c:4375
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
Definition: object.c:1368
int16_t y
Position in the map for this object.
Definition: object.h:326
#define RUNATT
Run but attack if player catches up to object.
Definition: define.h:508
int16_t maxhp
Max hit points.
Definition: living.h:40
int dirdiff(int dir1, int dir2)
Computes a direction difference.
Definition: object.c:3655
reply_type
Various kind of messages a player or NPC can say.
Definition: dialog.h:9
#define HI4
Definition: define.h:567
See Shooting Weapon.
Definition: object.h:118
#define SP_BULLET
Definition: spells.h:79
int replies_count
How many items in replies_words and replies.
Definition: dialog.h:56
Asking a question.
Definition: dialog.h:12
#define FLAG_ALIVE
Object can fight (or be fought)
Definition: define.h:230
void do_hidden_move(object *op)
For hidden creatures - a chance of becoming &#39;unhidden&#39; every time they move - as we subtract off &#39;inv...
Definition: player.c:4037
#define AP_IGNORE_CURSE
Apply/unapply regardless of cursed/damned status.
Definition: define.h:617
int monster_can_see_enemy(object *op, object *enemy)
Assuming no walls/barriers, lets check to see if its possible to see an enemy.
Definition: monster.c:2569
static void monster_rand_move(object *ob)
Move the monster in a specified movement pattern.
Definition: monster.c:2050
int get_randomized_dir(int dir)
Returns a random direction (1..8) similar to a given direction.
Definition: utils.c:438
static int monster_get_armour_quality(const object *item)
Returns the "quality" value of an armour of a monster.
Definition: monster.c:1506
#define MAX_REPLIES
How many NPC replies maximum to tell the player.
Definition: dialog.h:44
int object_can_pick(const object *who, const object *item)
Finds out if an object can be picked up.
Definition: object.c:3793
object * object_insert_in_ob(object *op, object *where)
This function inserts the object op in the linked list inside the object environment.
Definition: object.c:2690
signed short int16_t
Definition: win32.h:160
See Treasure.
Definition: object.h:110
#define FLAG_READY_SCROLL
monster has scroll in inv and can use it
Definition: define.h:325
int32_t weight
Attributes of the object.
Definition: object.h:365
#define FLAG_CAN_USE_SKILL
The monster can use skills.
Definition: define.h:322
#define MOVE_FLY_LOW
Low flying object.
Definition: define.h:408
Structure used to build up dialog information when a player says something.
Definition: dialog.h:51
uint32_t tmp_invis
Will invis go away when we attack?
Definition: player.h:125
void drain_rod_charge(object *rod)
Drain charges from a rod.
Definition: spell_util.c:819
#define SP_BOMB
Definition: spells.h:82
int8_t Wis
Definition: living.h:35
const char * text
What the player actually said.
Definition: dialog.h:53
#define FLAG_UNAGGRESSIVE
Monster doesn&#39;t attack players.
Definition: define.h:272
#define FLAG_USE_SHIELD
Can this creature use a shield?
Definition: define.h:237
static StringBuffer * monster_format_say(const object *npc, const char *message)
Format an NPC message.
Definition: monster.c:2111
#define FLAG_USE_RANGE
(Monster) can apply and use range items
Definition: define.h:293
struct mapdef * map
Pointer to the map in which this object is present.
Definition: object.h:297
#define snprintf
Definition: win32.h:46
int ob_blocked(const object *ob, mapstruct *m, int16_t x, int16_t y)
Returns true if the given object can&#39;t fit in the given spot.
Definition: map.c:489
void monster_do_say(const mapstruct *map, const char *message)
Output a NPC message on a map.
Definition: monster.c:2100
static int monster_check_good_weapon(object *who, object *item)
Checks if using weapon &#39;item&#39; would be better for &#39;who&#39;.
Definition: monster.c:1480
object * get_nearest_player(object *mon)
Finds the nearest visible player for some object.
Definition: player.c:520
int pets_should_arena_attack(object *pet, object *owner, object *target)
Determines if checks so pets don&#39;t attack players or other pets should be overruled by the arena petm...
Definition: pets.c:1152
#define WILL_APPLY_TREASURE
Open chests.
Definition: object.h:53
#define FOR_INV_FINISH()
Finishes FOR_INV_PREPARE().
Definition: define.h:712
Reply to something.
Definition: dialog.h:11
int16_t dam
How much damage this object does when hitting.
Definition: living.h:45
Definition: object.h:145
int32_t carrying
How much weight this object contains.
Definition: object.h:367
#define PACEH
The monster will pace back and forth until attacked.
Definition: define.h:540
void monster_check_apply_all(object *monster)
Calls monster_check_apply() for all inventory objects.
Definition: monster.c:1821
object * monster_find_nearest_living_creature(object *npc)
Returns the nearest living creature (monster or generator).
Definition: monster.c:152
const char * name
The name of the object, obviously...
Definition: object.h:311
static int monster_can_hit(object *ob1, object *ob2, rv_vector *rv)
Checks if monster can hit in hand-to-hand combat.
Definition: monster.c:973
static int monster_wait_att2(int dir, rv_vector *rv)
Return the next direction the monster should move for a specific movement type.
Definition: monster.c:1958
static void monster_pace2_movev(object *ob)
Move the monster in a specified movement pattern.
Definition: monster.c:2020
char * reply
Reply expected from the player.
Definition: dialog.h:19
int distance_x
X delta.
Definition: map.h:382
#define MSG_TYPE_COMMUNICATION_SAY
Player says something.
Definition: newclient.h:618
void ext_info_map_except(int color, const mapstruct *map, const object *op, uint8_t type, uint8_t subtype, const char *str1)
Writes to everyone on the map except *op.
Definition: info.c:185
#define SP_SMITE
Definition: spells.h:84
int is_true_undead(object *op)
Is the object a true undead?
Definition: player.c:3973
#define MSG_TYPE_COMMUNICATION
Communication between players.
Definition: newclient.h:386
object * monster_find_throw_ob(object *op)
Find an item for the monster to throw.
Definition: monster.c:2347
void monster_communicate(object *op, const char *txt)
This function looks for an object or creature that is listening to said text.
Definition: monster.c:2182
#define GET_MAP_LIGHT(M, X, Y)
Gets map light.
Definition: map.h:165
#define FLAG_PARALYZED
Monster or player is paralyzed.
Definition: define.h:380
int8_t direction
Means the object is moving that way.
Definition: object.h:334
#define AP_NOPRINT
Don&#39;t print messages - caller will do that may be some that still print.
Definition: define.h:621
void monster_check_earthwalls(object *op, mapstruct *m, int x, int y)
Living creature attempts to hit an earthwall.
Definition: monster.c:2070
static object * monster_choose_random_spell(object *monster)
Selects a spell to cast for a monster.
Definition: monster.c:1056
#define SIZEOFFREE
Definition: define.h:154
#define P_OUT_OF_MAP
This space is outside the map.
Definition: map.h:251
Number of statistics.
Definition: living.h:18
#define GET_MAP_MOVE_BLOCK(M, X, Y)
Gets the blocking state of a square.
Definition: map.h:192
int do_skill(object *op, object *part, object *skill, int dir, const char *string)
Main skills use function-similar in scope to cast_spell().
Definition: skill_util.c:428
static int monster_disthit_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv)
Return the next direction the monster should move for a specific movement type.
Definition: monster.c:1939
struct pl * contr
Pointer to the player which control this object.
Definition: object.h:276
#define FLAG_SCARED
Monster is scared (mb player in future)
Definition: define.h:271
uint8_t darkness
Indicates level of darkness of map.
Definition: map.h:346
#define SP_INVISIBLE
Definition: spells.h:93
#define MSG_TYPE_SKILL_FAILURE
Failure in using skill.
Definition: newclient.h:585
static int monster_move_randomly(object *op)
Handles random object movement.
Definition: monster.c:342
#define FLAG_ONLY_ATTACK
NPC will evaporate if there is no enemy.
Definition: define.h:311
#define FLAG_XRAYS
X-ray vision.
Definition: define.h:301
void use_trigger(object *op)
Toggles the state of specified button.
Definition: button.c:259
#define ATNR_PHYSICAL
Definition: attack.h:49
static void monster_pace_moveh(object *ob)
Move the monster in a specified movement pattern.
Definition: monster.c:2007
object * object_find_by_type_and_race(const object *who, int type, const char *race)
Find object in inventory by type and race.
Definition: object.c:4024
#define AT_PHYSICAL
Definition: attack.h:76
float speed
The overall speed of this object.
Definition: object.h:328
See Spell.
Definition: object.h:214
int on_same_map(const object *op1, const object *op2)
Checks whether 2 objects are on the same map or not.
Definition: map.c:2638
#define CAN_APPLY_NOT_MASK
Definition: define.h:667
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
#define CLEAR_FLAG(xyz, p)
Definition: define.h:224
#define HEAD(op)
Returns the head part of an object.
Definition: object.h:594
See Handle Trigger.
Definition: object.h:129
#define FLAG_WIZ
Object has special privilegies.
Definition: define.h:231
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
#define SP_SWARM
Definition: spells.h:110
#define IS_SHIELD(op)
Definition: define.h:169
See Door.
Definition: object.h:126
Many many details.
Definition: logger.h:14
int fire_bow(object *op, object *arrow, int dir, int wc_mod, int16_t sx, int16_t sy)
Creature (monster or player) fires a bow.
Definition: player.c:2173
#define FLAG_CAST_SPELL
(Monster) can learn and cast spells
Definition: define.h:291
int16_t x
Definition: object.h:326
#define FLAG_BERSERK
monster will attack closest living object
Definition: define.h:359
void skill_attack(object *tmp, object *pl, int dir, const char *string, object *skill)
Core routine for use when we attack using a skills system.
Definition: skill_util.c:1239
#define WAITATT
Wait for player to approach then hit, move if hit.
Definition: define.h:510
static int monster_use_range(object *head, object *part, object *pl, int dir)
Monster will use a ranged attack (ROD, WAND, ...).
Definition: monster.c:1321
#define FLAG_RUN_AWAY
Object runs away from nearest player \ but can still attack at a distance.
Definition: define.h:280
Skill-related defines, including subtypes.
Basic sentence.
Definition: dialog.h:10
int8_t wc
Weapon Class, how skilled, the lower the better.
Definition: living.h:36
unsigned short uint16_t
Definition: win32.h:163
#define ALLRUN
Always run, never attack good for sim.
Definition: define.h:512
#define FLAG_IS_THROWN
Object is designed to be thrown.
Definition: define.h:249
#define FOR_MAP_FINISH()
Finishes FOR_MAP_PREPARE().
Definition: define.h:765
int8_t Str
Definition: living.h:35
void animate_object(object *op, int dir)
Updates the face-variable of an object.
Definition: anim.c:212
int16_t resist[NROFATTACKS]
Resistance adjustments for attacks.
Definition: object.h:341
int has_carried_lights(const object *op)
Checks if op has a light source.
Definition: los.c:311
const char * sstring
Strings that should be manipulated through add_string() and free_string().
Definition: global.h:40
void monster_check_doors(object *op, mapstruct *m, int x, int y)
Living creature attempts to open a door.
Definition: monster.c:2086
unsigned int uint32_t
Definition: win32.h:162
See Player.
Definition: object.h:107
object * object_find_by_type_subtype(const object *who, int type, int subtype)
Find object in inventory.
Definition: object.c:4195
#define RUSH
Rush toward player blindly, similiar to dumb monster.
Definition: define.h:511
int8_t body_info[NUM_BODY_LOCATIONS]
Body info as loaded from the file.
Definition: object.h:372
#define WAIT2
Monster does not try to move towards player if far.
Definition: define.h:514
#define FLAG_GENERATOR
Will generate type ob->stats.food.
Definition: define.h:248
struct obj * spellitem
Spell ability monster is choosing to use.
Definition: object.h:394
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
object_split(ob,nr) splits up ob into two parts.
Definition: object.c:2463
#define FLAG_BLIND
If set, object cannot see (visually)
Definition: define.h:337
#define WILL_APPLY_HANDLE
Apply handles and triggers.
Definition: object.h:52
#define FLAG_NEUTRAL
monster is from type neutral
Definition: define.h:362
static const char * get_reply_text_own(reply_type rt)
Return the verb for the player&#39;s dialog type.
Definition: monster.c:2126
#define RANDOM()
Definition: define.h:679
#define MAX_NPC
How many NPCs maximum will reply to the player.
Definition: dialog.h:46
int16_t grace
Grace.
Definition: living.h:43
Also see SKILL_TOOL (74) below.
Definition: object.h:143
static int monster_use_bow(object *head, object *part, object *pl, int dir)
Tries to make a (part of a) monster fire a bow.
Definition: monster.c:1397
static void monster_check_apply(object *mon, object *item)
Called after an item is inserted in a monster.
Definition: monster.c:1562
tag_t count
Unique object number for this object.
Definition: object.h:299
living stats
Str, Con, Dex, etc.
Definition: object.h:368
struct archt * arch
Pointer to archetype.
Definition: object.h:412
Only for debugging purposes.
Definition: logger.h:13
Hiding.
Definition: skills.h:21
#define RANDO2
Constantly move in a different random direction.
Definition: define.h:555
uint8_t will_apply
See crossfire.doc and What monsters apply.
Definition: object.h:392
static int monster_move_no_enemy(object *op)
Makes a monster without any enemy move.
Definition: monster.c:627
One message a NPC can react to.
Definition: dialog.h:28
uint16_t width
Definition: map.h:347
unsigned int distance
Distance, in squares.
Definition: map.h:381
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:338
void object_set_enemy(object *op, object *enemy)
Sets the enemy of an object.
Definition: object.c:679
int direction
General direction to the targer.
Definition: map.h:384
See Handle.
Definition: object.h:208
static int monster_use_skill(object *head, object *part, object *pl, int dir)
A monster attempts using a skill.
Definition: monster.c:1264
#define SP_MAGIC_MISSILE
Definition: spells.h:85
void monster_npc_call_help(object *op)
A monster calls for help against its enemy.
Definition: monster.c:1831
#define FLAG_APPLIED
Object is ready for use by living.
Definition: define.h:235
#define NROFATTACKS
Definition: attack.h:17
int move_object(object *op, int dir)
Try to move op in the direction "dir".
Definition: move.c:39
signed int int32_t
Definition: win32.h:159
#define SIZEOFFREE2
Definition: define.h:153
#define SP_SUMMON_MONSTER
Definition: spells.h:101
struct struct_dialog_reply * replies
Replies this message has.
Definition: dialog.h:31
char * message
What the NPC will say.
Definition: dialog.h:30
static int monster_run_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv)
Return the next direction the monster should move for a specific movement type.
Definition: monster.c:1880
object * monster_check_enemy(object *npc, rv_vector *rv)
Checks npc->enemy and returns that enemy if still valid, NULL otherwise.
Definition: monster.c:71
sstring add_string(const char *str)
This will add &#39;str&#39; to the hash table.
Definition: shstr.c:124
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Append a formatted string to a string buffer instance.
Definition: stringbuffer.c:104
#define MIN_ACTIVE_SPEED
Cut off point of when an object is put on the active list or not.
Definition: define.h:674
#define DISTATT
Move toward a player if far, but maintain some space, attack from a distance - good for missile users...
Definition: define.h:505
int8_t glow_radius
indicates the glow radius of the object
Definition: object.h:364
int monster_move(object *op)
Main monster processing routine.
Definition: monster.c:699
#define FLAG_MONSTER
Will attack players.
Definition: define.h:245
#define MSG_TYPE_SKILL
Messages related to skill use.
Definition: newclient.h:383
static void monster_check_pickup(object *monster)
Checks for items that monster can pick up.
Definition: monster.c:1679
int8_t Pow
Definition: living.h:35
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
This rolls up wall, blocks_magic, blocks_view, etc, all into one function that just returns a P_...
Definition: map.c:302
struct obj * inv
Pointer to the first object in the inventory.
Definition: object.h:290
#define NDI_UNIQUE
Print immediately, don&#39;t buffer.
Definition: newclient.h:245
#define FLAG_READY_BOW
not implemented yet
Definition: define.h:300
sstring npc_msgs[MAX_NPC]
What the NPCs will say.
Definition: dialog.h:60
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.c:51
int monster_stand_in_light(object *op)
Determine if op stands in a lighted square.
Definition: monster.c:2526
static void monster_pace_movev(object *ob)
Move the monster in a specified movement pattern.
Definition: monster.c:1994
void make_visible(object *op)
Makes an object visible again.
Definition: player.c:3953
#define SP_MAGIC_WALL
Definition: spells.h:89
uint8_t pick_up
See crossfire.doc.
Definition: object.h:361
#define PACEH2
The monster will pace as above but the length of the pace area is longer and the monster stops before...
Definition: define.h:543
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Constructs a loop iterating over all objects of a map tile.
Definition: define.h:758
uint8_t run_away
Monster runs away if it&#39;s hp goes below this percentage.
Definition: object.h:384
#define IS_ARMOR(op)
Definition: define.h:165
static void monster_apply_below(object *monster)
If a monster who&#39;s eager to apply things encounters something apply-able, then make him apply it...
Definition: monster.c:1798
int can_see_monsterP(mapstruct *m, int x, int y, int dir)
Recursive routine to see if we can find a path to a certain point.
Definition: object.c:3745
#define PACEV
The monster will pace back and forth until attacked.
Definition: define.h:556
#define WILL_APPLY_FOOD
Eat food (not drinks).
Definition: object.h:56
struct struct_dialog_reply * next
Next reply, NULL for last.
Definition: dialog.h:22
A buffer that will be expanded as content is added to it.
Definition: stringbuffer.c:25
void query_name(const object *op, char *buf, size_t size)
Describes an item.
Definition: item.c:625
#define SPELL_MANA
Definition: spells.h:58
#define FOR_BELOW_PREPARE(op_, it_)
Constructs a loop iterating over all objects below an object.
Definition: define.h:739
static int monster_can_pick(object *monster, object *item)
Check if the monster can and is interested in picking up an item.
Definition: monster.c:1717
#define CIRCLE2
Same as CIRCLE1 but a larger circle is used.
Definition: define.h:539
object * find_skill_by_number(object *who, int skillno)
This returns the skill pointer of the given name (the one that accumulates exp, has the level...
Definition: main.c:351
reply_type type
Type of message.
Definition: dialog.h:21
This is a game-map.
Definition: map.h:325
#define P_IS_ALIVE
Something alive is on this space.
Definition: map.h:237
object * pets_get_enemy(object *pet, rv_vector *rv)
Given that &#39;pet&#39; is a friendly object, this function returns a monster the pet should attack...
Definition: pets.c:57
const New_Face * face
Face with colors.
Definition: object.h:332
See Jewel.
Definition: object.h:167
int hit_player(object *op, int dam, object *hitter, uint32_t type, int full_hit)
Object is attacked by something.
Definition: attack.c:1872
int get_rangevector(object *op1, const object *op2, rv_vector *retval, int flags)
From map.c This is used by get_player to determine where the other creature is.
Definition: map.c:2527
void ext_info_map(int color, const mapstruct *map, uint8_t type, uint8_t subtype, const char *str1)
Writes to everyone on the specified map.
Definition: main.c:325
int32_t move_status
What stage in attack mode.
Definition: object.h:390
int16_t level
Level of creature or object.
Definition: object.h:351
int8_t facing
Object is oriented/facing that way.
Definition: object.h:335
#define SP_SUMMON_GOLEM
Definition: spells.h:86
#define SP_EXPLOSION
Definition: spells.h:80
static int monster_do_talk_npc(object *npc, talk_info *info)
Checks the messages of a NPC for a matching text.
Definition: monster.c:2256
struct obj * more
Pointer to the rest of a large body of objects.
Definition: object.h:295
static void monster_circ2_move(object *ob)
Move the monster in a specified movement pattern.
Definition: monster.c:1981
object * object_get_owner(object *op)
Returns the object which this object marks as being the owner.
Definition: object.c:559
int8_t magic
Any magical bonuses to this item.
Definition: object.h:348
#define FLAG_USE_BOW
(Monster) can apply and fire bows
Definition: define.h:294
char * stringbuffer_finish(StringBuffer *sb)
Deallocate the string buffer instance and return the string.
Definition: stringbuffer.c:76
#define FOR_BELOW_FINISH()
Finishes FOR_BELOW_PREPARE().
Definition: define.h:746
int monster_can_detect_enemy(object *op, object *enemy, rv_vector *rv)
Determine if we can &#39;detect&#39; the enemy.
Definition: monster.c:2386
#define FOR_INV_PREPARE(op_, it_)
Constructs a loop iterating over the inventory of an object.
Definition: define.h:705
int cast_spell(object *op, object *caster, int dir, object *spell_ob, char *stringarg)
Main dispatch when someone casts a spell.
Definition: spell_util.c:1471
void object_remove(object *op)
This function removes the object op from the linked list of objects which it is currently tied to...
Definition: object.c:1654
#define DISTHIT
Attack from a distance if hit as recommended by Frank.
Definition: define.h:513
#define MAX_KNOWN_SPELLS
Maximum number of spells to consider when choosing a spell for a monster.
Definition: monster.c:1039
struct obj * attacked_by
This object start to attack us! only player & monster.
Definition: object.h:382
#define FLAG_FREED
Object is in the list of free objects.
Definition: define.h:233
static int monster_check_wakeup(object *op, object *enemy, rv_vector *rv)
Sees if this monster should wake up.
Definition: monster.c:296
#define LO4
bitmasks for upper and lower 4 bits from 8 bit fields
Definition: define.h:566