1 /**
2 * \file mon-util.c
3 * \brief Monster manipulation utilities.
4 *
5 * Copyright (c) 1997-2007 Ben Harrison, James E. Wilson, Robert A. Koeneke
6 *
7 * This work is free software; you can redistribute it and/or modify it
8 * under the terms of either:
9 *
10 * a) the GNU General Public License as published by the Free Software
11 * Foundation, version 2, or
12 *
13 * b) the "Angband licence":
14 * This software may be copied and distributed for educational, research,
15 * and not for profit purposes provided that this copyright and statement
16 * are included in all such copies. Other copyrights may also apply.
17 */
18
19 #include "angband.h"
20 #include "cmd-core.h"
21 #include "effects.h"
22 #include "game-world.h"
23 #include "init.h"
24 #include "mon-desc.h"
25 #include "mon-list.h"
26 #include "mon-lore.h"
27 #include "mon-make.h"
28 #include "mon-msg.h"
29 #include "mon-predicate.h"
30 #include "mon-spell.h"
31 #include "mon-summon.h"
32 #include "mon-timed.h"
33 #include "mon-util.h"
34 #include "obj-desc.h"
35 #include "obj-gear.h"
36 #include "obj-ignore.h"
37 #include "obj-knowledge.h"
38 #include "obj-pile.h"
39 #include "obj-slays.h"
40 #include "obj-tval.h"
41 #include "obj-util.h"
42 #include "player-calcs.h"
43 #include "player-history.h"
44 #include "player-quest.h"
45 #include "player-timed.h"
46 #include "player-util.h"
47 #include "project.h"
48 #include "trap.h"
49 #include "z-set.h"
50
51 /**
52 * ------------------------------------------------------------------------
53 * Lore utilities
54 * ------------------------------------------------------------------------ */
55 static const struct monster_flag monster_flag_table[] =
56 {
57 #define RF(a, b, c) { RF_##a, b, c },
58 #include "list-mon-race-flags.h"
59 #undef RF
60 {RF_MAX, 0, NULL}
61 };
62
63 /**
64 * Return a description for the given monster race flag.
65 *
66 * Returns an empty string for an out-of-range flag.
67 *
68 * \param flag is one of the RF_ flags.
69 */
describe_race_flag(int flag)70 const char *describe_race_flag(int flag)
71 {
72 const struct monster_flag *rf = &monster_flag_table[flag];
73
74 if (flag <= RF_NONE || flag >= RF_MAX)
75 return "";
76
77 return rf->desc;
78 }
79
80 /**
81 * Create a mask of monster flags of a specific type.
82 *
83 * \param f is the flag array we're filling
84 * \param ... is the list of flags we're looking for
85 *
86 * N.B. RFT_MAX must be the last item in the ... list
87 */
create_mon_flag_mask(bitflag * f,...)88 void create_mon_flag_mask(bitflag *f, ...)
89 {
90 const struct monster_flag *rf;
91 int i;
92 va_list args;
93
94 rf_wipe(f);
95
96 va_start(args, f);
97
98 /* Process each type in the va_args */
99 for (i = va_arg(args, int); i != RFT_MAX; i = va_arg(args, int)) {
100 for (rf = monster_flag_table; rf->index < RF_MAX; rf++)
101 if (rf->type == i)
102 rf_on(f, rf->index);
103 }
104
105 va_end(args);
106
107 return;
108 }
109
110
111 /**
112 * ------------------------------------------------------------------------
113 * Lookup utilities
114 * ------------------------------------------------------------------------ */
115 /**
116 * Returns the monster with the given name. If no monster has the exact name
117 * given, returns the first monster with the given name as a (case-insensitive)
118 * substring.
119 */
lookup_monster(const char * name)120 struct monster_race *lookup_monster(const char *name)
121 {
122 int i;
123 struct monster_race *closest = NULL;
124
125 /* Look for it */
126 for (i = 0; i < z_info->r_max; i++) {
127 struct monster_race *race = &r_info[i];
128 if (!race->name)
129 continue;
130
131 /* Test for equality */
132 if (my_stricmp(name, race->name) == 0)
133 return race;
134
135 /* Test for close matches */
136 if (!closest && my_stristr(race->name, name))
137 closest = race;
138 }
139
140 /* Return our best match */
141 return closest;
142 }
143
144 /**
145 * Return the monster base matching the given name.
146 */
lookup_monster_base(const char * name)147 struct monster_base *lookup_monster_base(const char *name)
148 {
149 struct monster_base *base;
150
151 /* Look for it */
152 for (base = rb_info; base; base = base->next) {
153 if (streq(name, base->name))
154 return base;
155 }
156
157 return NULL;
158 }
159
160 /**
161 * Return whether the given base matches any of the names given.
162 *
163 * Accepts a variable-length list of name strings. The list must end with NULL.
164 *
165 * This function is currently unused, except in a test... -NRM-
166 */
match_monster_bases(const struct monster_base * base,...)167 bool match_monster_bases(const struct monster_base *base, ...)
168 {
169 bool ok = false;
170 va_list vp;
171 char *name;
172
173 va_start(vp, base);
174 while (!ok && ((name = va_arg(vp, char *)) != NULL))
175 ok = base == lookup_monster_base(name);
176 va_end(vp);
177
178 return ok;
179 }
180
181 /**
182 * Returns the monster currently commanded, or NULL
183 */
get_commanded_monster(void)184 struct monster *get_commanded_monster(void)
185 {
186 int i;
187
188 /* Look for it */
189 for (i = 1; i < cave_monster_max(cave); i++) {
190 struct monster *mon = cave_monster(cave, i);
191
192 /* Skip dead monsters */
193 if (!mon->race) continue;
194
195 /* Test for control */
196 if (mon->m_timed[MON_TMD_COMMAND]) return mon;
197 }
198
199 return NULL;
200 }
201
202 /**
203 * ------------------------------------------------------------------------
204 * Monster updates
205 * ------------------------------------------------------------------------ */
206 /**
207 * Analyse the path from player to infravision-seen monster and forget any
208 * grids which would have blocked line of sight
209 */
path_analyse(struct chunk * c,struct loc grid)210 static void path_analyse(struct chunk *c, struct loc grid)
211 {
212 int path_n, i;
213 struct loc path_g[256];
214
215 if (c != cave) {
216 return;
217 }
218
219 /* Plot the path. */
220 path_n = project_path(path_g, z_info->max_range, player->grid, grid,
221 PROJECT_NONE);
222
223 /* Project along the path */
224 for (i = 0; i < path_n - 1; ++i) {
225 /* Forget grids which would block los */
226 if (square_iswall(player->cave, path_g[i])) {
227 sqinfo_off(square(c, path_g[i])->info, SQUARE_SEEN);
228 square_forget(c, path_g[i]);
229 square_light_spot(c, path_g[i]);
230 }
231 }
232 }
233
234 /**
235 * This function updates the monster record of the given monster
236 *
237 * This involves extracting the distance to the player (if requested),
238 * and then checking for visibility (natural, infravision, see-invis,
239 * telepathy), updating the monster visibility flag, redrawing (or
240 * erasing) the monster when its visibility changes, and taking note
241 * of any interesting monster flags (cold-blooded, invisible, etc).
242 *
243 * Note the new "mflag" field which encodes several monster state flags,
244 * including "view" for when the monster is currently in line of sight,
245 * and "mark" for when the monster is currently visible via detection.
246 *
247 * The only monster fields that are changed here are "cdis" (the
248 * distance from the player), "ml" (visible to the player), and
249 * "mflag" (to maintain the "MFLAG_VIEW" flag).
250 *
251 * Note the special "update_monsters()" function which can be used to
252 * call this function once for every monster.
253 *
254 * Note the "full" flag which requests that the "cdis" field be updated;
255 * this is only needed when the monster (or the player) has moved.
256 *
257 * Every time a monster moves, we must call this function for that
258 * monster, and update the distance, and the visibility. Every time
259 * the player moves, we must call this function for every monster, and
260 * update the distance, and the visibility. Whenever the player "state"
261 * changes in certain ways ("blindness", "infravision", "telepathy",
262 * and "see invisible"), we must call this function for every monster,
263 * and update the visibility.
264 *
265 * Routines that change the "illumination" of a grid must also call this
266 * function for any monster in that grid, since the "visibility" of some
267 * monsters may be based on the illumination of their grid.
268 *
269 * Note that this function is called once per monster every time the
270 * player moves. When the player is running, this function is one
271 * of the primary bottlenecks, along with "update_view()" and the
272 * "process_monsters()" code, so efficiency is important.
273 *
274 * Note the optimized "inline" version of the "distance()" function.
275 *
276 * A monster is "visible" to the player if (1) it has been detected
277 * by the player, (2) it is close to the player and the player has
278 * telepathy, or (3) it is close to the player, and in line of sight
279 * of the player, and it is "illuminated" by some combination of
280 * infravision, torch light, or permanent light (invisible monsters
281 * are only affected by "light" if the player can see invisible).
282 *
283 * Monsters which are not on the current panel may be "visible" to
284 * the player, and their descriptions will include an "offscreen"
285 * reference. Currently, offscreen monsters cannot be targeted
286 * or viewed directly, but old targets will remain set. XXX XXX
287 *
288 * The player can choose to be disturbed by several things, including
289 * "OPT(player, disturb_near)" (monster which is "easily" viewable moves in some
290 * way). Note that "moves" includes "appears" and "disappears".
291 */
update_mon(struct monster * mon,struct chunk * c,bool full)292 void update_mon(struct monster *mon, struct chunk *c, bool full)
293 {
294 struct monster_lore *lore;
295
296 int d;
297
298 /* If still generating the level, measure distances from the middle */
299 struct loc pgrid = character_dungeon ? player->grid :
300 loc(c->width / 2, c->height / 2);
301
302 /* Seen at all */
303 bool flag = false;
304
305 /* Seen by vision */
306 bool easy = false;
307
308 /* ESP permitted */
309 bool telepathy_ok = player_of_has(player, OF_TELEPATHY);
310
311 assert(mon != NULL);
312
313 /* Return if this is not the current level */
314 if (c != cave) {
315 return;
316 }
317
318 lore = get_lore(mon->race);
319
320 /* Compute distance, or just use the current one */
321 if (full) {
322 /* Distance components */
323 int dy = ABS(pgrid.y - mon->grid.y);
324 int dx = ABS(pgrid.x - mon->grid.x);
325
326 /* Approximate distance */
327 d = (dy > dx) ? (dy + (dx >> 1)) : (dx + (dy >> 1));
328
329 /* Restrict distance */
330 if (d > 255) d = 255;
331
332 /* Save the distance */
333 mon->cdis = d;
334 } else {
335 /* Extract the distance */
336 d = mon->cdis;
337 }
338
339 /* Detected */
340 if (mflag_has(mon->mflag, MFLAG_MARK)) flag = true;
341
342 /* Check if telepathy works here */
343 if (square_isno_esp(c, mon->grid) || square_isno_esp(c, pgrid)) {
344 telepathy_ok = false;
345 }
346
347 /* Nearby */
348 if (d <= z_info->max_sight) {
349 /* Basic telepathy */
350 if (telepathy_ok && monster_is_esp_detectable(mon)) {
351 /* Detectable */
352 flag = true;
353
354 /* Check for LOS so that MFLAG_VIEW is set later */
355 if (square_isview(c, mon->grid)) easy = true;
356 }
357
358 /* Normal line of sight and player is not blind */
359 if (square_isview(c, mon->grid) && !player->timed[TMD_BLIND]) {
360 /* Use "infravision" */
361 if (d <= player->state.see_infra) {
362 /* Learn about warm/cold blood */
363 rf_on(lore->flags, RF_COLD_BLOOD);
364
365 /* Handle "warm blooded" monsters */
366 if (!rf_has(mon->race->flags, RF_COLD_BLOOD)) {
367 /* Easy to see */
368 easy = flag = true;
369 }
370 }
371
372 /* Use illumination */
373 if (square_isseen(c, mon->grid)) {
374 /* Learn about invisibility */
375 rf_on(lore->flags, RF_INVISIBLE);
376
377 /* Handle invisibility */
378 if (monster_is_invisible(mon)) {
379 /* See invisible */
380 if (player_of_has(player, OF_SEE_INVIS)) {
381 /* Easy to see */
382 easy = flag = true;
383 }
384 } else {
385 /* Easy to see */
386 easy = flag = true;
387 }
388 }
389
390 /* Learn about intervening squares */
391 path_analyse(c, mon->grid);
392 }
393 }
394
395 /* If a mimic looks like an ignored item, it's not seen */
396 if (monster_is_mimicking(mon)) {
397 struct object *obj = mon->mimicked_obj;
398 if (ignore_item_ok(obj))
399 easy = flag = false;
400 }
401
402 /* Is the monster is now visible? */
403 if (flag) {
404 /* Learn about the monster's mind */
405 if (telepathy_ok) {
406 flags_set(lore->flags, RF_SIZE, RF_EMPTY_MIND, RF_WEIRD_MIND,
407 RF_SMART, RF_STUPID, FLAG_END);
408 }
409
410 /* It was previously unseen */
411 if (!monster_is_visible(mon)) {
412 /* Mark as visible */
413 mflag_on(mon->mflag, MFLAG_VISIBLE);
414
415 /* Draw the monster */
416 square_light_spot(c, mon->grid);
417
418 /* Update health bar as needed */
419 if (player->upkeep->health_who == mon)
420 player->upkeep->redraw |= (PR_HEALTH);
421
422 /* Hack -- Count "fresh" sightings */
423 if (lore->sights < SHRT_MAX)
424 lore->sights++;
425
426 /* Window stuff */
427 player->upkeep->redraw |= PR_MONLIST;
428 }
429 } else if (monster_is_visible(mon)) {
430 /* Not visible but was previously seen - treat mimics differently */
431 if (!mon->mimicked_obj || ignore_item_ok(mon->mimicked_obj)) {
432 /* Mark as not visible */
433 mflag_off(mon->mflag, MFLAG_VISIBLE);
434
435 /* Erase the monster */
436 square_light_spot(c, mon->grid);
437
438 /* Update health bar as needed */
439 if (player->upkeep->health_who == mon)
440 player->upkeep->redraw |= (PR_HEALTH);
441
442 /* Window stuff */
443 player->upkeep->redraw |= PR_MONLIST;
444 }
445 }
446
447
448 /* Is the monster is now easily visible? */
449 if (easy) {
450 /* Change */
451 if (!monster_is_in_view(mon)) {
452 /* Mark as easily visible */
453 mflag_on(mon->mflag, MFLAG_VIEW);
454
455 /* Disturb on appearance */
456 if (OPT(player, disturb_near))
457 disturb(player);
458
459 /* Re-draw monster window */
460 player->upkeep->redraw |= PR_MONLIST;
461 }
462 } else {
463 /* Change */
464 if (monster_is_in_view(mon)) {
465 /* Mark as not easily visible */
466 mflag_off(mon->mflag, MFLAG_VIEW);
467
468 /* Disturb on disappearance */
469 if (OPT(player, disturb_near) && !monster_is_mimicking(mon))
470 disturb(player);
471
472 /* Re-draw monster list window */
473 player->upkeep->redraw |= PR_MONLIST;
474 }
475 }
476 }
477
478 /**
479 * Updates all the (non-dead) monsters via update_mon().
480 */
update_monsters(bool full)481 void update_monsters(bool full)
482 {
483 int i;
484
485 /* Update each (live) monster */
486 for (i = 1; i < cave_monster_max(cave); i++) {
487 struct monster *mon = cave_monster(cave, i);
488
489 /* Update the monster if alive */
490 if (mon->race)
491 update_mon(mon, cave, full);
492 }
493 }
494
495
496 /**
497 * ------------------------------------------------------------------------
498 * Monster (and player) actual movement
499 * ------------------------------------------------------------------------ */
500 /**
501 * Called when the player has just left grid1 for grid2.
502 */
player_leaving(struct loc grid1,struct loc grid2)503 static void player_leaving(struct loc grid1, struct loc grid2)
504 {
505 struct loc decoy = cave_find_decoy(cave);
506
507 /* Decoys get destroyed if player is too far away */
508 if (!loc_is_zero(decoy) &&
509 distance(decoy, grid2) > z_info->max_sight) {
510 square_destroy_decoy(cave, decoy);
511 }
512
513 /* Delayed traps trigger when the player leaves. */
514 hit_trap(grid1, 1);
515 }
516
517 /**
518 * Is a helper function to move a mimicked object when the mimic (not known
519 * to the player) is moved. Assumes that the caller will be calling
520 * square_light_spot() for the source grid.
521 */
move_mimicked_object(struct chunk * c,struct monster * mon,struct loc src,struct loc dest)522 static void move_mimicked_object(struct chunk *c, struct monster *mon,
523 struct loc src, struct loc dest)
524 {
525 struct object *mimicked = mon->mimicked_obj;
526 /*
527 * Move a copy so, if necessary, the original can remain as a
528 * placeholder for the known version of the object in the player's
529 * view of the cave.
530 */
531 struct object *moved = object_new();
532 bool dummy = true;
533
534 assert(mimicked);
535 object_copy(moved, mimicked);
536 moved->oidx = 0;
537 mimicked->mimicking_m_idx = 0;
538 if (mimicked->known) {
539 moved->known = object_new();
540 object_copy(moved->known, mimicked->known);
541 moved->known->oidx = 0;
542 moved->known->grid = loc(0,0);
543 }
544 if (floor_carry(c, dest, moved, &dummy)) {
545 mon->mimicked_obj = moved;
546 } else {
547 /* Could not move the object so cancel mimicry. */
548 moved->mimicking_m_idx = 0;
549 mon->mimicked_obj = NULL;
550 /* Give object to monster if appropriate; otherwise, delete. */
551 if (! rf_has(mon->race->flags, RF_MIMIC_INV) ||
552 ! monster_carry(c, mon, moved)) {
553 if (moved->known) {
554 object_delete(&moved->known);
555 }
556 object_delete(&moved);
557 }
558 }
559 square_delete_object(c, src, mimicked, true, false);
560 }
561
562 /**
563 * Swap the players/monsters (if any) at two locations.
564 */
monster_swap(struct loc grid1,struct loc grid2)565 void monster_swap(struct loc grid1, struct loc grid2)
566 {
567 int m1, m2;
568 struct monster *mon;
569 struct loc pgrid = player->grid;
570
571 /* Monsters */
572 m1 = cave->squares[grid1.y][grid1.x].mon;
573 m2 = cave->squares[grid2.y][grid2.x].mon;
574
575 /* Update grids */
576 square_set_mon(cave, grid1, m2);
577 square_set_mon(cave, grid2, m1);
578
579 /* Monster 1 */
580 if (m1 > 0) {
581 /* Monster */
582 mon = cave_monster(cave, m1);
583
584 /* Update monster */
585 if (monster_is_mimicking(mon)) {
586 /*
587 * Become aware if the player can see the mimic before
588 * or after the swap.
589 */
590 if (monster_is_in_view(mon) ||
591 (m2 >= 0 && los(cave, pgrid, grid2)) ||
592 (m2 < 0 && los(cave, grid1, grid2))) {
593 become_aware(mon);
594 } else {
595 move_mimicked_object(cave, mon, grid1, grid2);
596 player->upkeep->redraw |= (PR_ITEMLIST);
597 }
598 }
599 mon->grid = grid2;
600 update_mon(mon, cave, true);
601
602 /* Affect light? */
603 if (mon->race->light != 0)
604 player->upkeep->update |= PU_UPDATE_VIEW;
605
606 /* Redraw monster list */
607 player->upkeep->redraw |= (PR_MONLIST);
608 } else if (m1 < 0) {
609 /* Player */
610 player->grid = grid2;
611 player_leaving(pgrid, player->grid);
612
613 /* Update the trap detection status */
614 player->upkeep->redraw |= (PR_DTRAP);
615
616 /* Updates */
617 player->upkeep->update |= (PU_PANEL | PU_UPDATE_VIEW | PU_DISTANCE);
618
619 /* Redraw monster list */
620 player->upkeep->redraw |= (PR_MONLIST);
621
622 /* Don't allow command repeat if moved away from item used. */
623 if (cmdq_does_previous_use_floor_item()) {
624 cmd_disable_repeat();
625 }
626 }
627
628 /* Monster 2 */
629 if (m2 > 0) {
630 /* Monster */
631 mon = cave_monster(cave, m2);
632
633 /* Update monster */
634 if (monster_is_mimicking(mon)) {
635 /*
636 * Become aware if the player can see the mimic before
637 * or after the swap.
638 */
639 if (monster_is_in_view(mon) ||
640 (m1 >= 0 && los(cave, pgrid, grid1)) ||
641 (m1 < 0 && los(cave, grid2, grid1))) {
642 become_aware(mon);
643 } else {
644 move_mimicked_object(cave, mon, grid2, grid1);
645 player->upkeep->redraw |= (PR_ITEMLIST);
646 }
647 }
648 mon->grid = grid1;
649 update_mon(mon, cave, true);
650
651 /* Affect light? */
652 if (mon->race->light != 0)
653 player->upkeep->update |= PU_UPDATE_VIEW;
654
655 /* Redraw monster list */
656 player->upkeep->redraw |= (PR_MONLIST);
657 } else if (m2 < 0) {
658 /* Player */
659 player->grid = grid1;
660 player_leaving(pgrid, player->grid);
661
662 /* Update the trap detection status */
663 player->upkeep->redraw |= (PR_DTRAP);
664
665 /* Updates */
666 player->upkeep->update |= (PU_PANEL | PU_UPDATE_VIEW | PU_DISTANCE);
667
668 /* Redraw monster list */
669 player->upkeep->redraw |= (PR_MONLIST);
670
671 /* Don't allow command repeat if moved away from item used. */
672 if (cmdq_does_previous_use_floor_item()) {
673 cmd_disable_repeat();
674 }
675 }
676
677 /* Redraw */
678 square_light_spot(cave, grid1);
679 square_light_spot(cave, grid2);
680 }
681
682 /**
683 * ------------------------------------------------------------------------
684 * Awareness and learning
685 * ------------------------------------------------------------------------ */
686 /**
687 * Monster wakes up and possibly becomes aware of the player
688 */
monster_wake(struct monster * mon,bool notify,int aware_chance)689 void monster_wake(struct monster *mon, bool notify, int aware_chance)
690 {
691 int flag = notify ? MON_TMD_FLG_NOTIFY : MON_TMD_FLG_NOMESSAGE;
692 mon_clear_timed(mon, MON_TMD_SLEEP, flag);
693 if (randint0(100) < aware_chance) {
694 mflag_on(mon->mflag, MFLAG_AWARE);
695 }
696 }
697
698 /**
699 * Monster can see a grid
700 */
monster_can_see(struct chunk * c,struct monster * mon,struct loc grid)701 bool monster_can_see(struct chunk *c, struct monster *mon, struct loc grid)
702 {
703 return los(c, mon->grid, grid);
704 }
705
706 /**
707 * Make player fully aware of the given mimic.
708 *
709 * When a player becomes aware of a mimic, we update the monster memory
710 * and delete the "fake item" that the monster was mimicking.
711 */
become_aware(struct monster * mon)712 void become_aware(struct monster *mon)
713 {
714 struct monster_lore *lore = get_lore(mon->race);
715
716 if (mflag_has(mon->mflag, MFLAG_CAMOUFLAGE)) {
717 mflag_off(mon->mflag, MFLAG_CAMOUFLAGE);
718
719 /* Learn about mimicry */
720 if (rf_has(mon->race->flags, RF_UNAWARE))
721 rf_on(lore->flags, RF_UNAWARE);
722
723 /* Delete any false items */
724 if (mon->mimicked_obj) {
725 struct object *obj = mon->mimicked_obj;
726 char o_name[80];
727 object_desc(o_name, sizeof(o_name), obj, ODESC_BASE);
728
729 /* Print a message */
730 if (square_isseen(cave, obj->grid))
731 msg("The %s was really a monster!", o_name);
732
733 /* Clear the mimicry */
734 obj->mimicking_m_idx = 0;
735 mon->mimicked_obj = NULL;
736
737 /*
738 * Give a copy of the object to the monster if
739 * appropriate.
740 */
741 if (rf_has(mon->race->flags, RF_MIMIC_INV)) {
742 struct object* given = object_new();
743
744 object_copy(given, obj);
745 given->oidx = 0;
746 if (obj->known) {
747 given->known = object_new();
748 object_copy(given->known, obj->known);
749 given->known->oidx = 0;
750 given->known->grid = loc(0, 0);
751 }
752 if (! monster_carry(cave, mon, given)) {
753 if (given->known) {
754 object_delete(&given->known);
755 }
756 object_delete(&given);
757 }
758 }
759
760 /*
761 * Delete the mimicked object; noting and lighting
762 * done below outside of the if block.
763 */
764 square_delete_object(cave, obj->grid, obj, false, false);
765 }
766
767 /* Update monster and item lists */
768 player->upkeep->update |= (PU_UPDATE_VIEW | PU_MONSTERS);
769 player->upkeep->redraw |= (PR_MONLIST | PR_ITEMLIST);
770 }
771
772 square_note_spot(cave, mon->grid);
773 square_light_spot(cave, mon->grid);
774 }
775
776 /**
777 * The given monster learns about an "observed" resistance or other player
778 * state property, or lack of it.
779 *
780 * Note that this function is robust to being called with `element` as an
781 * arbitrary PROJ_ type
782 */
update_smart_learn(struct monster * mon,struct player * p,int flag,int pflag,int element)783 void update_smart_learn(struct monster *mon, struct player *p, int flag,
784 int pflag, int element)
785 {
786 bool element_ok = ((element >= 0) && (element < ELEM_MAX));
787
788 /* Sanity check */
789 if (!flag && !element_ok) return;
790
791 /* Anything a monster might learn, the player should learn */
792 if (flag) equip_learn_flag(p, flag);
793 if (element_ok) equip_learn_element(p, element);
794
795 /* Not allowed to learn */
796 if (!OPT(p, birth_ai_learn)) return;
797
798 /* Too stupid to learn anything */
799 if (monster_is_stupid(mon)) return;
800
801 /* Not intelligent, only learn sometimes */
802 if (!monster_is_smart(mon) && one_in_(2)) return;
803
804 /* Analyze the knowledge; fail very rarely */
805 if (one_in_(100))
806 return;
807
808 /* Learn the flag */
809 if (flag) {
810 if (player_of_has(p, flag)) {
811 of_on(mon->known_pstate.flags, flag);
812 } else {
813 of_off(mon->known_pstate.flags, flag);
814 }
815 }
816
817 /* Learn the pflag */
818 if (pflag) {
819 if (pf_has(p->state.pflags, pflag)) {
820 of_on(mon->known_pstate.pflags, pflag);
821 } else {
822 of_off(mon->known_pstate.pflags, pflag);
823 }
824 }
825
826 /* Learn the element */
827 if (element_ok)
828 mon->known_pstate.el_info[element].res_level
829 = p->state.el_info[element].res_level;
830 }
831
832 /**
833 * ------------------------------------------------------------------------
834 * Monster healing
835 * ------------------------------------------------------------------------ */
836 #define MAX_KIN_RADIUS 5
837 #define MAX_KIN_DISTANCE 5
838
839 /**
840 * Given a dungeon chunk, a monster, and a location, see if there is
841 * an injured monster with the same base kind in LOS and less than
842 * MAX_KIN_DISTANCE away.
843 */
get_injured_kin(struct chunk * c,const struct monster * mon,struct loc grid)844 static struct monster *get_injured_kin(struct chunk *c,
845 const struct monster *mon,
846 struct loc grid)
847 {
848 /* Ignore the monster itself */
849 if (loc_eq(grid, mon->grid))
850 return NULL;
851
852 /* Check kin */
853 struct monster *kin = square_monster(c, grid);
854 if (!kin)
855 return NULL;
856
857 if (kin->race->base != mon->race->base)
858 return NULL;
859
860 /* Check line of sight */
861 if (los(c, mon->grid, grid) == false)
862 return NULL;
863
864 /* Check injury */
865 if (kin->hp == kin->maxhp)
866 return NULL;
867
868 /* Check distance */
869 if (distance(mon->grid, grid) > MAX_KIN_DISTANCE)
870 return NULL;
871
872 return kin;
873 }
874
875 /**
876 * Find out if there are any injured monsters nearby.
877 *
878 * See get_injured_kin() above for more details on what monsters qualify.
879 */
find_any_nearby_injured_kin(struct chunk * c,const struct monster * mon)880 bool find_any_nearby_injured_kin(struct chunk *c, const struct monster *mon)
881 {
882 struct loc grid;
883 for (grid.y = mon->grid.y - MAX_KIN_RADIUS;
884 grid.y <= mon->grid.y + MAX_KIN_RADIUS; grid.y++) {
885 for (grid.x = mon->grid.x - MAX_KIN_RADIUS;
886 grid.x <= mon->grid.x + MAX_KIN_RADIUS; grid.x++) {
887 if (get_injured_kin(c, mon, grid) != NULL) {
888 return true;
889 }
890 }
891 }
892
893 return false;
894 }
895
896 /**
897 * Choose one injured monster of the same base in LOS of the provided monster.
898 *
899 * Scan MAX_KIN_RADIUS grids around the monster to find potential grids,
900 * make a list of kin, and choose a random one.
901 */
choose_nearby_injured_kin(struct chunk * c,const struct monster * mon)902 struct monster *choose_nearby_injured_kin(struct chunk *c,
903 const struct monster *mon)
904 {
905 struct set *set = set_new();
906 struct loc grid;
907
908 for (grid.y = mon->grid.y - MAX_KIN_RADIUS;
909 grid.y <= mon->grid.y + MAX_KIN_RADIUS; grid.y++) {
910 for (grid.x = mon->grid.x - MAX_KIN_RADIUS;
911 grid.x <= mon->grid.x + MAX_KIN_RADIUS; grid.x++) {
912 struct monster *kin = get_injured_kin(c, mon, grid);
913 if (kin != NULL) {
914 set_add(set, kin);
915 }
916 }
917 }
918
919 struct monster *found = set_choose(set);
920 set_free(set);
921
922 return found;
923 }
924
925
926 /**
927 * ------------------------------------------------------------------------
928 * Monster damage and death utilities
929 * ------------------------------------------------------------------------ */
930 /**
931 * Handles the "death" of a monster.
932 *
933 * Disperses treasures carried by the monster centered at the monster location.
934 * Note that objects dropped may disappear in crowded rooms.
935 *
936 * Checks for "Quest" completion when a quest monster is killed.
937 *
938 * Note that only the player can induce "monster_death()" on Uniques.
939 * Thus (for now) all Quest monsters should be Uniques.
940 *
941 * If `stats` is true, then we skip updating the monster memory. This is
942 * used by stats-generation code, for efficiency.
943 */
monster_death(struct monster * mon,bool stats)944 void monster_death(struct monster *mon, bool stats)
945 {
946 int dump_item = 0;
947 int dump_gold = 0;
948 struct object *obj = mon->held_obj;
949
950 bool visible = monster_is_visible(mon) || monster_is_unique(mon);
951
952 /* Delete any mimicked objects */
953 if (mon->mimicked_obj) {
954 square_delete_object(cave, mon->grid, mon->mimicked_obj, true, true);
955 mon->mimicked_obj = NULL;
956 }
957
958 /* Drop objects being carried */
959 while (obj) {
960 struct object *next = obj->next;
961
962 /* Object no longer held */
963 obj->held_m_idx = 0;
964 pile_excise(&mon->held_obj, obj);
965
966 /* Count it and drop it - refactor once origin is a bitflag */
967 if (!stats) {
968 if (tval_is_money(obj) && (obj->origin != ORIGIN_STOLEN))
969 dump_gold++;
970 else if (!tval_is_money(obj) && ((obj->origin == ORIGIN_DROP)
971 || (obj->origin == ORIGIN_DROP_PIT)
972 || (obj->origin == ORIGIN_DROP_VAULT)
973 || (obj->origin == ORIGIN_DROP_SUMMON)
974 || (obj->origin == ORIGIN_DROP_SPECIAL)
975 || (obj->origin == ORIGIN_DROP_BREED)
976 || (obj->origin == ORIGIN_DROP_POLY)
977 || (obj->origin == ORIGIN_DROP_WIZARD)))
978 dump_item++;
979 }
980
981 /* Change origin if monster is invisible, unless we're in stats mode */
982 if (!visible && !stats)
983 obj->origin = ORIGIN_DROP_UNKNOWN;
984
985 drop_near(cave, &obj, 0, mon->grid, true, false);
986 obj = next;
987 }
988
989 /* Forget objects */
990 mon->held_obj = NULL;
991
992 /* Take note of any dropped treasure */
993 if (visible && (dump_item || dump_gold))
994 lore_treasure(mon, dump_item, dump_gold);
995
996 /* Update monster list window */
997 player->upkeep->redraw |= PR_MONLIST;
998
999 /* Affect light? */
1000 if (mon->race->light != 0)
1001 player->upkeep->update |= PU_UPDATE_VIEW;
1002
1003 /* Check if we finished a quest */
1004 quest_check(mon);
1005 }
1006
1007 /**
1008 * Handle the consequences of the killing of a monster by the player
1009 */
player_kill_monster(struct monster * mon,const char * note)1010 static void player_kill_monster(struct monster *mon, const char *note)
1011 {
1012 s32b div, new_exp, new_exp_frac;
1013 struct monster_lore *lore = get_lore(mon->race);
1014 char m_name[80];
1015 char buf[80];
1016
1017 /* Assume normal death sound */
1018 int soundfx = MSG_KILL;
1019
1020 /* Extract monster name */
1021 monster_desc(m_name, sizeof(m_name), mon, MDESC_DEFAULT);
1022
1023 /* Shapechanged monsters revert on death */
1024 if (mon->original_race) {
1025 monster_revert_shape(mon);
1026 lore = get_lore(mon->race);
1027 monster_desc(m_name, sizeof(m_name), mon, MDESC_DEFAULT);
1028 }
1029
1030 /* Play a special sound if the monster was unique */
1031 if (rf_has(mon->race->flags, RF_UNIQUE)) {
1032 if (mon->race->base == lookup_monster_base("Morgoth"))
1033 soundfx = MSG_KILL_KING;
1034 else
1035 soundfx = MSG_KILL_UNIQUE;
1036 }
1037
1038 /* Death message */
1039 if (note) {
1040 if (strlen(note) <= 1) {
1041 /* Death by Spell attack - messages handled by project_m() */
1042 } else {
1043 char *str = format("%s%s", m_name, note);
1044 my_strcap(str);
1045
1046 /* Make sure to flush any monster messages first */
1047 notice_stuff(player);
1048
1049 /* Death by Missile attack */
1050 msgt(soundfx, "%s", str);
1051 }
1052 } else {
1053 /* Make sure to flush any monster messages first */
1054 notice_stuff(player);
1055
1056 if (!monster_is_visible(mon))
1057 /* Death by physical attack -- invisible monster */
1058 msgt(soundfx, "You have killed %s.", m_name);
1059 else if (monster_is_destroyed(mon))
1060 /* Death by Physical attack -- non-living monster */
1061 msgt(soundfx, "You have destroyed %s.", m_name);
1062 else
1063 /* Death by Physical attack -- living monster */
1064 msgt(soundfx, "You have slain %s.", m_name);
1065 }
1066
1067 /* Player level */
1068 div = player->lev;
1069
1070 /* Give some experience for the kill */
1071 new_exp = ((long)mon->race->mexp * mon->race->level) / div;
1072
1073 /* Handle fractional experience */
1074 new_exp_frac = ((((long)mon->race->mexp * mon->race->level) % div)
1075 * 0x10000L / div) + player->exp_frac;
1076
1077 /* Keep track of experience */
1078 if (new_exp_frac >= 0x10000L) {
1079 new_exp++;
1080 player->exp_frac = (u16b)(new_exp_frac - 0x10000L);
1081 } else {
1082 player->exp_frac = (u16b)new_exp_frac;
1083 }
1084
1085 /* When the player kills a Unique, it stays dead */
1086 if (rf_has(mon->race->flags, RF_UNIQUE)) {
1087 char unique_name[80];
1088 assert(mon->original_race == NULL);
1089 mon->race->max_num = 0;
1090
1091 /*
1092 * This gets the correct name if we slay an invisible
1093 * unique and don't have See Invisible.
1094 */
1095 monster_desc(unique_name, sizeof(unique_name), mon,
1096 MDESC_DIED_FROM);
1097
1098 /* Log the slaying of a unique */
1099 strnfmt(buf, sizeof(buf), "Killed %s", unique_name);
1100 history_add(player, buf, HIST_SLAY_UNIQUE);
1101 }
1102
1103 /* Gain experience */
1104 player_exp_gain(player, new_exp);
1105
1106 /* Generate treasure */
1107 monster_death(mon, false);
1108
1109 /* Bloodlust bonus */
1110 if (player->timed[TMD_BLOODLUST]) {
1111 player_inc_timed(player, TMD_BLOODLUST, 10, false, false);
1112 player_over_exert(player, PY_EXERT_CONF, 5, 3);
1113 player_over_exert(player, PY_EXERT_HALLU, 5, 10);
1114 }
1115
1116 /* Recall even invisible uniques or winners */
1117 if (monster_is_visible(mon) || monster_is_unique(mon)) {
1118 /* Count kills this life */
1119 if (lore->pkills < SHRT_MAX) lore->pkills++;
1120
1121 /* Count kills in all lives */
1122 if (lore->tkills < SHRT_MAX) lore->tkills++;
1123
1124 /* Update lore and tracking */
1125 lore_update(mon->race, lore);
1126 monster_race_track(player->upkeep, mon->race);
1127 }
1128
1129 /* Delete the monster */
1130 delete_monster_idx(mon->midx);
1131 }
1132
1133 /**
1134 * See how a monster reacts to damage
1135 */
monster_scared_by_damage(struct monster * mon,int dam)1136 static bool monster_scared_by_damage(struct monster *mon, int dam)
1137 {
1138 int current_fear = mon->m_timed[MON_TMD_FEAR];
1139
1140 /* Pain can reduce or cancel existing fear, or cause fear */
1141 if (current_fear) {
1142 int tmp = randint1(dam);
1143
1144 /* Cure a little or all fear */
1145 if (tmp < current_fear) {
1146 /* Reduce fear */
1147 mon_dec_timed(mon, MON_TMD_FEAR, tmp, MON_TMD_FLG_NOMESSAGE);
1148 } else {
1149 /* Cure fear */
1150 mon_clear_timed(mon, MON_TMD_FEAR, MON_TMD_FLG_NOMESSAGE);
1151 return false;
1152 }
1153 } else if (monster_can_be_scared(mon)) {
1154 /* Percentage of fully healthy */
1155 int percentage = (100L * mon->hp) / mon->maxhp;
1156
1157 /* Run (sometimes) if at 10% or less of max hit points... */
1158 bool low_hp = randint1(10) >= percentage;
1159
1160 /* ...or (usually) when hit for half its current hit points */
1161 bool big_hit = (dam >= mon->hp) && (randint0(100) < 80);
1162
1163 if (low_hp || big_hit) {
1164 int time = randint1(10);
1165 if ((dam >= mon->hp) && (percentage > 7)) {
1166 time += 20;
1167 } else {
1168 time += (11 - percentage) * 5;
1169 }
1170
1171 /* Note fear */
1172 mon_inc_timed(mon, MON_TMD_FEAR, time,
1173 MON_TMD_FLG_NOMESSAGE | MON_TMD_FLG_NOFAIL);
1174 return true;
1175 }
1176 }
1177 return false;
1178 }
1179
1180 /**
1181 * Deal damage to a monster from another monster (or at least not the player).
1182 *
1183 * This is a helper for melee handlers. It is very similar to mon_take_hit(),
1184 * but eliminates the player-oriented stuff of that function.
1185 *
1186 * \param context is the project_m context.
1187 * \param hurt_msg is the message if the monster is hurt (if any).
1188 * \return true if the monster died, false if it is still alive.
1189 */
mon_take_nonplayer_hit(int dam,struct monster * t_mon,enum mon_messages hurt_msg,enum mon_messages die_msg)1190 bool mon_take_nonplayer_hit(int dam, struct monster *t_mon,
1191 enum mon_messages hurt_msg,
1192 enum mon_messages die_msg)
1193 {
1194 assert(t_mon);
1195
1196 /* "Unique" monsters can only be "killed" by the player */
1197 if (rf_has(t_mon->race->flags, RF_UNIQUE)) {
1198 /* Reduce monster hp to zero, but don't kill it. */
1199 if (dam > t_mon->hp) dam = t_mon->hp;
1200 }
1201
1202 /* Redraw (later) if needed */
1203 if (player->upkeep->health_who == t_mon)
1204 player->upkeep->redraw |= (PR_HEALTH);
1205
1206 /* Wake the monster up, doesn't become aware of the player */
1207 monster_wake(t_mon, false, 0);
1208
1209 /* Hurt the monster */
1210 t_mon->hp -= dam;
1211
1212 /* Dead or damaged monster */
1213 if (t_mon->hp < 0) {
1214 /* Death message */
1215 add_monster_message(t_mon, die_msg, false);
1216
1217 /* Generate treasure, etc */
1218 monster_death(t_mon, false);
1219
1220 /* Delete the monster */
1221 delete_monster_idx(t_mon->midx);
1222 return true;
1223 } else if (!monster_is_mimicking(t_mon)) {
1224 /* Give detailed messages if visible */
1225 if (hurt_msg != MON_MSG_NONE) {
1226 add_monster_message(t_mon, hurt_msg, false);
1227 } else if (dam > 0) {
1228 message_pain(t_mon, dam);
1229 }
1230 }
1231
1232 /* Sometimes a monster gets scared by damage */
1233 if (!t_mon->m_timed[MON_TMD_FEAR] && dam > 0) {
1234 (void) monster_scared_by_damage(t_mon, dam);
1235 }
1236
1237 return false;
1238 }
1239
1240 /**
1241 * Decreases a monster's hit points by `dam` and handle monster death.
1242 *
1243 * Hack -- we "delay" fear messages by passing around a "fear" flag.
1244 *
1245 * We announce monster death (using an optional "death message" (`note`)
1246 * if given, and a otherwise a generic killed/destroyed message).
1247 *
1248 * Returns true if the monster has been killed (and deleted).
1249 *
1250 * TODO: Consider decreasing monster experience over time, say, by using
1251 * "(m_exp * m_lev * (m_lev)) / (p_lev * (m_lev + n_killed))" instead
1252 * of simply "(m_exp * m_lev) / (p_lev)", to make the first monster
1253 * worth more than subsequent monsters. This would also need to
1254 * induce changes in the monster recall code. XXX XXX XXX
1255 **/
mon_take_hit(struct monster * mon,int dam,bool * fear,const char * note)1256 bool mon_take_hit(struct monster *mon, int dam, bool *fear, const char *note)
1257 {
1258 /* Redraw (later) if needed */
1259 if (player->upkeep->health_who == mon)
1260 player->upkeep->redraw |= (PR_HEALTH);
1261
1262 /* Wake it up, make it aware of the player */
1263 monster_wake(mon, false, 100);
1264 mon_clear_timed(mon, MON_TMD_HOLD, MON_TMD_FLG_NOTIFY);
1265
1266 /* Become aware of its presence */
1267 if (monster_is_camouflaged(mon))
1268 become_aware(mon);
1269
1270 /* No damage, we're done */
1271 if (dam == 0) return false;
1272
1273 /* Covering tracks is no longer possible */
1274 player->timed[TMD_COVERTRACKS] = 0;
1275
1276 /* Hurt it */
1277 mon->hp -= dam;
1278 if (mon->hp < 0) {
1279 /* Deal with arena monsters */
1280 if (player->upkeep->arena_level) {
1281 player->upkeep->generate_level = true;
1282 player->upkeep->health_who = mon;
1283 (*fear) = false;
1284 return true;
1285 }
1286
1287 /* It is dead now */
1288 player_kill_monster(mon, note);
1289
1290 /* Not afraid */
1291 (*fear) = false;
1292
1293 /* Monster is dead */
1294 return true;
1295 } else {
1296 /* Did it get frightened? */
1297 (*fear) = monster_scared_by_damage(mon, dam);
1298
1299 /* Not dead yet */
1300 return false;
1301 }
1302 }
1303
kill_arena_monster(struct monster * mon)1304 void kill_arena_monster(struct monster *mon)
1305 {
1306 struct monster *old_mon = cave_monster(cave, mon->midx);
1307 assert(old_mon);
1308 update_mon(old_mon, cave, true);
1309 old_mon->hp = -1;
1310 player_kill_monster(old_mon, " is defeated!");
1311 }
1312
1313 /**
1314 * Terrain damages monster
1315 */
monster_take_terrain_damage(struct monster * mon)1316 void monster_take_terrain_damage(struct monster *mon)
1317 {
1318 /* Damage the monster */
1319 if (square_isfiery(cave, mon->grid)) {
1320 bool fear = false;
1321
1322 if (!rf_has(mon->race->flags, RF_IM_FIRE)) {
1323 mon_take_nonplayer_hit(100 + randint1(100), mon, MON_MSG_CATCH_FIRE,
1324 MON_MSG_DISINTEGRATES);
1325 }
1326
1327 if (fear && monster_is_visible(mon)) {
1328 add_monster_message(mon, MON_MSG_FLEE_IN_TERROR, true);
1329 }
1330 }
1331 }
1332
1333 /**
1334 * Terrain is currently damaging monster
1335 */
monster_taking_terrain_damage(struct monster * mon)1336 bool monster_taking_terrain_damage(struct monster *mon)
1337 {
1338 if (square_isdamaging(cave, mon->grid) &&
1339 !rf_has(mon->race->flags, square_feat(cave, mon->grid)->resist_flag)) {
1340 return true;
1341 }
1342
1343 return false;
1344 }
1345
1346
1347 /**
1348 * ------------------------------------------------------------------------
1349 * Monster inventory utilities
1350 * ------------------------------------------------------------------------ */
1351 /**
1352 * Add the given object to the given monster's inventory.
1353 *
1354 * Currently always returns true - it is left as a bool rather than
1355 * void in case a limit on monster inventory size is proposed in future.
1356 */
monster_carry(struct chunk * c,struct monster * mon,struct object * obj)1357 bool monster_carry(struct chunk *c, struct monster *mon, struct object *obj)
1358 {
1359 struct object *held_obj;
1360
1361 /* Scan objects already being held for combination */
1362 for (held_obj = mon->held_obj; held_obj; held_obj = held_obj->next) {
1363 /* Check for combination */
1364 if (object_similar(held_obj, obj, OSTACK_MONSTER)) {
1365 /* Combine the items */
1366 object_absorb(held_obj, obj);
1367
1368 /* Result */
1369 return true;
1370 }
1371 }
1372
1373 /* Forget location */
1374 obj->grid = loc(0, 0);
1375
1376 /* Link the object to the monster */
1377 obj->held_m_idx = mon->midx;
1378
1379 /* Add the object to the monster's inventory */
1380 list_object(c, obj);
1381 if (obj->known) {
1382 obj->known->oidx = obj->oidx;
1383 player->cave->objects[obj->oidx] = obj->known;
1384 }
1385 pile_insert(&mon->held_obj, obj);
1386
1387 /* Result */
1388 return true;
1389 }
1390
1391 /**
1392 * Get a random object from a monster's inventory
1393 */
get_random_monster_object(struct monster * mon)1394 struct object *get_random_monster_object(struct monster *mon)
1395 {
1396 struct object *obj, *pick = NULL;
1397 int i = 1;
1398
1399 /* Pick a random object */
1400 for (obj = mon->held_obj; obj; obj = obj->next)
1401 {
1402 /* Check it isn't a quest artifact */
1403 if (obj->artifact && kf_has(obj->kind->kind_flags, KF_QUEST_ART))
1404 continue;
1405
1406 if (one_in_(i)) pick = obj;
1407 i++;
1408 }
1409
1410 return pick;
1411 }
1412
1413 /**
1414 * Player or monster midx steals an item from a monster
1415 *
1416 * \param mon Monster stolen from
1417 * \param midx Index of the thief
1418 */
steal_monster_item(struct monster * mon,int midx)1419 void steal_monster_item(struct monster *mon, int midx)
1420 {
1421 struct object *obj = get_random_monster_object(mon);
1422 struct monster_lore *lore = get_lore(mon->race);
1423 struct monster *thief = NULL;
1424 char m_name[80];
1425
1426 /* Get the target monster name (or "it") */
1427 monster_desc(m_name, sizeof(m_name), mon, MDESC_TARG);
1428
1429 if (midx < 0) {
1430 /* Base monster protection and player stealing skill */
1431 bool unique = rf_has(mon->race->flags, RF_UNIQUE);
1432 int guard = (mon->race->level * (unique ? 4 : 3)) / 4 +
1433 mon->mspeed - player->state.speed;
1434 int steal_skill = player->state.skills[SKILL_STEALTH] +
1435 adj_dex_th[player->state.stat_ind[STAT_DEX]];
1436 int monster_reaction;
1437
1438 /* No object */
1439 if (!obj) {
1440 msg("You can find nothing to steal from %s.", m_name);
1441 if (one_in_(3)) {
1442 /* Monster notices */
1443 monster_wake(mon, false, 100);
1444 }
1445 return;
1446 }
1447
1448 /* Penalize some status conditions */
1449 if (player->timed[TMD_BLIND] || player->timed[TMD_CONFUSED] ||
1450 player->timed[TMD_IMAGE]) {
1451 steal_skill /= 4;
1452 }
1453 if (mon->m_timed[MON_TMD_SLEEP]) {
1454 guard /= 2;
1455 }
1456
1457 /* Monster base reaction, plus allowance for item weight */
1458 monster_reaction = guard / 2 + randint1(MAX(guard, 1));
1459 monster_reaction += obj->weight / 20;
1460
1461 /* Try and steal */
1462 if (monster_reaction < steal_skill) {
1463 int wake = 35 - player->state.skills[SKILL_STEALTH];
1464
1465 /* Success! */
1466 obj->held_m_idx = 0;
1467 pile_excise(&mon->held_obj, obj);
1468 if (tval_is_money(obj)) {
1469 msg("You steal %d gold pieces worth of treasure.", obj->pval);
1470 player->au += obj->pval;
1471 delist_object(cave, obj);
1472 object_delete(&obj);
1473 } else {
1474 object_grab(player, obj);
1475 delist_object(player->cave, obj->known);
1476 delist_object(cave, obj);
1477 /* Drop immediately if ignored to prevent pack overflow */
1478 if (ignore_item_ok(obj)) {
1479 char o_name[80];
1480 object_desc(o_name, sizeof(o_name), obj,
1481 ODESC_PREFIX | ODESC_FULL);
1482 drop_near(cave, &obj, 0, player->grid, true, true);
1483 msg("You drop %s.", o_name);
1484 } else {
1485 inven_carry(player, obj, true, true);
1486 }
1487 }
1488
1489 /* Track thefts */
1490 lore->thefts++;
1491
1492 /* Monster wakes a little */
1493 mon_dec_timed(mon, MON_TMD_SLEEP, wake, MON_TMD_FLG_NOTIFY);
1494 } else if (monster_reaction / 2 < steal_skill) {
1495 /* Decent attempt, at least */
1496 char o_name[80];
1497
1498 object_see(player, obj);
1499 if (tval_is_money(obj)) {
1500 (void)strnfmt(o_name, sizeof(o_name), "treasure");
1501 } else {
1502 object_desc(o_name, sizeof(o_name), obj,
1503 ODESC_PREFIX | ODESC_FULL);
1504 }
1505 msg("You fail to steal %s from %s.", o_name, m_name);
1506 /* Monster wakes, may notice */
1507 monster_wake(mon, true, 50);
1508 } else {
1509 /* Bungled it */
1510 monster_wake(mon, true, 100);
1511 monster_desc(m_name, sizeof(m_name), mon, MDESC_STANDARD);
1512 msg("%s cries out in anger!", m_name);
1513 effect_simple(EF_WAKE, source_monster(mon->midx), "", 0, 0, 0, 0, 0,
1514 NULL);
1515 }
1516
1517 /* Player hit and run */
1518 if (player->timed[TMD_ATT_RUN]) {
1519 const char *near = "20";
1520 msg("You vanish into the shadows!");
1521 effect_simple(EF_TELEPORT, source_player(), near, 0, 0, 0, 0, 0,
1522 NULL);
1523 (void) player_clear_timed(player, TMD_ATT_RUN, false);
1524 }
1525 } else {
1526 /* Get the thief details */
1527 char t_name[80];
1528 thief = cave_monster(cave, midx);
1529 assert(thief);
1530 monster_desc(t_name, sizeof(t_name), thief, MDESC_STANDARD);
1531
1532 /* Try to steal */
1533 if (!obj || react_to_slay(obj, thief)) {
1534 /* Fail to steal */
1535 msg("%s tries to steal something from %s, but fails.", t_name,
1536 m_name);
1537 } else {
1538 msg("%s steals something from %s!", t_name, m_name);
1539
1540 /* Steal and carry */
1541 obj->held_m_idx = 0;
1542 pile_excise(&mon->held_obj, obj);
1543 (void)monster_carry(cave, thief, obj);
1544 }
1545 }
1546 }
1547
1548
1549 /**
1550 * ------------------------------------------------------------------------
1551 * Monster shapechange utilities
1552 * ------------------------------------------------------------------------ */
1553 /**
1554 * The shape base for shapechanges
1555 */
1556 struct monster_base *shape_base;
1557
1558 /**
1559 * Predicate function for get_mon_num_prep
1560 * Check to see if the monster race has the same base as the desired shape
1561 */
monster_base_shape_okay(struct monster_race * race)1562 static bool monster_base_shape_okay(struct monster_race *race)
1563 {
1564 assert(race);
1565
1566 /* Check if it matches */
1567 if (race->base != shape_base) return false;
1568
1569 return true;
1570 }
1571
1572 /**
1573 * Monster shapechange
1574 */
monster_change_shape(struct monster * mon)1575 bool monster_change_shape(struct monster *mon)
1576 {
1577 struct monster_shape *shape = mon->race->shapes;
1578 struct monster_race *race = NULL;
1579
1580 /* Use the monster's preferred shapes if any */
1581 if (shape) {
1582 /* Pick one */
1583 int choice = randint0(mon->race->num_shapes);
1584 while (choice--) {
1585 shape = shape->next;
1586 }
1587
1588 /* Race or base? */
1589 if (shape->race) {
1590 /* Simple */
1591 race = shape->race;
1592 } else {
1593 /* Set the shape base */
1594 shape_base = shape->base;
1595
1596 /* Choose a race of the given base */
1597 get_mon_num_prep(monster_base_shape_okay);
1598
1599 /* Pick a random race */
1600 race = get_mon_num(player->depth + 5);
1601
1602 /* Reset allocation table */
1603 get_mon_num_prep(NULL);
1604 }
1605 } else {
1606 /* Choose something the monster can summon */
1607 bitflag summon_spells[RSF_SIZE];
1608 int i, poss = 0, which, index, summon_type;
1609 const struct monster_spell *spell;
1610
1611 /* Extract the summon spells */
1612 create_mon_spell_mask(summon_spells, RST_SUMMON, RST_NONE);
1613 rsf_inter(summon_spells, mon->race->spell_flags);
1614
1615 /* Count possibilities */
1616 for (i = rsf_next(summon_spells, FLAG_START); i != FLAG_END;
1617 i = rsf_next(summon_spells, i + 1)) {
1618 poss++;
1619 }
1620
1621 /* Pick one */
1622 which = randint0(poss);
1623 index = rsf_next(summon_spells, FLAG_START);
1624 for (i = 0; i < which; i++) {
1625 index = rsf_next(summon_spells, index);
1626 }
1627 spell = monster_spell_by_index(index);
1628
1629 /* Set the summon type, and the kin_base if necessary */
1630 summon_type = spell->effect->subtype;
1631 if (summon_type == summon_name_to_idx("KIN")) {
1632 kin_base = mon->race->base;
1633 }
1634
1635 /* Choose a race */
1636 race = select_shape(mon, summon_type);
1637 }
1638
1639 /* Print a message immediately, update visuals */
1640 if (monster_is_obvious(mon)) {
1641 char m_name[80];
1642 monster_desc(m_name, sizeof(m_name), mon, MDESC_IND_HID);
1643 msgt(MSG_GENERIC, "%s %s", m_name, "shimmers and changes!");
1644 if (player->upkeep->health_who == mon)
1645 player->upkeep->redraw |= (PR_HEALTH);
1646
1647 player->upkeep->redraw |= (PR_MONLIST);
1648 square_light_spot(cave, mon->grid);
1649 }
1650
1651 /* Set the race */
1652 if (race) {
1653 if (!mon->original_race) mon->original_race = mon->race;
1654 mon->race = race;
1655 mon->mspeed += mon->race->speed - mon->original_race->speed;
1656 }
1657
1658 /* Emergency teleport if needed */
1659 if (!monster_passes_walls(mon) && square_iswall(cave, mon->grid)) {
1660 effect_simple(EF_TELEPORT, source_monster(mon->midx), "1", 0, 0, 0,
1661 mon->grid.y, mon->grid.x, NULL);
1662 }
1663
1664 return mon->original_race != NULL;
1665 }
1666
1667 /**
1668 * Monster reverse shapechange
1669 */
monster_revert_shape(struct monster * mon)1670 bool monster_revert_shape(struct monster *mon)
1671 {
1672 if (mon->original_race) {
1673 if (monster_is_obvious(mon)) {
1674 char m_name[80];
1675 monster_desc(m_name, sizeof(m_name), mon, MDESC_IND_HID);
1676 msgt(MSG_GENERIC, "%s %s", m_name, "shimmers and changes!");
1677 if (player->upkeep->health_who == mon)
1678 player->upkeep->redraw |= (PR_HEALTH);
1679
1680 player->upkeep->redraw |= (PR_MONLIST);
1681 square_light_spot(cave, mon->grid);
1682 }
1683 mon->mspeed += mon->original_race->speed - mon->race->speed;
1684 mon->race = mon->original_race;
1685 mon->original_race = NULL;
1686
1687 /* Emergency teleport if needed */
1688 if (!monster_passes_walls(mon) && square_iswall(cave, mon->grid)) {
1689 effect_simple(EF_TELEPORT, source_monster(mon->midx), "1", 0, 0, 0,
1690 mon->grid.y, mon->grid.x, NULL);
1691 }
1692
1693 return true;
1694 }
1695
1696 return false;
1697 }
1698