Crossfire Server, Branches 1.12  R18729
monster.c
Go to the documentation of this file.
1 /*
2  * static char *rcsid_monster_c =
3  * "$Id: monster.c 11644 2009-04-15 06:24:55Z mwedel $";
4  */
5 
6 /*
7  CrossFire, A Multiplayer game for X-windows
8 
9  Copyright (C) 2002-2007 Mark Wedel & Crossfire Development Team
10  Copyright (C) 1992 Frank Tore Johansen
11 
12  This program is free software; you can redistribute it and/or modify
13  it under the terms of the GNU General Public License as published by
14  the Free Software Foundation; either version 2 of the License, or
15  (at your option) any later version.
16 
17  This program is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  GNU General Public License for more details.
21 
22  You should have received a copy of the GNU General Public License
23  along with this program; if not, write to the Free Software
24  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 
26  The authors can be reached via e-mail at crossfire-devel@real-time.com
27 */
28 
35 #include <assert.h>
36 #include <global.h>
37 #ifndef __CEXTRACT__
38 #include <sproto.h>
39 #include <spells.h>
40 #include <skills.h>
41 #endif
42 
43 static int can_hit(object *ob1, object *ob2, rv_vector *rv);
44 static int monster_cast_spell(object *head, object *part, object *pl, int dir, rv_vector *rv);
45 static int monster_use_scroll(object *head, object *part, object *pl, int dir, rv_vector *rv);
46 static int monster_use_skill(object *head, object *part, object *pl, int dir);
47 static int monster_use_range(object *head, object *part, object *pl, int dir);
48 static int monster_use_bow(object *head, object *part, object *pl, int dir);
49 static void monster_check_pickup(object *monster);
50 static int monster_can_pick(object *monster, object *item);
51 static void monster_apply_below(object *monster);
52 static int dist_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv);
53 static int run_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv);
54 static int hitrun_att(int dir, object *ob, object *enemy);
55 static int wait_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv);
56 static int disthit_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv);
57 static int wait_att2(int dir, object *ob, object *enemy, object *part, rv_vector *rv);
58 static void circ1_move(object *ob);
59 static void circ2_move(object *ob);
60 static void pace_movev(object *ob);
61 static void pace_moveh(object *ob);
62 static void pace2_movev(object *ob);
63 static void pace2_moveh(object *ob);
64 static void rand_move(object *ob);
65 static int talk_to_npc(object *op, object *npc, const char *txt, int *talked);
66 
67 #define MIN_MON_RADIUS 3 /* minimum monster detection radius */
68 
83 object *check_enemy(object *npc, rv_vector *rv) {
84  /* if this is pet, let him attack the same enemy as his owner
85  * TODO: when there is no ower enemy, try to find a target,
86  * which CAN attack the owner. */
87  if ((npc->attack_movement&HI4) == PETMOVE) {
88  if (npc->owner == NULL)
89  npc->enemy = NULL;
90  else if (npc->enemy == NULL)
91  npc->enemy = npc->owner->enemy;
92  }
93 
94  /* periodically, a monster mayu change its target. Also, if the object
95  * has been destroyed, etc, clear the enemy.
96  * TODO: this should be changed, because it invokes to attack forced or
97  * attacked monsters to leave the attacker alone, before it is destroyed
98  */
99  /* i had removed the random target leave, this invokes problems with friendly
100  * objects, getting attacked and defending herself - they don't try to attack
101  * again then but perhaps get attack on and on
102  * If we include a aggravated flag in , we can handle evil vs evil and good vs good
103  * too. */
104 
105  if (npc->enemy) {
106  /* I broke these if's apart to better be able to see what
107  * the grouping checks are. Code is the same.
108  */
109  if (QUERY_FLAG(npc->enemy, FLAG_REMOVED)
110  || QUERY_FLAG(npc->enemy, FLAG_FREED)
111  || !on_same_map(npc, npc->enemy)
112  || npc == npc->enemy
113  || QUERY_FLAG(npc, FLAG_NEUTRAL)
114  || QUERY_FLAG(npc->enemy, FLAG_NEUTRAL))
115  npc->enemy = NULL;
116 
117  else if (QUERY_FLAG(npc, FLAG_FRIENDLY) && (
118  (QUERY_FLAG(npc->enemy, FLAG_FRIENDLY) && !(should_arena_attack(npc, npc->owner, npc->enemy)))
119  || ((npc->enemy->type == PLAYER) && !(should_arena_attack(npc, npc->owner, npc->enemy)))
120  || npc->enemy == npc->owner))
121  npc->enemy = NULL;
122  else if (!QUERY_FLAG(npc, FLAG_FRIENDLY)
123  && (!QUERY_FLAG(npc->enemy, FLAG_FRIENDLY) && npc->enemy->type != PLAYER))
124  npc->enemy = NULL;
125 
126  /* I've noticed that pets could sometimes get an arrow as the
127  * target enemy - this code below makes sure the enemy is something
128  * that should be attacked. My guess is that the arrow hits
129  * the creature/owner, and so the creature then takes that
130  * as the enemy to attack.
131  */
132  else if (!QUERY_FLAG(npc->enemy, FLAG_MONSTER)
133  && !QUERY_FLAG(npc->enemy, FLAG_GENERATOR)
134  && npc->enemy->type != PLAYER
135  && npc->enemy->type != GOLEM)
136  npc->enemy = NULL;
137 
138  }
139  return can_detect_enemy(npc, npc->enemy, rv) ? npc->enemy : NULL;
140 }
141 
162 object *find_nearest_living_creature(object *npc) {
163  int i, mflags;
164  sint16 nx, ny;
165  mapstruct *m;
166  object *tmp;
167  int search_arr[SIZEOFFREE];
168 
169  get_search_arr(search_arr);
170  for (i = 0; i < SIZEOFFREE; i++) {
171  /* modified to implement smart searching using search_arr
172  * guidance array to determine direction of search order
173  */
174  nx = npc->x+freearr_x[search_arr[i]];
175  ny = npc->y+freearr_y[search_arr[i]];
176  m = npc->map;
177 
178  mflags = get_map_flags(m, &m, nx, ny, &nx, &ny);
179  if (mflags&P_OUT_OF_MAP)
180  continue;
181 
182  if (mflags&P_IS_ALIVE) {
183  tmp = GET_MAP_OB(m, nx, ny);
184  while (tmp != NULL
185  && !QUERY_FLAG(tmp, FLAG_MONSTER)
186  && !QUERY_FLAG(tmp, FLAG_GENERATOR)
187  && tmp->type != PLAYER)
188  tmp = tmp->above;
189 
190  if (!tmp) {
191  LOG(llevDebug, "find_nearest_living_creature: map %s (%d,%d) has is_alive set but did not find a monster?\n", m->path, nx, ny);
192  } else {
193  if (can_see_monsterP(m, nx, ny, i))
194  return tmp;
195  }
196  } /* is something living on this space */
197  }
198  return NULL; /* nothing found */
199 }
200 
216 static object *find_enemy(object *npc, rv_vector *rv) {
217  object *attacker, *tmp = NULL;
218 
219  attacker = npc->attacked_by; /* save this for later use. This can be a attacker. */
220  npc->attacked_by = NULL; /* always clear the attacker entry */
221 
222  /* if we berserk, we don't care about others - we attack all we can find */
223  if (QUERY_FLAG(npc, FLAG_BERSERK)) {
224  tmp = find_nearest_living_creature(npc);
225  if (tmp)
226  get_rangevector(npc, tmp, rv, 0);
227  return tmp;
228  }
229 
230  /* Here is the main enemy selection.
231  * We want this: if there is an enemy, attack him until its not possible or
232  * one of both is dead.
233  * If we have no enemy and we are...
234  * a monster: try to find a player, a pet or a friendly monster
235  * a friendly: only target a monster which is targeting you first or targeting a player
236  * a neutral: fight a attacker (but there should be none), then do nothing
237  * a pet: attack player enemy or a monster
238  */
239 
240  /* pet move */
241  if ((npc->attack_movement&HI4) == PETMOVE) {
242  tmp = get_pet_enemy(npc, rv);
243  if (tmp)
244  get_rangevector(npc, tmp, rv, 0);
245  return tmp;
246  }
247 
248  /* we check our old enemy. */
249  if ((tmp = check_enemy(npc, rv)) == NULL) {
250  if (attacker) { /* if we have an attacker, check him */
251  /* we want be sure this is the right one! */
252  if (attacker->count == npc->attacked_by_count) {
253  /* TODO: thats not finished */
254  /* we don't want a fight evil vs evil or good against non evil */
255  if (QUERY_FLAG(npc, FLAG_NEUTRAL)
256  || QUERY_FLAG(attacker, FLAG_NEUTRAL) /* neutral */
257  || (QUERY_FLAG(npc, FLAG_FRIENDLY) && QUERY_FLAG(attacker, FLAG_FRIENDLY))
258  || (!QUERY_FLAG(npc, FLAG_FRIENDLY) && (!QUERY_FLAG(attacker, FLAG_FRIENDLY) && attacker->type != PLAYER)))
259  CLEAR_FLAG(npc, FLAG_SLEEP); /* skip it, but lets wakeup */
260  else if (on_same_map(npc, attacker)) { /* thats the only thing we must know... */
261  CLEAR_FLAG(npc, FLAG_SLEEP); /* well, NOW we really should wake up! */
262  npc->enemy = attacker;
263  get_rangevector(npc, attacker, rv, 0);
264  return attacker; /* yes, we face our attacker! */
265  }
266  }
267  }
268 
269  /* we have no legal enemy or attacker, so we try to target a new one */
270  if (!QUERY_FLAG(npc, FLAG_UNAGGRESSIVE)
271  && !QUERY_FLAG(npc, FLAG_FRIENDLY)
272  && !QUERY_FLAG(npc, FLAG_NEUTRAL)) {
273  npc->enemy = get_nearest_player(npc);
274  if (npc->enemy)
275  tmp = check_enemy(npc, rv);
276  }
277 
278  }
279 
280  return tmp;
281 }
282 
298 static int check_wakeup(object *op, object *enemy, rv_vector *rv) {
299  int radius = MAX(op->stats.Wis, MIN_MON_RADIUS);
300 
301  /* Trim work - if no enemy, no need to do anything below */
302  if (!enemy)
303  return 0;
304 
305  /* blinded monsters can only find nearby objects to attack */
306  if (QUERY_FLAG(op, FLAG_BLIND))
307  radius = MIN_MON_RADIUS;
308 
309  /* This covers the situation where the monster is in the dark
310  * and has an enemy. If the enemy has no carried light (or isnt
311  * glowing!) then the monster has trouble finding the enemy.
312  * Remember we already checked to see if the monster can see in
313  * the dark. */
314  else if (op->map
315  && op->map->darkness > 0
316  && enemy
317  && !enemy->invisible
318  && !stand_in_light(enemy)
320  int dark = radius/(op->map->darkness);
321 
322  radius = (dark > MIN_MON_RADIUS) ? (dark+1) : MIN_MON_RADIUS;
323  } else if (!QUERY_FLAG(op, FLAG_SLEEP))
324  return 1;
325 
326  /* enemy should already be on this map, so don't really need to check
327  * for that.
328  */
329  if (rv->distance < (QUERY_FLAG(enemy, FLAG_STEALTH) ? (radius/2)+1 : radius)) {
330  CLEAR_FLAG(op, FLAG_SLEEP);
331  return 1;
332  }
333  return 0;
334 }
335 
344 static int move_randomly(object *op) {
345  int i;
346 
347  /* Give up to 15 chances for a monster to move randomly */
348  for (i = 0; i < 15; i++) {
349  if (move_object(op, RANDOM()%8+1))
350  return 1;
351  }
352  return 0;
353 }
354 
355 #define MAX_EXPLORE 5000
356 
371 int compute_path(object *source, object *target, int default_dir) {
372  char *path;
373  int explore_x[MAX_EXPLORE], explore_y[MAX_EXPLORE];
374  int current = 0, dir, max = 1, size, x, y, check_dir;
375 
376  if (target->map != source->map)
377  return default_dir;
378 
379  /* printf("compute_path (%d, %d) => (%d, %d)\n", source->x, source->y, target->x, target->y);*/
380 
381  size = source->map->width*source->map->height;
382  path = calloc(size, sizeof(char));
383  if (path == NULL) {
385  }
386  explore_x[0] = target->x;
387  explore_y[0] = target->y;
388 
389  while (current < max) {
390  for (check_dir = 0; check_dir < 8; check_dir++) {
391  dir = absdir(default_dir+check_dir);
392  x = explore_x[current]+freearr_x[dir];
393  y = explore_y[current]+freearr_y[dir];
394 
395  if (x == source->x && y == source->y) {
396  /* LOG(llevDebug, "compute_path => %d\n", absdir(dir+4));*/
397  free(path);
398  return absdir(dir+4);
399  }
400 
401  if (OUT_OF_REAL_MAP(source->map, x, y))
402  continue;
403  if (ob_blocked(source, source->map, x, y))
404  continue;
405 
406  assert(source->map->height*x+y >= 0);
407  assert(source->map->height*x+y < size);
408 
409  if (path[source->map->height*x+y] == 0) {
410  assert(max < MAX_EXPLORE);
411  explore_x[max] = x;
412  explore_y[max] = y;
413 
414  path[source->map->height*x+y] = absdir(dir+4);
415  /* printf("explore[%d] => (%d, %d) %d\n", max, x, y, path[source->map->height*x+y]);*/
416  max++;
417  if (max == MAX_EXPLORE) {
418  free(path);
419  return default_dir;
420  }
421  }
422  }
423  current++;
424  }
425 
426  free(path);
427  return default_dir;
428 }
429 
436 static void monster_do_living(object *op) {
437  assert(QUERY_FLAG(op, FLAG_MONSTER));
438 
439  /* generate hp, if applicable */
440  if (op->stats.Con > 0 && op->stats.hp < op->stats.maxhp) {
441  /* last heal is in funny units. Dividing by speed puts
442  * the regeneration rate on a basis of time instead of
443  * #moves the monster makes. The scaling by 8 is
444  * to capture 8th's of a hp fraction regens
445  *
446  * Cast to sint32 before comparing to maxhp since otherwise an (sint16)
447  * overflow might produce monsters with negative hp.
448  */
449 
450  op->last_heal += (int)((float)(8*op->stats.Con)/FABS(op->speed));
451  op->stats.hp = MIN((sint32)op->stats.hp+op->last_heal/32, op->stats.maxhp); /* causes Con/4 hp/tick */
452  op->last_heal %= 32;
453 
454  /* So if the monster has gained enough HP that they are no longer afraid */
455  if (QUERY_FLAG(op, FLAG_RUN_AWAY)
456  && op->stats.hp >= (signed short)(((float)op->run_away/(float)100)*(float)op->stats.maxhp))
458 
459  if (op->stats.hp > op->stats.maxhp)
460  op->stats.hp = op->stats.maxhp;
461  }
462 
463  /* generate sp, if applicable */
464  if (op->stats.Pow > 0 && op->stats.sp < op->stats.maxsp) {
465  /* last_sp is in funny units. Dividing by speed puts
466  * the regeneration rate on a basis of time instead of
467  * #moves the monster makes. The scaling by 8 is
468  * to capture 8th's of a sp fraction regens
469  *
470  * Cast to sint32 before comparing to maxhp since otherwise an (sint16)
471  * overflow might produce monsters with negative sp.
472  */
473 
474  op->last_sp += (int)((float)(8*op->stats.Pow)/FABS(op->speed));
475  op->stats.sp = MIN(op->stats.sp+op->last_sp/128, op->stats.maxsp); /* causes Pow/16 sp/tick */
476  op->last_sp %= 128;
477  }
478 
479  /* this should probably get modified by many more values.
480  * (eg, creatures resistance to fear, level, etc. )
481  */
482  if (QUERY_FLAG(op, FLAG_SCARED) && !(RANDOM()%20)) {
483  CLEAR_FLAG(op, FLAG_SCARED); /* Time to regain some "guts"... */
484  }
485 }
486 
495 static int monster_move_no_enemy(object *op) {
496  assert(QUERY_FLAG(op, FLAG_MONSTER));
497 
498  if (QUERY_FLAG(op, FLAG_ONLY_ATTACK)) {
499  remove_ob(op);
500  free_object(op);
501  return 1;
502  }
503 
504  /* Probably really a bug for a creature to have both
505  * stand still and a movement type set.
506  */
507  if (!QUERY_FLAG(op, FLAG_STAND_STILL)) {
508  if (op->attack_movement&HI4) {
509  switch (op->attack_movement&HI4) {
510  case(PETMOVE):
511  pet_move(op);
512  break;
513 
514  case(CIRCLE1):
515  circ1_move(op);
516  break;
517 
518  case(CIRCLE2):
519  circ2_move(op);
520  break;
521 
522  case(PACEV):
523  pace_movev(op);
524  break;
525 
526  case(PACEH):
527  pace_moveh(op);
528  break;
529 
530  case(PACEV2):
531  pace2_movev(op);
532  break;
533 
534  case(PACEH2):
535  pace2_moveh(op);
536  break;
537 
538  case(RANDO):
539  rand_move(op);
540  break;
541 
542  case(RANDO2):
543  move_randomly(op);
544  break;
545  }
546  return 0;
547  } else if (QUERY_FLAG(op, FLAG_RANDOM_MOVE))
548  move_randomly(op);
549 
550  } /* stand still */
551 
552  return 0;
553 }
554 
566 int move_monster(object *op) {
567  int dir, diff;
568  object *owner, *enemy, *part, *oph = op;
569  rv_vector rv;
570 
571  /* Monsters not on maps don't do anything. These monsters are things
572  * Like royal guards in city dwellers inventories.
573  */
574  if (!op->map)
575  return 0;
576 
577  /* for target facing, we copy this value here for fast access */
578  if (oph->head) /* force update the head - one arch one pic */
579  oph = oph->head;
580 
581  if (QUERY_FLAG(op, FLAG_NO_ATTACK)) /* we never ever attack */
582  enemy = op->enemy = NULL;
583  else if ((enemy = find_enemy(op, &rv))) {
584  /* we have an enemy, just tell him we want him dead */
585  enemy->attacked_by = op; /* our ptr */
586  enemy->attacked_by_count = op->count; /* our tag */
587  }
588 
589  if (QUERY_FLAG(op, FLAG_SLEEP)
590  || QUERY_FLAG(op, FLAG_BLIND)
591  || ((op->map->darkness > 0) && !QUERY_FLAG(op, FLAG_SEE_IN_DARK) && !QUERY_FLAG(op, FLAG_SEE_INVISIBLE))) {
592  if (!check_wakeup(op, enemy, &rv))
593  return 0;
594  }
595 
596  /* check if monster pops out of hidden spot */
597  if (op->hide)
598  do_hidden_move(op);
599 
600  if (op->pick_up)
602 
603  if (op->will_apply)
604  monster_apply_below(op); /* Check for items to apply below */
605 
606  monster_do_living(op);
607 
608  /* If we don't have an enemy, do special movement or the like */
609  if (!enemy) {
610  return monster_move_no_enemy(op);
611  } /* no enemy */
612 
613  /* We have an enemy. Block immediately below is for pets */
614  if ((op->attack_movement&HI4) == PETMOVE && (owner = get_owner(op)) != NULL && !on_same_map(op, owner)) {
615  follow_owner(op, owner);
616  /* If the pet was unable to follow the owner, free it */
617  if (QUERY_FLAG(op, FLAG_REMOVED) && FABS(op->speed) > MIN_ACTIVE_SPEED) {
619  free_object(op);
620  return 1;
621  }
622  return 0;
623  }
624 
625  /* doppleganger code to change monster facing to that of the nearest
626  * player. Hmm. The code is here, but no monster in the current
627  * arch set uses it.
628  */
629  if ((op->race != NULL)&& strcmp(op->race, "doppleganger") == 0) {
630  op->face = enemy->face;
631  if (op->name)
632  free_string(op->name);
633  add_refcount(op->name = enemy->name);
634  }
635 
636  /* Calculate range information for closest body part - this
637  * is used for the 'skill' code, which isn't that smart when
638  * it comes to figuring it out - otherwise, giants throw boulders
639  * into themselves.
640  */
641  get_rangevector(op, enemy, &rv, 0);
642  if (op->direction != rv.direction) {
643  op->direction = rv.direction;
644  op->facing = op->direction;
645  if (op->animation_id)
646  animate_object(op, op->direction);
647  }
648 
649  /* Move the check for scared up here - if the monster was scared,
650  * we were not doing any of the logic below, so might as well save
651  * a few cpu cycles.
652  */
653  if (!QUERY_FLAG(op, FLAG_SCARED)) {
654  rv_vector rv1;
655 
656  /* now we test every part of an object .... this is a real ugly piece of code */
657  for (part = op; part != NULL; part = part->more) {
658  get_rangevector(part, enemy, &rv1, 0x1);
659  dir = rv1.direction;
660 
661  /* hm, not sure about this part - in original was a scared flag here too
662  * but that we test above... so can be old code here
663  */
664  if (QUERY_FLAG(op, FLAG_RUN_AWAY))
665  dir = absdir(dir+4);
666  if (QUERY_FLAG(op, FLAG_CONFUSED))
667  dir = absdir(dir+RANDOM()%3+RANDOM()%3-2);
668 
669  if (QUERY_FLAG(op, FLAG_CAST_SPELL) && !(RANDOM()%3)) {
670  if (monster_cast_spell(op, part, enemy, dir, &rv1))
671  return 0;
672  }
673 
674  if (QUERY_FLAG(op, FLAG_READY_SCROLL) && !(RANDOM()%3)) {
675  if (monster_use_scroll(op, part, enemy, dir, &rv1))
676  return 0;
677  }
678 
679  if (QUERY_FLAG(op, FLAG_READY_RANGE) && !(RANDOM()%3)) {
680  if (monster_use_range(op, part, enemy, dir))
681  return 0;
682  }
683  if (QUERY_FLAG(op, FLAG_READY_SKILL) && !(RANDOM()%3)) {
684  if (monster_use_skill(op, rv.part, enemy, rv.direction))
685  return 0;
686  }
687  if (QUERY_FLAG(op, FLAG_READY_BOW) && !(RANDOM()%2)) {
688  if (monster_use_bow(op, part, enemy, dir))
689  return 0;
690  }
691  } /* for processing of all parts */
692  } /* If not scared */
693 
694 
695  /* code below is for when we didn't use a range attack or a skill, so
696  * either move or hit with hth attack. */
697 
698  part = rv.part;
699  dir = rv.direction;
700 
702  dir = absdir(dir+4);
703  else if (!can_hit(part, enemy, &rv))
704  dir = compute_path(op, enemy, rv.direction);
705 
706  if (QUERY_FLAG(op, FLAG_CONFUSED))
707  dir = absdir(dir+RANDOM()%3+RANDOM()%3-2);
708 
709  if ((op->attack_movement&LO4) && !QUERY_FLAG(op, FLAG_SCARED)) {
710  switch (op->attack_movement&LO4) {
711  case DISTATT:
712  dir = dist_att(dir, op, enemy, part, &rv);
713  break;
714 
715  case RUNATT:
716  dir = run_att(dir, op, enemy, part, &rv);
717  break;
718 
719  case HITRUN:
720  dir = hitrun_att(dir, op, enemy);
721  break;
722 
723  case WAITATT:
724  dir = wait_att(dir, op, enemy, part, &rv);
725  break;
726 
727  case RUSH: /* default - monster normally moves towards player */
728  case ALLRUN:
729  break;
730 
731  case DISTHIT:
732  dir = disthit_att(dir, op, enemy, part, &rv);
733  break;
734 
735  case WAIT2:
736  dir = wait_att2(dir, op, enemy, part, &rv);
737  break;
738 
739  default:
740  LOG(llevDebug, "Illegal low mon-move: %d\n", op->attack_movement&LO4);
741  }
742  }
743 
744  if (!dir)
745  return 0;
746 
747  if (!QUERY_FLAG(op, FLAG_STAND_STILL)) {
748  if (move_object(op, dir)) /* Can the monster move directly toward player? */
749  return 0;
750 
751  if (QUERY_FLAG(op, FLAG_SCARED)
752  || !can_hit(part, enemy, &rv)
753  || QUERY_FLAG(op, FLAG_RUN_AWAY)) {
754  /* Try move around corners if !close */
755  int maxdiff = (QUERY_FLAG(op, FLAG_ONLY_ATTACK) || RANDOM()&1) ? 1 : 2;
756  for (diff = 1; diff <= maxdiff; diff++) {
757  /* try different detours */
758  int m = 1-(RANDOM()&2); /* Try left or right first? */
759  if (move_object(op, absdir(dir+diff*m))
760  || move_object(op, absdir(dir-diff*m)))
761  return 0;
762  }
763  }
764  } /* if monster is not standing still */
765 
766  /*
767  * Eneq(@csd.uu.se): Patch to make RUN_AWAY or SCARED monsters move a random
768  * direction if they can't move away.
769  */
770  if (!QUERY_FLAG(op, FLAG_ONLY_ATTACK)
772  if (move_randomly(op))
773  return 0;
774 
775  /*
776  * Try giving the monster a new enemy - the player that is closest
777  * to it. In this way, it won't just keep trying to get to a target
778  * that is inaccessible.
779  * This could be more clever - it should go through a list of several
780  * enemies, as it is now, you could perhaps get situations where there
781  * are two players flanking the monster at close distance, but which
782  * the monster can't get to, and a third one at a far distance that
783  * the monster could get to - as it is, the monster won't look at that
784  * third one.
785  */
786  if (!QUERY_FLAG(op, FLAG_FRIENDLY) && enemy == op->enemy) {
787  object *nearest_player = get_nearest_player(op);
788 
789  if (nearest_player && nearest_player != enemy && !can_hit(part, enemy, &rv)) {
790  op->enemy = NULL;
791  enemy = nearest_player;
792  }
793  }
794 
795  if (!QUERY_FLAG(op, FLAG_SCARED) && can_hit(part, enemy, &rv)) {
796  /* The adjustement to wc that was here before looked totally bogus -
797  * since wc can in fact get negative, that would mean by adding
798  * the current wc, the creature gets better? Instead, just
799  * add a fixed amount - nasty creatures that are runny away should
800  * still be pretty nasty.
801  */
802  if (QUERY_FLAG(op, FLAG_RUN_AWAY)) {
803  part->stats.wc += 10;
804  (void)skill_attack(enemy, part, 0, NULL, NULL);
805  part->stats.wc -= 10;
806  } else
807  (void)skill_attack(enemy, part, 0, NULL, NULL);
808  } /* if monster is in attack range */
809 
810  if (QUERY_FLAG(part, FLAG_FREED)) /* Might be freed by ghost-attack or hit-back */
811  return 1;
812 
813  if (QUERY_FLAG(op, FLAG_ONLY_ATTACK)) {
814  remove_ob(op);
815  free_object(op);
816  return 1;
817  }
818  return 0;
819 }
820 
835 static int can_hit(object *ob1, object *ob2, rv_vector *rv) {
836  object *more;
837  rv_vector rv1;
838 
839  if (QUERY_FLAG(ob1, FLAG_CONFUSED)&&!(RANDOM()%3))
840  return 0;
841 
842  if (abs(rv->distance_x) < 2 && abs(rv->distance_y) < 2)
843  return 1;
844 
845  /* check all the parts of ob2 - just because we can't get to
846  * its head doesn't mean we don't want to pound its feet
847  */
848  for (more = ob2->more; more != NULL; more = more->more) {
849  get_rangevector(ob1, more, &rv1, 0);
850  if (abs(rv1.distance_x) < 2 && abs(rv1.distance_y) < 2)
851  return 1;
852  }
853  return 0;
854 }
855 
880 static int monster_should_cast_spell(object *monster, object *spell_ob) {
881  if (spell_ob->subtype == SP_BOLT
882  || spell_ob->subtype == SP_BULLET
883  || spell_ob->subtype == SP_EXPLOSION
884  || spell_ob->subtype == SP_CONE
885  || spell_ob->subtype == SP_BOMB
886  || spell_ob->subtype == SP_SMITE
887  || spell_ob->subtype == SP_MAGIC_MISSILE
888  || spell_ob->subtype == SP_SUMMON_GOLEM
889  || spell_ob->subtype == SP_MAGIC_WALL
890  || spell_ob->subtype == SP_SUMMON_MONSTER
891  || spell_ob->subtype == SP_MOVING_BALL
892  || spell_ob->subtype == SP_SWARM
893  || spell_ob->subtype == SP_INVISIBLE)
894  return 1;
895 
896  return 0;
897 }
898 
900 #define MAX_KNOWN_SPELLS 20
901 
917 static object *monster_choose_random_spell(object *monster) {
918  object *altern[MAX_KNOWN_SPELLS];
919  object *tmp;
920  int i = 0;
921 
922  for (tmp = monster->inv; tmp != NULL; tmp = tmp->below)
923  if (tmp->type == SPELLBOOK || tmp->type == SPELL) {
924  /* Check and see if it's actually a useful spell.
925  * If its a spellbook, the spell is actually the inventory item.
926  * if it is a spell, then it is just the object itself.
927  */
928  if (monster_should_cast_spell(monster, (tmp->type == SPELLBOOK) ? tmp->inv : tmp)) {
929  altern[i++] = tmp;
930  if (i == MAX_KNOWN_SPELLS)
931  break;
932  }
933  }
934  if (!i)
935  return NULL;
936  return altern[RANDOM()%i];
937 }
938 
957 static int monster_cast_spell(object *head, object *part, object *pl, int dir, rv_vector *rv) {
958  object *spell_item;
959  object *owner;
960  rv_vector rv1;
961 
962  /* If you want monsters to cast spells over friends, this spell should
963  * be removed. It probably should be in most cases, since monsters still
964  * don't care about residual effects (ie, casting a cone which may have a
965  * clear path to the player, the side aspects of the code will still hit
966  * other monsters)
967  */
968  if (!(dir = path_to_player(part, pl, 0)))
969  return 0;
970 
971  if (QUERY_FLAG(head, FLAG_FRIENDLY) && (owner = get_owner(head)) != NULL) {
972  get_rangevector(head, owner, &rv1, 0x1);
973  if (dirdiff(dir, rv1.direction) < 2) {
974  return 0; /* Might hit owner with spell */
975  }
976  }
977 
978  if (QUERY_FLAG(head, FLAG_CONFUSED))
979  dir = absdir(dir+RANDOM()%3+RANDOM()%3-2);
980 
981  /* If the monster hasn't already chosen a spell, choose one
982  * I'm not sure if it really make sense to pre-select spells (events
983  * could be different by the time the monster goes again).
984  */
985  if (head->spellitem == NULL) {
986  if ((spell_item = monster_choose_random_spell(head)) == NULL) {
987  LOG(llevMonster, "Turned off spells in %s\n", head->name);
988  CLEAR_FLAG(head, FLAG_CAST_SPELL); /* Will be turned on when picking up book */
989  return 0;
990  }
991  if (spell_item->type == SPELLBOOK) {
992  if (!spell_item->inv) {
993  LOG(llevError, "spellbook %s does not contain a spell?\n", spell_item->name);
994  return 0;
995  }
996  spell_item = spell_item->inv;
997  }
998  } else
999  spell_item = head->spellitem;
1000 
1001  if (!spell_item)
1002  return 0;
1003 
1004  /* Best guess this is a defensive/healing spell */
1005  if (spell_item->range <= 1 || spell_item->stats.dam < 0)
1006  dir = 0;
1007 
1008  /* Monster doesn't have enough spell-points */
1009  if (head->stats.sp < SP_level_spellpoint_cost(head, spell_item, SPELL_MANA))
1010  return 0;
1011 
1012  if (head->stats.grace < SP_level_spellpoint_cost(head, spell_item, SPELL_GRACE))
1013  return 0;
1014 
1015  head->stats.sp -= SP_level_spellpoint_cost(head, spell_item, SPELL_MANA);
1016  head->stats.grace -= SP_level_spellpoint_cost(head, spell_item, SPELL_GRACE);
1017 
1018  /* set this to null, so next time monster will choose something different */
1019  head->spellitem = NULL;
1020 
1021  return cast_spell(part, part, dir, spell_item, NULL);
1022 }
1023 
1040 static int monster_use_scroll(object *head, object *part, object *pl, int dir, rv_vector *rv) {
1041  object *scroll;
1042  object *owner;
1043  rv_vector rv1;
1044 
1045  /* If you want monsters to cast spells over friends, this spell should
1046  * be removed. It probably should be in most cases, since monsters still
1047  * don't care about residual effects (ie, casting a cone which may have a
1048  * clear path to the player, the side aspects of the code will still hit
1049  * other monsters)
1050  */
1051  if (!(dir = path_to_player(part, pl, 0)))
1052  return 0;
1053 
1054  if (QUERY_FLAG(head, FLAG_FRIENDLY) && (owner = get_owner(head)) != NULL) {
1055  get_rangevector(head, owner, &rv1, 0x1);
1056  if (dirdiff(dir, rv1.direction) < 2) {
1057  return 0; /* Might hit owner with spell */
1058  }
1059  }
1060 
1061  if (QUERY_FLAG(head, FLAG_CONFUSED))
1062  dir = absdir(dir+RANDOM()%3+RANDOM()%3-2);
1063 
1064  for (scroll = head->inv; scroll; scroll = scroll->below)
1065  if (scroll->type == SCROLL && monster_should_cast_spell(head, scroll->inv))
1066  break;
1067 
1068  /* Used up all his scrolls, so nothing do to */
1069  if (!scroll) {
1071  return 0;
1072  }
1073 
1074  /* Spell should be cast on caster (ie, heal, strength) */
1075  if (scroll->inv->range == 0)
1076  dir = 0;
1077 
1078  /* Face the direction that we want to cast. */
1079  head->direction = dir;
1080  head->facing = head->direction;
1081  if (head->animation_id)
1082  animate_object(head, head->direction);
1083 
1084  ob_apply(scroll, part, 0);
1085  return 1;
1086 }
1087 
1115 static int monster_use_skill(object *head, object *part, object *pl, int dir) {
1116  object *skill, *owner;
1117 
1118  if (!(dir = path_to_player(part, pl, 0)))
1119  return 0;
1120 
1121  if (QUERY_FLAG(head, FLAG_FRIENDLY) && (owner = get_owner(head)) != NULL) {
1122  int dir2 = find_dir_2(head->x-owner->x, head->y-owner->y);
1123  if (dirdiff(dir, dir2) < 1)
1124  return 0; /* Might hit owner with skill -thrown rocks for example ?*/
1125  }
1126  if (QUERY_FLAG(head, FLAG_CONFUSED))
1127  dir = absdir(dir+RANDOM()%3+RANDOM()%3-2);
1128 
1129  /* skill selection - monster will use the next unused skill.
1130  * well...the following scenario will allow the monster to
1131  * toggle between 2 skills. One day it would be nice to make
1132  * more skills available to monsters.
1133  */
1134 
1135  for (skill = head->inv; skill != NULL; skill = skill->below)
1136  if (skill->type == SKILL && skill != head->chosen_skill) {
1137  head->chosen_skill = skill;
1138  break;
1139  }
1140 
1141  if (!skill && !head->chosen_skill) {
1142  LOG(llevDebug, "Error: Monster %s (%d) has FLAG_READY_SKILL without skill.\n", head->name, head->count);
1144  return 0;
1145  }
1146  /* use skill */
1147  return do_skill(head, part, head->chosen_skill, dir, NULL);
1148 }
1149 
1164 static int monster_use_range(object *head, object *part, object *pl, int dir) {
1165  object *wand, *owner;
1166  int at_least_one = 0;
1167 
1168  if (!(dir = path_to_player(part, pl, 0)))
1169  return 0;
1170 
1171  if (QUERY_FLAG(head, FLAG_FRIENDLY) && (owner = get_owner(head)) != NULL) {
1172  int dir2 = find_dir_2(head->x-owner->x, head->y-owner->y);
1173  if (dirdiff(dir, dir2) < 2)
1174  return 0; /* Might hit owner with spell */
1175  }
1176  if (QUERY_FLAG(head, FLAG_CONFUSED))
1177  dir = absdir(dir+RANDOM()%3+RANDOM()%3-2);
1178 
1179  for (wand = head->inv; wand != NULL; wand = wand->below) {
1180  if (wand->type == WAND) {
1181  /* Found a wand, let's see if it has charges left */
1182  at_least_one = 1;
1183  if (wand->stats.food <= 0)
1184  continue;
1185 
1186  cast_spell(head, wand, dir, wand->inv, NULL);
1187  drain_wand_charge(wand);
1188 
1189  /* Success */
1190  return 1;
1191  } else if (wand->type == ROD || wand->type == HORN) {
1192  /* Found rod/horn, let's use it if possible */
1193  at_least_one = 1;
1194  if (wand->stats.hp < MAX(wand->inv->stats.sp, wand->inv->stats.grace))
1195  continue;
1196 
1197  /* drain charge before casting spell - can be a case where the
1198  * spell destroys the monster, and rod, so if done after, results
1199  * in crash.
1200  */
1201  drain_rod_charge(wand);
1202  cast_spell(head, wand, dir, wand->inv, NULL);
1203 
1204  /* Success */
1205  return 1;
1206  }
1207  }
1208 
1209  if (at_least_one)
1210  return 0;
1211 
1212  LOG(llevError, "Error: Monster %s (%d) HAS_READY_RANG() without wand/horn/rod.\n", head->name, head->count);
1214  return 0;
1215 }
1216 
1233 static int monster_use_bow(object *head, object *part, object *pl, int dir) {
1234  object *owner;
1235  rv_vector rv;
1236  sint16 x, y;
1237  mapstruct *map;
1238 
1239  get_rangevector(part, pl, &rv, 1);
1240  if (rv.distance > 100)
1241  /* Too far */
1242  return 0;
1243  if (rv.distance_x != 0 && rv.distance_y != 0 && abs(rv.distance_x) != abs(rv.distance_y))
1244  /* Player must be on same horizontal, vertical or diagonal line. */
1245  return 0;
1246  dir = absdir(find_dir_2(rv.distance_x, rv.distance_y)+4);
1247 
1248  if (QUERY_FLAG(head, FLAG_FRIENDLY))
1249  owner = get_owner(head);
1250  else
1251  owner = NULL;
1252 
1253  /* The monster can possibly fire, let's see if the path is ok for an arrow. */
1254  x = part->x;
1255  y = part->y;
1256  map = part->map;
1257  while (x != pl->x || y != pl->y || map != pl->map) {
1258  x += freearr_x[dir];
1259  y += freearr_y[dir];
1260  map = get_map_from_coord(map, &x, &y);
1261  if (!map) {
1262  LOG(llevError, "monster_use_bow: no map but still path exists??\n");
1263  return 0;
1264  }
1265  if ((GET_MAP_MOVE_BLOCK(map, x, y)&MOVE_FLY_LOW) == MOVE_FLY_LOW)
1266  return 0;
1267  if (owner && owner->x == x && owner->y == y && owner->map == map)
1268  /* Don't hit owner! */
1269  return 0;
1270  }
1271 
1272  /* Finally, path is clear, can fire. */
1273 
1274  if (QUERY_FLAG(head, FLAG_CONFUSED))
1275  dir = absdir(dir+RANDOM()%3+RANDOM()%3-2);
1276 
1277  /* in server/player.c */
1278  return fire_bow(head, NULL, dir, 0, part->x, part->y);
1279 }
1280 
1293 static int check_good_weapon(object *who, object *item) {
1294  object *other_weap;
1295  int val = 0, i;
1296 
1297  for (other_weap = who->inv; other_weap != NULL; other_weap = other_weap->below)
1298  if (other_weap->type == item->type && QUERY_FLAG(other_weap, FLAG_APPLIED))
1299  break;
1300 
1301  if (other_weap == NULL) /* No other weapons */
1302  return 1;
1303 
1304  /* Rather than go through and apply the new one, and see if it is
1305  * better, just do some simple checks
1306  * Put some multipliers for things that hvae several effects,
1307  * eg, magic affects both damage and wc, so it has more weight
1308  */
1309 
1310  val = item->stats.dam-other_weap->stats.dam;
1311  val += (item->magic-other_weap->magic)*3;
1312  /* Monsters don't really get benefits from things like regen rates
1313  * from items. But the bonus for their stats are very important.
1314  */
1315  for (i = 0; i < NUM_STATS; i++)
1316  val += (get_attr_value(&item->stats, i)-get_attr_value(&other_weap->stats, i))*2;
1317 
1318  if (val > 0)
1319  return 1;
1320  else
1321  return 0;
1322 }
1323 
1336 static int check_good_armour(object *who, object *item) {
1337  object *other_armour;
1338  int val = 0, i;
1339 
1340  for (other_armour = who->inv; other_armour != NULL; other_armour = other_armour->below)
1341  if (other_armour->type == item->type && QUERY_FLAG(other_armour, FLAG_APPLIED))
1342  break;
1343 
1344  if (other_armour == NULL) /* No other armour, use the new */
1345  return 1;
1346 
1347  /* Like above function , see which is better */
1348  val = item->stats.ac-other_armour->stats.ac;
1349  val = (item->resist[ATNR_PHYSICAL]-other_armour->resist[ATNR_PHYSICAL])/5;
1350  val += (item->magic-other_armour->magic)*3;
1351 
1352  /* for the other protections, do weigh them very much in the equation -
1353  * it is the armor protection which is most important, because there is
1354  * no good way to know what the player may attack the monster with.
1355  * So if the new item has better protection than the old, give that higher
1356  * value. If the reverse, then decrease the value of this item some.
1357  */
1358  for (i = 1; i < NROFATTACKS; i++) {
1359  if (item->resist[i] > other_armour->resist[i])
1360  val++;
1361  else if (item->resist[i] < other_armour->resist[i])
1362  val--;
1363  }
1364 
1365  /* Very few armours have stats, so not much need to worry about those. */
1366 
1367  if (val > 0)
1368  return 1;
1369  else
1370  return 0;
1371 
1372 }
1373 
1393 static void monster_check_pickup(object *monster) {
1394  object *tmp, *next;
1395  int next_tag;
1396 
1397  for (tmp = monster->below; tmp != NULL; tmp = next) {
1398  next = tmp->below;
1399  next_tag = next ? next->count : 0;
1400  if (monster_can_pick(monster, tmp)) {
1401  remove_ob(tmp);
1402  tmp = insert_ob_in_ob(tmp, monster);
1403  (void)monster_check_apply(monster, tmp);
1404  }
1405  /* We could try to re-establish the cycling, of the space, but probably
1406  * not a big deal to just bail out.
1407  */
1408  if (next && was_destroyed(next, next_tag))
1409  return;
1410  }
1411 }
1412 
1413 /*
1414  * monster_can_pick(): If the monster is interested in picking up
1415  * the item, then return 0. Otherwise 0.
1416  * Instead of pick_up, flags for "greed", etc, should be used.
1417  * I've already utilized flags for bows, wands, rings, etc, etc. -Frank.
1418  */
1419 
1420 static int monster_can_pick(object *monster, object *item) {
1421  int flag = 0;
1422  int i;
1423 
1424  if (!can_pick(monster, item))
1425  return 0;
1426 
1427  if (QUERY_FLAG(item, FLAG_UNPAID))
1428  return 0;
1429 
1430  if (monster->pick_up&64) /* All */
1431  flag = 1;
1432 
1433  else {
1434  if (IS_WEAPON(item))
1435  flag = (monster->pick_up&8) || QUERY_FLAG(monster, FLAG_USE_WEAPON);
1436  else if (IS_ARMOR(item))
1437  flag = (monster->pick_up&16) || QUERY_FLAG(monster, FLAG_USE_ARMOUR);
1438  else if (IS_SHIELD(item))
1439  flag = (monster->pick_up&16) || QUERY_FLAG(monster, FLAG_USE_SHIELD);
1440  else switch (item->type) {
1441  case MONEY:
1442  case GEM:
1443  flag = monster->pick_up&2;
1444  break;
1445 
1446  case FOOD:
1447  flag = monster->pick_up&4;
1448  break;
1449 
1450  case SKILL:
1451  flag = QUERY_FLAG(monster, FLAG_CAN_USE_SKILL);
1452  break;
1453 
1454  case RING:
1455  flag = QUERY_FLAG(monster, FLAG_USE_RING);
1456  break;
1457 
1458  case WAND:
1459  case HORN:
1460  case ROD:
1461  flag = QUERY_FLAG(monster, FLAG_USE_RANGE);
1462  break;
1463 
1464  case SPELLBOOK:
1465  flag = (monster->arch != NULL && QUERY_FLAG((&monster->arch->clone), FLAG_CAST_SPELL));
1466  break;
1467 
1468  case SCROLL:
1469  flag = QUERY_FLAG(monster, FLAG_USE_SCROLL);
1470  break;
1471 
1472  case BOW:
1473  case ARROW:
1474  flag = QUERY_FLAG(monster, FLAG_USE_BOW);
1475  break;
1476  }
1477  /* Simplistic check - if the monster has a location to equip it, he will
1478  * pick it up. Note that this doesn't handle cases where an item may
1479  * use several locations.
1480  */
1481  for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
1482  if (monster->body_info[i] && item->body_info[i]) {
1483  flag = 1;
1484  break;
1485  }
1486  }
1487  }
1488 
1489  if (((!(monster->pick_up&32)) && flag) || ((monster->pick_up&32) && (!flag)))
1490  return 1;
1491  return 0;
1492 }
1493 
1494 /*
1495  * monster_apply_below():
1496  * Vick's (vick@bern.docs.uu.se) @921107 -> If a monster who's
1497  * eager to apply things, encounters something apply-able,
1498  * then make him apply it
1499  */
1500 static void monster_apply_below(object *monster) {
1501  object *tmp, *next;
1502 
1503  for (tmp = monster->below; tmp != NULL; tmp = next) {
1504  next = tmp->below;
1505  switch (tmp->type) {
1506  case CF_HANDLE:
1507  case TRIGGER:
1508  if (monster->will_apply&WILL_APPLY_HANDLE)
1509  manual_apply(monster, tmp, 0);
1510  break;
1511 
1512  case TREASURE:
1513  if (monster->will_apply&WILL_APPLY_TREASURE)
1514  manual_apply(monster, tmp, 0);
1515  break;
1516  }
1517  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
1518  break;
1519  }
1520 }
1521 
1522 /*
1523  * monster_check_apply() is meant to be called after an item is
1524  * inserted in a monster.
1525  * If an item becomes outdated (monster found a better item),
1526  * a pointer to that object is returned, so it can be dropped.
1527  * (so that other monsters can pick it up and use it)
1528  * Note that as things are now, monsters never drop something -
1529  * they can pick up all that they can use.
1530  */
1531 
1532 /* Sept 96, fixed this so skills will be readied -b.t.*/
1533 
1534 void monster_check_apply(object *mon, object *item) {
1535  int flag = 0;
1536 
1537  if (item->type == SPELLBOOK
1538  && mon->arch != NULL
1539  && (QUERY_FLAG((&mon->arch->clone), FLAG_CAST_SPELL))) {
1540  SET_FLAG(mon, FLAG_CAST_SPELL);
1541  return;
1542  }
1543 
1544  /* If for some reason, this item is already applied, no more work to do */
1545  if (QUERY_FLAG(item, FLAG_APPLIED))
1546  return;
1547 
1548  /* Might be better not to do this - if the monster can fire a bow,
1549  * it is possible in his wanderings, he will find one to use. In
1550  * which case, it would be nice to have ammo for it.
1551  */
1552  if (QUERY_FLAG(mon, FLAG_USE_BOW) && item->type == ARROW) {
1553  /* Check for the right kind of bow */
1554  object *bow;
1555 
1556  for (bow = mon->inv; bow != NULL; bow = bow->below)
1557  if (bow->type == BOW && bow->race == item->race) {
1558  SET_FLAG(mon, FLAG_READY_BOW);
1559  LOG(llevMonster, "Found correct bow for arrows.\n");
1560  return; /* nothing more to do for arrows */
1561  }
1562  }
1563 
1564  if (item->type == TREASURE && mon->will_apply&WILL_APPLY_TREASURE)
1565  flag = 1;
1566  /* Eating food gets hp back */
1567  else if (item->type == FOOD && mon->will_apply&WILL_APPLY_FOOD)
1568  flag = 1;
1569  else if (item->type == SCROLL && QUERY_FLAG(mon, FLAG_USE_SCROLL)) {
1570  if (!item->inv)
1571  LOG(llevDebug, "Monster %d having scroll %d with empty inventory!\n", mon->count, item->count);
1572  else if (monster_should_cast_spell(mon, item->inv))
1574  /* Don't use it right now */
1575  return;
1576  } else if (item->type == WEAPON)
1577  flag = check_good_weapon(mon, item);
1578  else if (IS_ARMOR(item) || IS_SHIELD(item))
1579  flag = check_good_armour(mon, item);
1580  /* Should do something more, like make sure this is a better item */
1581  else if (item->type == RING)
1582  flag = 1;
1583  else if (item->type == WAND || item->type == ROD || item->type == HORN) {
1584  /* We never really 'ready' the wand/rod/horn, because that would mean the
1585  * weapon would get undone.
1586  */
1587  if (!(can_apply_object(mon, item)&CAN_APPLY_NOT_MASK)) {
1588  SET_FLAG(mon, FLAG_READY_RANGE);
1589  SET_FLAG(item, FLAG_APPLIED);
1590  }
1591  return;
1592  } else if (item->type == BOW) {
1593  /* We never really 'ready' the bow, because that would mean the
1594  * weapon would get undone.
1595  */
1596  if (!(can_apply_object(mon, item)&CAN_APPLY_NOT_MASK))
1597  SET_FLAG(mon, FLAG_READY_BOW);
1598  return;
1599  } else if (item->type == SKILL) {
1600  /*
1601  * skills are specials: monsters must have the 'FLAG_READY_SKILL' flag set,
1602  * else they can't use the skill...
1603  * Skills also don't need to get applied, so return now.
1604  */
1605  SET_FLAG(mon, FLAG_READY_SKILL);
1606  return;
1607  }
1608 
1609  /* if we don't match one of the above types, return now.
1610  * can_apply_object will say that we can apply things like flesh,
1611  * bolts, and whatever else, because it only checks against the
1612  * body_info locations.
1613  */
1614  if (!flag)
1615  return;
1616 
1617  /* Check to see if the monster can use this item. If not, no need
1618  * to do further processing. Note that can_apply_object already checks
1619  * for the CAN_USE flags.
1620  */
1621  if (can_apply_object(mon, item)&CAN_APPLY_NOT_MASK)
1622  return;
1623 
1624  /* should only be applying this item, not unapplying it.
1625  * also, ignore status of curse so they can take off old armour.
1626  * monsters have some advantages after all.
1627  */
1629  return;
1630 }
1631 
1632 void npc_call_help(object *op) {
1633  int x, y, mflags;
1634  object *npc;
1635  sint16 sx, sy;
1636  mapstruct *m;
1637 
1638  for (x = -3; x < 4; x++)
1639  for (y = -3; y < 4; y++) {
1640  m = op->map;
1641  sx = op->x+x;
1642  sy = op->y+y;
1643  mflags = get_map_flags(m, &m, sx, sy, &sx, &sy);
1644  /* If nothing alive on this space, no need to search the space. */
1645  if ((mflags&P_OUT_OF_MAP) || !(mflags&P_IS_ALIVE))
1646  continue;
1647 
1648  for (npc = GET_MAP_OB(m, sx, sy); npc != NULL; npc = npc->above)
1650  npc->enemy = op->enemy;
1651  }
1652 }
1653 
1654 static int dist_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv) {
1655  if (can_hit(part, enemy, rv))
1656  return dir;
1657  if (rv->distance < 10)
1658  return absdir(dir+4);
1659  else if (rv->distance > 18)
1660  return dir;
1661  return 0;
1662 }
1663 
1664 static int run_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv) {
1665  if ((can_hit(part, enemy, rv) && ob->move_status < 20) || ob->move_status < 20) {
1666  ob->move_status++;
1667  return (dir);
1668  } else if (ob->move_status > 20)
1669  ob->move_status = 0;
1670  return absdir(dir+4);
1671 }
1672 
1673 static int hitrun_att(int dir, object *ob, object *enemy) {
1674  if (ob->move_status++ < 25)
1675  return dir;
1676  else if (ob->move_status < 50)
1677  return absdir(dir+4);
1678  else
1679  ob->move_status = 0;
1680  return absdir(dir+4);
1681 }
1682 
1683 static int wait_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv) {
1684  int inrange = can_hit(part, enemy, rv);
1685 
1686  if (ob->move_status || inrange)
1687  ob->move_status++;
1688 
1689  if (ob->move_status == 0)
1690  return 0;
1691  else if (ob->move_status < 10)
1692  return dir;
1693  else if (ob->move_status < 15)
1694  return absdir(dir+4);
1695  ob->move_status = 0;
1696  return 0;
1697 }
1698 
1699 static int disthit_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv) {
1700  /* The logic below here looked plain wrong before. Basically, what should
1701  * happen is that if the creatures hp percentage falls below run_away,
1702  * the creature should run away (dir+4)
1703  * I think its wrong for a creature to have a zero maxhp value, but
1704  * at least one map has this set, and whatever the map contains, the
1705  * server should try to be resilant enough to avoid the problem
1706  */
1707  if (ob->stats.maxhp && (ob->stats.hp*100)/ob->stats.maxhp < ob->run_away)
1708  return absdir(dir+4);
1709  return dist_att(dir, ob, enemy, part, rv);
1710 }
1711 
1712 static int wait_att2(int dir, object *ob, object *enemy, object *part, rv_vector *rv) {
1713  if (rv->distance < 9)
1714  return absdir(dir+4);
1715  return 0;
1716 }
1717 
1718 static void circ1_move(object *ob) {
1719  static const int circle [12] = { 3, 3, 4, 5, 5, 6, 7, 7, 8, 1, 1, 2 };
1720 
1721  if (++ob->move_status > 11)
1722  ob->move_status = 0;
1723  if (!(move_object(ob, circle[ob->move_status])))
1724  (void)move_object(ob, RANDOM()%8+1);
1725 }
1726 
1727 static void circ2_move(object *ob) {
1728  static const int circle[20] = { 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 1, 1, 1, 2, 2 };
1729 
1730  if (++ob->move_status > 19)
1731  ob->move_status = 0;
1732  if (!(move_object(ob, circle[ob->move_status])))
1733  (void)move_object(ob, RANDOM()%8+1);
1734 }
1735 
1736 static void pace_movev(object *ob) {
1737  if (ob->move_status++ > 6)
1738  ob->move_status = 0;
1739  if (ob->move_status < 4)
1740  (void)move_object(ob, 5);
1741  else
1742  (void)move_object(ob, 1);
1743 }
1744 
1745 static void pace_moveh(object *ob) {
1746  if (ob->move_status++ > 6)
1747  ob->move_status = 0;
1748  if (ob->move_status < 4)
1749  (void)move_object(ob, 3);
1750  else
1751  (void)move_object(ob, 7);
1752 }
1753 
1754 static void pace2_movev(object *ob) {
1755  if (ob->move_status++ > 16)
1756  ob->move_status = 0;
1757  if (ob->move_status < 6)
1758  (void)move_object(ob, 5);
1759  else if (ob->move_status < 8)
1760  return;
1761  else if (ob->move_status < 13)
1762  (void)move_object(ob, 1);
1763  else
1764  return;
1765 }
1766 
1767 static void pace2_moveh(object *ob) {
1768  if (ob->move_status++ > 16)
1769  ob->move_status = 0;
1770  if (ob->move_status < 6)
1771  (void)move_object(ob, 3);
1772  else if (ob->move_status < 8)
1773  return;
1774  else if (ob->move_status < 13)
1775  (void)move_object(ob, 7);
1776  else
1777  return;
1778 }
1779 
1780 static void rand_move(object *ob) {
1781  int i;
1782 
1783  if (ob->move_status < 1
1784  || ob->move_status > 8
1785  || !(move_object(ob, ob->move_status || !(RANDOM()%9))))
1786  for (i = 0; i < 5; i++)
1787  if (move_object(ob, ob->move_status = RANDOM()%8+1))
1788  return;
1789 }
1790 
1791 void check_earthwalls(object *op, mapstruct *m, int x, int y) {
1792  object *tmp;
1793 
1794  for (tmp = GET_MAP_OB(m, x, y); tmp != NULL; tmp = tmp->above) {
1795  if (tmp->type == EARTHWALL) {
1796  hit_player(tmp, op->stats.dam, op, AT_PHYSICAL, 1);
1797  return;
1798  }
1799  }
1800 }
1801 
1802 void check_doors(object *op, mapstruct *m, int x, int y) {
1803  object *tmp;
1804 
1805  for (tmp = GET_MAP_OB(m, x, y); tmp != NULL; tmp = tmp->above) {
1806  if (tmp->type == DOOR) {
1807  hit_player(tmp, 1000, op, AT_PHYSICAL, 1);
1808  return;
1809  }
1810  }
1811 }
1812 
1831 void communicate(object *op, const char *txt) {
1832  object *npc;
1833  int i, mflags, talked = 0;
1834  sint16 x, y;
1835  mapstruct *mp, *orig_map = op->map;
1836  char buf[MAX_BUF];
1837 
1838  snprintf(buf, sizeof(buf), "%s says: %s", op->name, txt);
1839  if (op->type == PLAYER) {
1841  }
1842 
1843  /* Note that this loop looks pretty inefficient to me - we look and try to talk
1844  * to every object within 2 spaces. It would seem that if we trim this down to
1845  * only try to talk to objects with npc->msg set, things would be a lot more efficient,
1846  * but I'm not sure if there are any objects out there that don't have a message and instead
1847  * rely sorely on events - MSW 2009-04-14
1848  */
1849  for (i = 0; i <= SIZEOFFREE2; i++) {
1850  mp = op->map;
1851  x = op->x+freearr_x[i];
1852  y = op->y+freearr_y[i];
1853 
1854  mflags = get_map_flags(mp, &mp, x, y, &x, &y);
1855  if (mflags&P_OUT_OF_MAP)
1856  continue;
1857 
1858  for (npc = GET_MAP_OB(mp, x, y); npc != NULL; npc = npc->above) {
1859  talk_to_npc(op, npc, txt, &talked);
1860  if (orig_map != op->map) {
1861  LOG(llevDebug, "Warning: Forced to swap out very recent map - MAX_OBJECTS should probably be increased\n");
1862  return;
1863  }
1864  }
1865  }
1866 
1867  /* if talked is set, then the talk_to_npc() wrote out this information, so
1868  * don't do it again.
1869  */
1870  if (!talked) {
1871  }
1872 }
1873 
1883 static int do_talk_npc(object *op, object *npc, const char *txt, int *talked) {
1884  char buf[MAX_BUF];
1885  struct_dialog_reply *reply;
1886  struct_dialog_message *message;
1887 
1888  if (!get_dialog_message(npc, txt, &message, &reply))
1889  return 0;
1890 
1891  if (reply) {
1892  snprintf(buf, sizeof(buf), "%s %s: %s", op->name, (reply->type == rt_reply ? "replies" : "asks"), reply->message);
1894  *talked = 1;
1895  }
1896 #if 0
1897  /* let the caller handle this reply - no reason we need to. Leaving this in for the
1898  * time being, as I don't completely understand what all of this is trying to do.
1899  * MSW 2009-04-14
1900  */
1901 
1902  else if (!*talked) {
1903  *talked = 1;
1904  snprintf(buf, sizeof(buf), "%s says: %s", op->name, txt);
1906  }
1907 #endif
1908 
1909  if (npc->type == MAGIC_EAR) {
1911  use_trigger(npc);
1912  } else {
1913  npc_say(npc, message->message);
1914  reply = message->replies;
1915 
1916  if (reply) {
1918  while (reply) {
1920  reply = reply->next;
1921  }
1922  }
1923  }
1924 
1925  return 1;
1926 }
1927 
1933 void npc_say(object *npc, const char *cp) {
1934  char buf[HUGE_BUF], name[MAX_BUF];
1935 
1936  query_name(npc, name, sizeof(name));
1937  snprintf(buf, sizeof(buf), "%s says: %s", name, cp);
1939  buf, buf);
1940 }
1941 
1952 static int talk_to_npc(object *op, object *npc, const char *txt, int *talked) {
1953  object *cobj;
1954 
1955  /* Move this commone area up here - shouldn't cost much extra cpu
1956  * time, and makes the function more readable */
1957  /* Lauwenmark: Handle for plugin say event */
1958  if (execute_event(npc, EVENT_SAY, op, NULL, txt, SCRIPT_FIX_ALL) != 0)
1959  return 0;
1960  /* Lauwenmark - Here we let the objects inside inventories hear and answer, too. */
1961  /* This allows the existence of "intelligent" weapons you can discuss with */
1962  for (cobj = npc->inv; cobj != NULL; cobj = cobj->below) {
1963  if (execute_event(cobj, EVENT_SAY, npc, NULL, txt, SCRIPT_FIX_ALL) != 0)
1964  return 0;
1965  }
1966  if (op == npc)
1967  return 0;
1968  return do_talk_npc(op, npc, txt, talked);
1969 }
1970 
1971 /* find_mon_throw_ob() - modeled on find_throw_ob
1972  * This is probably overly simplistic as it is now - We want
1973  * monsters to throw things like chairs and other pieces of
1974  * furniture, even if they are not good throwable objects.
1975  * Probably better to have the monster throw a throwable object
1976  * first, then throw any non equipped weapon.
1977  */
1978 object *find_mon_throw_ob(object *op) {
1979  object *tmp = NULL;
1980 
1981  if (op->head)
1982  tmp = op->head;
1983  else
1984  tmp = op;
1985 
1986  /* New throw code: look through the inventory. Grap the first legal is_thrown
1987  * marked item and throw it to the enemy.
1988  */
1989 
1990  for (tmp = op->inv; tmp; tmp = tmp->below) {
1991  /* Can't throw invisible objects or items that are applied */
1992  if (tmp->invisible || QUERY_FLAG(tmp, FLAG_APPLIED))
1993  continue;
1994 
1995  if (QUERY_FLAG(tmp, FLAG_IS_THROWN))
1996  break;
1997  }
1998 
1999 #ifdef DEBUG_THROW
2000  {
2001  char what[MAX_BUF];
2002 
2003  query_name(tmp, what, MAX_BUF);
2004  LOG(llevDebug, "%s chooses to throw: %s (%d)\n", op->name, !(tmp) ? "(nothing)" : what, tmp ? tmp->count : -1);
2005  }
2006 #endif
2007 
2008  return tmp;
2009 }
2010 
2011 /* determine if we can 'detect' the enemy. Check for walls blocking the
2012  * los. Also, just because its hidden/invisible, we may be sensitive/smart
2013  * enough (based on Wis & Int) to figure out where the enemy is. -b.t.
2014  * modified by MSW to use the get_rangevector so that map tiling works
2015  * properly. I also so odd code in place that checked for x distance
2016  * OR y distance being within some range - that seemed wrong - both should
2017  * be within the valid range. MSW 2001-08-05
2018  * Returns 0 if enemy can not be detected, 1 if it is detected
2019  */
2020 int can_detect_enemy(object *op, object *enemy, rv_vector *rv) {
2021  int radius = MIN_MON_RADIUS, hide_discovery;
2022 
2023  /* null detection for any of these condtions always */
2024  if (!op || !enemy || !op->map || !enemy->map)
2025  return 0;
2026 
2027  /* If the monster (op) has no way to get to the enemy, do nothing */
2028  if (!on_same_map(op, enemy))
2029  return 0;
2030 
2031  get_rangevector(op, enemy, rv, 0);
2032 
2033  /* Monsters always ignore the DM */
2034  if ((op->type != PLAYER) && QUERY_FLAG(enemy, FLAG_WIZ))
2035  return 0;
2036 
2037  /* simple check. Should probably put some range checks in here. */
2038  if (can_see_enemy(op, enemy))
2039  return 1;
2040 
2041  /* The rest of this is for monsters. Players are on their own for
2042  * finding enemies!
2043  */
2044  if (op->type == PLAYER)
2045  return 0;
2046 
2047  /* Quality invisible? Bah, we wont see them w/o SEE_INVISIBLE
2048  * flag (which was already checked) in can_see_enmy (). Lets get out of here
2049  */
2050  if (enemy->invisible && (!enemy->contr || (!enemy->contr->tmp_invis && !enemy->contr->hidden)))
2051  return 0;
2052 
2053  /* use this for invis also */
2054  hide_discovery = op->stats.Int/5;
2055 
2056  /* Determine Detection radii */
2057  if (!enemy->hide) /* to detect non-hidden (eg dark/invis enemy) */
2058  radius = MAX((op->stats.Wis/5)+1, MIN_MON_RADIUS);
2059  else { /* a level/INT/Dex adjustment for hiding */
2060  object *sk_hide;
2061  int bonus = (op->level/2)+(op->stats.Int/5);
2062 
2063  if (enemy->type == PLAYER) {
2064  if ((sk_hide = find_skill_by_number(enemy, SK_HIDING)))
2065  bonus -= sk_hide->level;
2066  else {
2067  LOG(llevError, "can_detect_enemy() got hidden player w/o hiding skill!\n");
2068  make_visible(enemy);
2069  radius = MAX(radius, MIN_MON_RADIUS);
2070  }
2071  } else /* enemy is not a player */
2072  bonus -= enemy->level;
2073 
2074  radius += bonus/5;
2075  hide_discovery += bonus*5;
2076  } /* else creature has modifiers for hiding */
2077 
2078  /* Radii stealth adjustment. Only if you are stealthy
2079  * will you be able to sneak up closer to creatures */
2080  if (QUERY_FLAG(enemy, FLAG_STEALTH))
2081  radius = radius/2, hide_discovery = hide_discovery/3;
2082 
2083  /* Radii adjustment for enemy standing in the dark */
2084  if (op->map->darkness > 0 && !stand_in_light(enemy)) {
2085  /* on dark maps body heat can help indicate location with infravision
2086  * undead don't have body heat, so no benefit detecting them.
2087  */
2088  if (QUERY_FLAG(op, FLAG_SEE_IN_DARK) && !is_true_undead(enemy))
2089  radius += op->map->darkness/2;
2090  else
2091  radius -= op->map->darkness/2;
2092 
2093  /* op next to a monster (and not in complete darkness)
2094  * the monster should have a chance to see you.
2095  */
2096  if (radius < MIN_MON_RADIUS && op->map->darkness < 5 && rv->distance <= 1)
2097  radius = MIN_MON_RADIUS;
2098  } /* if on dark map */
2099 
2100  /* Lets not worry about monsters that have incredible detection
2101  * radii, we only need to worry here about things the player can
2102  * (potentially) see. This is 13, as that is the maximum size the player
2103  * may have for their map - in that way, creatures at the edge will
2104  * do something. Note that the distance field in the
2105  * vector is real distance, so in theory this should be 18 to
2106  * find that.
2107  */
2108  if (radius > 13)
2109  radius = 13;
2110 
2111  /* Enemy in range! Now test for detection */
2112  if ((int)rv->distance <= radius) {
2113  /* ah, we are within range, detected? take cases */
2114  if (!enemy->invisible) /* enemy in dark squares... are seen! */
2115  return 1;
2116 
2117  /* hidden or low-quality invisible */
2118  if (enemy->hide && (rv->distance <= 1) && (RANDOM()%100 <= hide_discovery)) {
2119  make_visible(enemy);
2120  /* inform players of new status */
2121  if (enemy->type == PLAYER && player_can_view(enemy, op))
2123  "You are discovered by %s!",
2124  "You are discovered by %s!",
2125  op->name);
2126  return 1; /* detected enemy */
2127  } else if (enemy->invisible) {
2128  /* Change this around - instead of negating the invisible, just
2129  * return true so that the mosnter that managed to detect you can
2130  * do something to you. Decreasing the duration of invisible
2131  * doesn't make a lot of sense IMO, as a bunch of stupid creatures
2132  * can then basically negate the spell. The spell isn't negated -
2133  * they just know where you are!
2134  */
2135  if ((RANDOM()%50) <= hide_discovery) {
2136  if (enemy->type == PLAYER) {
2137  char name[MAX_BUF];
2138 
2139  query_name(op, name, MAX_BUF);
2141  "You see %s noticing your position.",
2142  "You see %s noticing your position.",
2143  name);
2144  }
2145  return 1;
2146  }
2147  }
2148  } /* within range */
2149 
2150  /* Wasn't detected above, so still hidden */
2151  return 0;
2152 }
2153 
2154 /* determine if op stands in a lighted square. This is not a very
2155  * intellegent algorithm. For one thing, we ignore los here, SO it
2156  * is possible for a bright light to illuminate a player on the
2157  * other side of a wall (!).
2158  */
2159 int stand_in_light(object *op) {
2160  sint16 nx, ny;
2161  mapstruct *m;
2162 
2163  if (!op)
2164  return 0;
2165  if (op->glow_radius > 0)
2166  return 1;
2167 
2168  if (op->map) {
2169  int x, y, x1, y1;
2170 
2171  /* Check the spaces with the max light radius to see if any of them
2172  * have lights, and if any of them light the player enough, then return 1.
2173  */
2174  for (x = op->x-MAX_LIGHT_RADII; x <= op->x+MAX_LIGHT_RADII; x++) {
2175  for (y = op->y-MAX_LIGHT_RADII; y <= op->y+MAX_LIGHT_RADII; y++) {
2176  m = op->map;
2177  nx = x;
2178  ny = y;
2179 
2180  if (get_map_flags(m, &m, nx, ny, &nx, &ny)&P_OUT_OF_MAP)
2181  continue;
2182 
2183  x1 = abs(x-op->x)*abs(x-op->x);
2184  y1 = abs(y-op->y)*abs(y-op->y);
2185  if (isqrt(x1+y1) < GET_MAP_LIGHT(m, nx, ny))
2186  return 1;
2187  }
2188  }
2189  }
2190  return 0;
2191 }
2192 
2193 /*
2194  * assuming no walls/barriers, lets check to see if its *possible*
2195  * to see an enemy. Note, "detection" is different from "seeing".
2196  * See can_detect_enemy() for more details. -b.t.
2197  * return 0 if can't be seen, 1 if can be
2198  */
2199 int can_see_enemy(object *op, object *enemy) {
2200  object *looker = op->head ? op->head : op;
2201 
2202  /* safety */
2203  if (!looker || !enemy || !QUERY_FLAG(looker, FLAG_ALIVE))
2204  return 0;
2205 
2206  /* we dont give a full treatment of xrays here (shorter range than normal,
2207  * see through walls). Should we change the code elsewhere to make you
2208  * blind even if you can xray?
2209  */
2210  if (QUERY_FLAG(looker, FLAG_BLIND) && !QUERY_FLAG(looker, FLAG_XRAYS))
2211  return 0;
2212 
2213  /* checking for invisible things */
2214  if (enemy->invisible) {
2215  /* HIDDEN ENEMY. by definition, you can't see hidden stuff!
2216  * However, if you carry any source of light, then the hidden
2217  * creature is seeable (and stupid) */
2218  if (has_carried_lights(enemy)) {
2219  if (enemy->hide) {
2220  make_visible(enemy);
2222  "Your light reveals your hiding spot!",
2223  NULL);
2224  }
2225  return 1;
2226  } else if (enemy->hide)
2227  return 0;
2228 
2229  /* Invisible enemy. Break apart the check for invis undead/invis looker
2230  * into more simple checks - the QUERY_FLAG doesn't return 1/0 values,
2231  * and making it a conditional makes the code pretty ugly.
2232  */
2233  if (!QUERY_FLAG(looker, FLAG_SEE_INVISIBLE)) {
2234  if (makes_invisible_to(enemy, looker))
2235  return 0;
2236  }
2237  } else if (looker->type == PLAYER) /* for players, a (possible) shortcut */
2238  if (player_can_view(looker, enemy))
2239  return 1;
2240 
2241  /* ENEMY IN DARK MAP. Without infravision, the enemy is not seen
2242  * unless they carry a light or stand in light. Darkness doesnt
2243  * inhibit the undead per se (but we should give their archs
2244  * CAN_SEE_IN_DARK, this is just a safety
2245  * we care about the enemy maps status, not the looker.
2246  * only relevant for tiled maps, but it is possible that the
2247  * enemy is on a bright map and the looker on a dark - in that
2248  * case, the looker can still see the enemy
2249  */
2250  if (enemy->map->darkness > 0
2251  && !stand_in_light(enemy)
2252  && (!QUERY_FLAG(looker, FLAG_SEE_IN_DARK) || !is_true_undead(looker) || !QUERY_FLAG(looker, FLAG_XRAYS)))
2253  return 0;
2254 
2255  return 1;
2256 }
char path[HUGE_BUF]
Definition: map.h:384
static int move_randomly(object *op)
Definition: monster.c:344
int find_dir_2(int x, int y)
Definition: object.c:3380
#define FOOD
Definition: define.h:118
#define RING
Definition: define.h:232
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, sint16 x, sint16 y, sint16 *nx, sint16 *ny)
Definition: map.c:330
int get_dialog_message(object *op, const char *text, struct_dialog_message **message, struct_dialog_reply **reply)
Definition: dialog.c:214
sint8 Int
Definition: living.h:78
#define NUM_BODY_LOCATIONS
Definition: object.h:41
Definition: player.h:146
#define FLAG_SEE_IN_DARK
Definition: define.h:634
#define FLAG_IS_FLOOR
Definition: define.h:599
#define FLAG_UNPAID
Definition: define.h:532
sint8 ac
Definition: living.h:79
static int hitrun_att(int dir, object *ob, object *enemy)
Definition: monster.c:1673
static void monster_do_living(object *op)
Definition: monster.c:436
#define SP_BOLT
Definition: spells.h:106
#define OUT_OF_MEMORY
Definition: define.h:94
signed short sint16
Definition: global.h:72
#define RANDO
Definition: define.h:859
Definition: map.h:399
#define FLAG_SLEEP
Definition: define.h:604
const char * race
Definition: object.h:171
#define EARTHWALL
Definition: define.h:167
uint16 attack_movement
Definition: object.h:242
#define MAX_LIGHT_RADII
Definition: define.h:759
#define FLAG_USE_SCROLL
Definition: define.h:588
tag_t attacked_by_count
Definition: object.h:234
#define SET_FLAG(xyz, p)
Definition: define.h:510
int fire_bow(object *op, object *arrow, int dir, int wc_mod, sint16 sx, sint16 sy)
Definition: player.c:1922
sstring add_refcount(sstring str)
Definition: shstr.c:202
#define SP_CONE
Definition: spells.h:109
int makes_invisible_to(object *pl, object *mon)
Definition: spell_effect.c:774
#define FABS(x)
Definition: define.h:61
static void circ2_move(object *ob)
Definition: monster.c:1727
sint8 range
Definition: object.h:256
signed int sint32
Definition: global.h:64
object * part
Definition: map.h:404
#define WAND
Definition: define.h:291
#define NDI_WHITE
Definition: newclient.h:196
#define FLAG_USE_ARMOUR
Definition: define.h:592
#define FLAG_STAND_STILL
Definition: define.h:605
void drain_wand_charge(object *wand)
Definition: spell_util.c:753
void npc_say(object *npc, const char *cp)
Definition: monster.c:1933
static int check_good_weapon(object *who, object *item)
Definition: monster.c:1293
#define FLAG_FRIENDLY
Definition: define.h:542
#define MONEY
Definition: define.h:148
#define PACEV2
Definition: define.h:868
object * mon
Definition: comet_perf.c:74
#define SP_MOVING_BALL
Definition: spells.h:137
#define DOOR
Definition: define.h:135
#define SPELL_GRACE
Definition: spells.h:87
void get_search_arr(int *search_arr)
Definition: object.c:3283
sint32 move_status
Definition: object.h:241
sint32 last_heal
Definition: object.h:208
sint8 get_attr_value(const living *stats, int attr)
Definition: living.c:377
#define FLAG_READY_RANGE
Definition: define.h:595
void free_string(sstring str)
Definition: shstr.c:272
#define HUGE_BUF
Definition: define.h:83
#define MSG_TYPE_SKILL_FAILURE
Definition: newclient.h:504
object clone
Definition: object.h:326
sint16 invisible
Definition: object.h:211
short freearr_x[SIZEOFFREE]
Definition: object.c:75
int can_see_enemy(object *op, object *enemy)
Definition: monster.c:2199
void monster_check_apply(object *mon, object *item)
Definition: monster.c:1534
void draw_ext_info(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *message, const char *oldmessage)
Definition: standalone.c:171
#define MIN_MON_RADIUS
Definition: monster.c:67
#define IS_WEAPON(op)
Definition: define.h:449
#define FLAG_CONFUSED
Definition: define.h:608
sint32 last_sp
Definition: object.h:209
#define SCROLL
Definition: define.h:293
#define FLAG_STEALTH
Definition: define.h:609
#define MAX_EXPLORE
Definition: monster.c:355
uint8 subtype
Definition: object.h:190
#define FLAG_USE_WEAPON
Definition: define.h:593
object * get_pet_enemy(object *pet, rv_vector *rv)
Definition: pets.c:67
struct obj * above
Definition: object.h:146
char * message
Definition: dialog.h:11
#define OUT_OF_REAL_MAP(M, X, Y)
Definition: map.h:238
int manual_apply(object *op, object *tmp, int aflag)
Definition: apply.c:512
#define GOLEM
Definition: define.h:168
static int run_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv)
Definition: monster.c:1664
#define FLAG_NO_ATTACK
Definition: define.h:659
#define MSG_TYPE_COMMUNICATION_SAY
Definition: newclient.h:538
sint16 x
Definition: object.h:179
void remove_friendly_object(object *op)
Definition: friend.c:69
method_ret ob_apply(object *op, object *applier, int aflags)
Definition: ob_methods.c:59
#define CIRCLE1
Definition: define.h:841
sint16 sp
Definition: living.h:83
int player_can_view(object *pl, object *op)
Definition: player.c:3906
int path_to_player(object *mon, object *pl, unsigned mindiff)
Definition: player.c:556
#define PETMOVE
Definition: define.h:826
uint16 height
Definition: map.h:370
#define MSG_TYPE_DIALOG
Definition: newclient.h:322
#define SCRIPT_FIX_ALL
Definition: global.h:450
#define AP_APPLY
Definition: define.h:1009
void draw_ext_info_format(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *new_format, const char *old_format,...)
Definition: standalone.c:175
#define FLAG_USE_SHIELD
Definition: define.h:533
struct obj * enemy
Definition: object.h:232
#define FLAG_USE_RING
Definition: define.h:594
int distance_y
Definition: map.h:402
int absdir(int d)
Definition: object.c:3417
#define HITRUN
Definition: define.h:818
static int monster_use_scroll(object *head, object *part, object *pl, int dir, rv_vector *rv)
Definition: monster.c:1040
int can_detect_enemy(object *op, object *enemy, rv_vector *rv)
Definition: monster.c:2020
#define PLAYER
Definition: define.h:113
sint16 maxsp
Definition: living.h:84
sint8 Con
Definition: living.h:78
#define FLAG_REMOVED
Definition: define.h:528
sint16 hp
Definition: living.h:81
#define MAGIC_EAR
Definition: define.h:141
static int talk_to_npc(object *op, object *npc, const char *txt, int *talked)
Definition: monster.c:1952
short freearr_y[SIZEOFFREE]
Definition: object.c:81
#define NDI_NAVY
Definition: newclient.h:197
static void pace2_movev(object *ob)
Definition: monster.c:1754
#define FLAG_SEE_INVISIBLE
Definition: define.h:549
#define FLAG_READY_SKILL
Definition: define.h:630
struct obj * chosen_skill
Definition: object.h:237
#define RUNATT
Definition: define.h:817
void remove_ob(object *op)
Definition: object.c:1515
sint16 maxhp
Definition: living.h:82
static int wait_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv)
Definition: monster.c:1683
int dirdiff(int dir1, int dir2)
Definition: object.c:3434
#define HI4
Definition: define.h:876
#define SP_BULLET
Definition: spells.h:107
#define FLAG_ALIVE
Definition: define.h:526
void do_hidden_move(object *op)
Definition: player.c:3796
#define AP_IGNORE_CURSE
Definition: define.h:1016
uint32 hidden
Definition: player.h:186
#define FLAG_READY_SCROLL
Definition: define.h:621
int skill_attack(object *tmp, object *pl, int dir, const char *string, object *skill)
Definition: skill_util.c:1126
#define FLAG_CAN_USE_SKILL
Definition: define.h:618
#define MOVE_FLY_LOW
Definition: define.h:701
void drain_rod_charge(object *rod)
Definition: spell_util.c:743
#define SP_BOMB
Definition: spells.h:110
sint8 Wis
Definition: living.h:78
#define FLAG_UNAGGRESSIVE
Definition: define.h:568
struct mapdef * map
Definition: object.h:155
void get_rangevector(object *op1, const object *op2, rv_vector *retval, int flags)
Definition: map.c:2504
object * get_nearest_player(object *mon)
Definition: player.c:447
#define HORN
Definition: define.h:147
int compute_path(object *source, object *target, int default_dir)
Definition: monster.c:371
#define WILL_APPLY_TREASURE
Definition: object.h:79
static int can_hit(object *ob1, object *ob2, rv_vector *rv)
Definition: monster.c:835
Definition: dialog.h:5
static int monster_should_cast_spell(object *monster, object *spell_ob)
Definition: monster.c:880
sint16 dam
Definition: living.h:87
#define PACEH
Definition: define.h:849
const char * name
Definition: object.h:167
#define SPELL
Definition: define.h:283
uint32 tmp_invis
Definition: player.h:179
int distance_x
Definition: map.h:401
uint16 run_away
Definition: object.h:235
#define SP_SMITE
Definition: spells.h:112
static void rand_move(object *ob)
Definition: monster.c:1780
object * get_owner(object *op)
Definition: object.c:524
int is_true_undead(object *op)
Definition: player.c:3731
struct obj * below
Definition: object.h:145
void fatal(int err)
Definition: glue.c:60
#define GET_MAP_LIGHT(M, X, Y)
Definition: map.h:186
object * check_enemy(object *npc, rv_vector *rv)
Definition: monster.c:83
static object * monster_choose_random_spell(object *monster)
Definition: monster.c:917
#define SIZEOFFREE
Definition: define.h:441
#define P_OUT_OF_MAP
Definition: map.h:272
mapstruct * get_map_from_coord(mapstruct *m, sint16 *x, sint16 *y)
Definition: map.c:2366
#define GET_MAP_MOVE_BLOCK(M, X, Y)
Definition: map.h:213
int do_skill(object *op, object *part, object *skill, int dir, const char *string)
Definition: skill_util.c:373
sint8 facing
Definition: object.h:186
sint16 y
Definition: object.h:179
struct pl * contr
Definition: object.h:134
#define WEAPON
Definition: define.h:127
int can_pick(const object *who, const object *item)
Definition: object.c:3569
#define FLAG_SCARED
Definition: define.h:567
#define SP_INVISIBLE
Definition: spells.h:121
#define FLAG_ONLY_ATTACK
Definition: define.h:607
#define FLAG_XRAYS
Definition: define.h:597
void use_trigger(object *op)
Definition: button.c:268
#define ATNR_PHYSICAL
Definition: attack.h:77
void pet_move(object *ob)
Definition: pets.c:348
#define MAX(x, y)
Definition: define.h:70
#define EVENT_SAY
Definition: plugin.h:67
int can_apply_object(object *who, object *op)
Definition: apply.c:955
#define MSG_TYPE_SKILL
Definition: newclient.h:329
#define AT_PHYSICAL
Definition: attack.h:104
float speed
Definition: object.h:181
int on_same_map(const object *op1, const object *op2)
Definition: map.c:2609
#define CAN_APPLY_NOT_MASK
Definition: define.h:1056
#define QUERY_FLAG(xyz, p)
Definition: define.h:514
#define CLEAR_FLAG(xyz, p)
Definition: define.h:512
#define TRIGGER
Definition: define.h:139
#define FLAG_WIZ
Definition: define.h:527
#define GEM
Definition: define.h:202
object * insert_ob_in_ob(object *op, object *where)
Definition: object.c:2510
#define MAX_BUF
Definition: define.h:81
object * find_mon_throw_ob(object *op)
Definition: monster.c:1978
#define SP_SWARM
Definition: spells.h:138
int stand_in_light(object *op)
Definition: monster.c:2159
#define IS_SHIELD(op)
Definition: define.h:456
#define FLAG_CAST_SPELL
Definition: define.h:587
#define FLAG_BERSERK
Definition: define.h:655
static int check_good_armour(object *who, object *item)
Definition: monster.c:1336
#define WAITATT
Definition: define.h:819
static int monster_use_range(object *head, object *part, object *pl, int dir)
Definition: monster.c:1164
#define FLAG_RUN_AWAY
Definition: define.h:576
sint8 wc
Definition: living.h:79
#define ALLRUN
Definition: define.h:821
#define FLAG_IS_THROWN
Definition: define.h:545
#define MIN(x, y)
Definition: define.h:67
void animate_object(object *op, int dir)
Definition: anim.c:186
sint16 resist[NROFATTACKS]
Definition: object.h:192
uint8 darkness
Definition: map.h:369
int has_carried_lights(const object *op)
Definition: los.c:322
static void pace_movev(object *ob)
Definition: monster.c:1736
sint8 body_info[NUM_BODY_LOCATIONS]
Definition: object.h:223
#define MSG_TYPE_DIALOG_MAGIC_MOUTH
Definition: newclient.h:407
int snprintf(char *dest, int max, const char *format,...)
Definition: porting.c:498
void check_doors(object *op, mapstruct *m, int x, int y)
Definition: monster.c:1802
#define RUSH
Definition: define.h:820
#define WAIT2
Definition: define.h:823
#define NUM_STATS
Definition: living.h:48
#define FLAG_GENERATOR
Definition: define.h:544
struct obj * spellitem
Definition: object.h:245
static void pace2_moveh(object *ob)
Definition: monster.c:1767
#define FLAG_BLIND
Definition: define.h:633
#define WILL_APPLY_HANDLE
Definition: object.h:78
sint8 direction
Definition: object.h:185
#define FLAG_NEUTRAL
Definition: define.h:658
struct obj * owner
Definition: object.h:228
sint16 grace
Definition: living.h:85
#define SK_HIDING
Definition: skills.h:49
static int monster_use_bow(object *head, object *part, object *pl, int dir)
Definition: monster.c:1233
tag_t count
Definition: object.h:157
uint16 width
Definition: map.h:370
living stats
Definition: object.h:219
struct archt * arch
Definition: object.h:263
#define MSG_TYPE_COMMUNICATION
Definition: newclient.h:332
#define RANDO2
Definition: define.h:864
uint8 will_apply
Definition: object.h:243
static int monster_move_no_enemy(object *op)
Definition: monster.c:495
unsigned int distance
Definition: map.h:400
#define SKILL
Definition: define.h:157
#define CF_HANDLE
Definition: define.h:275
int isqrt(int n)
Definition: porting.c:573
int should_arena_attack(object *pet, object *owner, object *target)
Definition: pets.c:1146
static object * find_enemy(object *npc, rv_vector *rv)
Definition: monster.c:216
int direction
Definition: map.h:403
static int monster_use_skill(object *head, object *part, object *pl, int dir)
Definition: monster.c:1115
#define SP_MAGIC_MISSILE
Definition: spells.h:113
#define FLAG_APPLIED
Definition: define.h:531
void check_earthwalls(object *op, mapstruct *m, int x, int y)
Definition: monster.c:1791
#define NROFATTACKS
Definition: attack.h:45
int move_object(object *op, int dir)
Definition: move.c:53
int execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
Definition: standalone.c:225
int move_monster(object *op)
Definition: monster.c:566
sint16 SP_level_spellpoint_cost(object *caster, object *spell, int flags)
Definition: spell_util.c:281
#define SIZEOFFREE2
Definition: define.h:440
static int do_talk_npc(object *op, object *npc, const char *txt, int *talked)
Definition: monster.c:1883
#define SP_SUMMON_MONSTER
Definition: spells.h:129
struct struct_dialog_reply * replies
Definition: dialog.h:19
uint16 animation_id
Definition: object.h:267
static void circ1_move(object *ob)
Definition: monster.c:1718
#define BOW
Definition: define.h:126
#define MIN_ACTIVE_SPEED
Definition: define.h:1063
#define GET_MAP_OB(M, X, Y)
Definition: map.h:193
#define DISTATT
Definition: define.h:814
sint8 glow_radius
Definition: object.h:215
#define FLAG_MONSTER
Definition: define.h:541
#define TREASURE
Definition: define.h:116
static void monster_check_pickup(object *monster)
Definition: monster.c:1393
sint8 Pow
Definition: living.h:78
struct obj * inv
Definition: object.h:148
#define NDI_UNIQUE
Definition: newclient.h:219
struct obj * head
Definition: object.h:154
static int monster_cast_spell(object *head, object *part, object *pl, int dir, rv_vector *rv)
Definition: monster.c:957
#define FLAG_READY_BOW
Definition: define.h:596
#define SPELLBOOK
Definition: define.h:266
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:63
#define FLAG_USE_RANGE
Definition: define.h:589
#define FLAG_RANDOM_MOVE
Definition: define.h:606
#define ARROW
Definition: define.h:125
static int dist_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv)
Definition: monster.c:1654
static int check_wakeup(object *op, object *enemy, rv_vector *rv)
Definition: monster.c:298
void make_visible(object *op)
Definition: player.c:3712
#define ROD
Definition: define.h:115
#define SP_MAGIC_WALL
Definition: spells.h:117
uint8 pick_up
Definition: object.h:212
#define was_destroyed(op, old_tag)
Definition: object.h:94
#define PACEH2
Definition: define.h:852
#define IS_ARMOR(op)
Definition: define.h:452
void npc_call_help(object *op)
Definition: monster.c:1632
static void monster_apply_below(object *monster)
Definition: monster.c:1500
int can_see_monsterP(mapstruct *m, int x, int y, int dir)
Definition: object.c:3524
#define PACEV
Definition: define.h:865
#define WILL_APPLY_FOOD
Definition: object.h:82
struct struct_dialog_reply * next
Definition: dialog.h:13
void query_name(const object *op, char *buf, size_t size)
Definition: item.c:628
#define SPELL_MANA
Definition: spells.h:86
static int monster_can_pick(object *monster, object *item)
Definition: monster.c:1420
#define CIRCLE2
Definition: define.h:848
object * find_skill_by_number(object *who, int skillno)
Definition: standalone.c:209
void free_object(object *ob)
Definition: object.c:1238
reply_type type
Definition: dialog.h:12
Definition: map.h:346
#define P_IS_ALIVE
Definition: map.h:258
#define MSG_TYPE_DIALOG_NPC
Definition: newclient.h:405
New_Face * face
Definition: object.h:183
static int wait_att2(int dir, object *ob, object *enemy, object *part, rv_vector *rv)
Definition: monster.c:1712
static int disthit_att(int dir, object *ob, object *enemy, object *part, rv_vector *rv)
Definition: monster.c:1699
sint16 level
Definition: object.h:202
#define SP_SUMMON_GOLEM
Definition: spells.h:114
#define SP_EXPLOSION
Definition: spells.h:108
struct obj * more
Definition: object.h:153
object * find_nearest_living_creature(object *npc)
Definition: monster.c:162
sint8 magic
Definition: object.h:199
void ext_info_map(int color, const mapstruct *map, uint8 type, uint8 subtype, const char *str1, const char *str2)
Definition: standalone.c:184
#define FLAG_USE_BOW
Definition: define.h:590
int hit_player(object *op, int dam, object *hitter, uint32 type, int full_hit)
Definition: attack.c:1868
static void pace_moveh(object *ob)
Definition: monster.c:1745
int cast_spell(object *op, object *caster, int dir, object *spell_ob, char *stringarg)
Definition: spell_util.c:1308
uint8 type
Definition: object.h:189
#define DISTHIT
Definition: define.h:822
#define MAX_KNOWN_SPELLS
Definition: monster.c:900
void communicate(object *op, const char *txt)
Definition: monster.c:1831
struct obj * attacked_by
Definition: object.h:233
int ob_blocked(const object *ob, mapstruct *m, sint16 x, sint16 y)
Definition: map.c:525
sint32 food
Definition: living.h:89
#define FLAG_FREED
Definition: define.h:529
#define LO4
Definition: define.h:875
void follow_owner(object *ob, object *owner)
Definition: pets.c:306
uint32 hide
Definition: object.h:238