comparison xrogue/actions.c @ 133:e6179860cb76

Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 21 Apr 2015 08:55:20 -0400
parents
children f54901b9c39b
comparison
equal deleted inserted replaced
124:d10fc4a065ac 133:e6179860cb76
1 /*
2 actions.c - functions for dealing with monster actions
3
4 XRogue: Expeditions into the Dungeons of Doom
5 Copyright (C) 1991 Robert Pietkivitch
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
10 All rights reserved.
11
12 Based on "Rogue: Exploring the Dungeons of Doom"
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14 All rights reserved.
15
16 See the file LICENSE.TXT for full copyright and licensing information.
17 */
18
19 #include <ctype.h>
20 #include <curses.h>
21 #include <limits.h>
22 #include "rogue.h"
23
24 int mf_count = 0; /* move_free counter - see actions.c(m_act()) */
25 int mf_jmpcnt = 0; /* move_free counter for # of jumps */
26
27 /*
28 * Did we disrupt a spell?
29 */
30 dsrpt_monster(tp, always, see_him)
31 register struct thing *tp;
32 bool always, see_him;
33 {
34 switch (tp->t_action) {
35 case A_SUMMON:
36 case A_MISSILE:
37 case A_SLOW:
38 tp->t_action = A_NIL; /* Just make the old fellow start over again */
39 tp->t_no_move = movement(tp);
40 tp->t_using = NULL; /* Just to be on the safe side */
41 turn_on(*tp, WASDISRUPTED);
42 if (see_him)
43 msg("%s's spell has been disrupted.",prname(monster_name(tp),TRUE));
44 /*
45 * maybe choose something else to do next time since player
46 * is disrupting us
47 */
48 tp->t_summon *= 2;
49 tp->t_cast /= 2;
50 return;
51 }
52
53 /* We may want to disrupt other actions, too */
54 if (always) {
55 tp->t_action = A_NIL; /* Just make the old fellow start over again */
56 tp->t_no_move = movement(tp);
57 tp->t_using = NULL;/* Just to be on the safe side */
58 }
59 }
60
61 dsrpt_player()
62 {
63 int which, action;
64 struct linked_list *item;
65 struct object *obj;
66
67 action = player.t_action;
68 which = player.t_selection;
69
70 switch (action) {
71 case C_CAST: /* Did we disrupt a spell? */
72 case C_PRAY:
73 case C_CHANT:
74 {
75 msg("Your %s was disrupted!", action == C_CAST ? "spell" : "prayer");
76
77 /* Charge him 1/4 anyway */
78 if (action == C_CAST)
79 spell_power += magic_spells[which].s_cost / 4;
80 else if (action == C_PRAY)
81 pray_time += cleric_spells[which].s_cost / 4;
82 else if (action == C_CHANT)
83 chant_time += druid_spells[which].s_cost / 4;
84 }
85 when C_COUNT: /* counting of gold? */
86 {
87 if (purse > 0) {
88 msg("Your gold goes flying everywhere!");
89 do {
90 item = spec_item(GOLD, NULL, NULL, NULL);
91 obj = OBJPTR(item);
92 obj->o_count = min(purse, rnd(20)+1);
93 purse -= obj->o_count;
94 obj->o_pos = hero;
95 fall(item, FALSE);
96 } while (purse > 0 && rnd(25) != 1);
97 }
98 }
99 when C_EAT:
100 msg("Ack! You gag on your food for a moment. ");
101 del_pack(player.t_using);
102
103 when A_PICKUP:
104 msg("You drop what you are picking up! ");
105
106 when C_SEARCH: /* searching for traps and secret doors... */
107 msg("Ouch! You decide to stop searching. ");
108 count = 0; /* don't search again */
109
110 when C_SETTRAP:
111 msg("Ouch! You can't set a trap right now. ");
112
113 when A_NIL:
114 default:
115 return;
116 }
117 player.t_no_move = movement(&player); /* disoriented for a while */
118 player.t_action = A_NIL;
119 player.t_selection = 0;
120 }
121
122 /*
123 * m_act:
124 * If the critter isn't doing anything, choose an action for it.
125 * Otherwise, let it perform its chosen action.
126 */
127
128 m_act(tp)
129 register struct thing *tp;
130 {
131 struct object *obj;
132 bool flee; /* Are we scared? */
133
134 /* What are we planning to do? */
135 switch (tp->t_action) {
136 default:
137 /* An unknown action! */
138 msg("Unknown monster action (%d)", tp->t_action);
139
140 /* Fall through */
141
142 case A_NIL:
143 /* If the monster is fairly intelligent and about to die, it
144 * may turn tail and run. But if we are a FRIENDLY creature
145 * in the hero's service, don't run.
146 */
147 if (off(*tp, ISFLEE) &&
148 tp->t_stats.s_hpt < tp->maxstats.s_hpt &&
149 tp->t_stats.s_hpt < max(10, tp->maxstats.s_hpt/6) &&
150 (off(*tp, ISFRIENDLY) || tp->t_dest != &hero) &&
151 rnd(25) < tp->t_stats.s_intel) {
152 turn_on(*tp, ISFLEE);
153
154 /* It is okay to turn tail */
155 tp->t_oldpos = tp->t_pos;
156 }
157
158 /* Should the monster run away? */
159 flee = on(*tp, ISFLEE) ||
160 ((tp->t_dest == &hero) && on(player, ISINWALL) &&
161 off(*tp, CANINWALL));
162
163 m_select(tp, flee); /* Select an action */
164 return;
165
166 when A_ATTACK:
167 /*
168 * We're trying to attack the player or monster at t_newpos
169 * if the prey moved, do nothing
170 */
171 obj = tp->t_using ? OBJPTR(tp->t_using) : NULL;
172 if (ce(tp->t_newpos, hero)) {
173 attack(tp, obj, FALSE);
174 }
175 else if (mvwinch(mw, tp->t_newpos.y, tp->t_newpos.x) &&
176 step_ok(tp->t_newpos.y, tp->t_newpos.x, FIGHTOK, tp)) {
177 skirmish(tp, &tp->t_newpos, obj, FALSE);
178 }
179
180 when A_SELL:
181 /* Is the quartermaster still next to us? */
182 if (ce(tp->t_newpos, hero)) sell(tp);
183
184 /* The quartermaster moved away */
185 else if (off(player, ISBLIND) && cansee(unc(tp->t_pos)) &&
186 (off(*tp, ISINVIS) || on(player, CANSEE)) &&
187 (off(*tp, ISSHADOW) || on(player, CANSEE)) &&
188 (off(*tp, CANSURPRISE) || ISWEARING(R_ALERT)) &&
189 (rnd(12) < 4))
190 msg("%s grunts with frustration",prname(monster_name(tp),TRUE));
191
192 when A_MOVE:
193 /* Let's try to move */
194 do_chase(tp);
195
196 /* If t_no_move > 0, we found that we have to fight! */
197 if (tp->t_no_move > 0) return;
198
199 when A_BREATHE:
200 /* Breathe on the critter */
201 m_breathe(tp);
202
203 when A_SLOW:
204 /* make him move slower */
205 add_slow();
206 turn_off(*tp, CANSLOW);
207
208 when A_MISSILE:
209 /* Start up a magic missile spell */
210 m_spell(tp);
211
212 when A_SONIC:
213 /* Let out a sonic blast! */
214 m_sonic(tp);
215
216 when A_THROW:
217 /* We're throwing something (like an arrow) */
218 missile(tp->t_newpos.y, tp->t_newpos.x, tp->t_using, tp);
219
220 when A_SUMMON:
221 /* We're summoning help */
222 m_summon(tp);
223
224 when A_USERELIC:
225 /* Use our relic */
226 m_use_relic(tp);
227
228 when A_USEWAND:
229 /* use the wand we have */
230 m_use_wand(tp);
231 }
232
233 /* Can we in fact move? (we might have solidified in solid rock) */
234 if (!step_ok(hero.y, hero.x, NOMONST, &player)) {
235
236 if (move_free > 1) goto jump_over; /* avoid messages */
237 if (mf_count > 2) goto jump_over; /* limit messages */
238
239 if (pstats.s_hpt < 1) {
240 pstats.s_hpt = -1;
241 msg("You have merged into the surroundings! --More--");
242 wait_for(' ');
243 death(D_PETRIFY);
244 }
245 else {
246 mf_count += 1; /* count number of times we are here */
247 pstats.s_hpt -= rnd(2)+1;
248 if (pstats.s_hpt < 1) {
249 pstats.s_hpt = -1;
250 msg("You have merged into the surroundings! --More--");
251 wait_for(' ');
252 death(D_PETRIFY);
253 }
254 }
255 switch (rnd(51)) {
256 case 0: msg("Arrrggghhhhh!! ");
257 when 5: msg("You can't move! ");
258 when 10: msg("You motion angrily! ");
259 when 15: msg("You feel so weird! ");
260 when 20: msg("If only you could phase. ");
261 when 25: msg("The rock maggots are closing in! ");
262 when 30: msg("You wrench and wrench and wrench... ");
263 when 35: msg("You wish you could teleport out of here! ");
264 when 40: msg("Your feel your life force ebbing away... ");
265 when 45: msg("You partially regain your senses. ");
266 when 50: msg("The rock maggots have found you!!! ");
267 otherwise: pstats.s_hpt -= rnd(4)+1;
268 }
269 if (pstats.s_hpt < 1) {
270 pstats.s_hpt = -1;
271 msg("You lose the urge to live... --More--");
272 wait_for(' ');
273 death(D_PETRIFY);
274 }
275 jump_over:
276 mf_jmpcnt++; /* count this jump */
277 if (mf_jmpcnt > 9) { /* take a few turns, then reset it */
278 mf_jmpcnt = 0;
279 mf_count = 0;
280 }
281 }
282
283 /* No action now */
284 tp->t_action = A_NIL;
285 tp->t_using = NULL;
286 }
287
288 /*
289 * m_breathe:
290 * Breathe in the chosen direction.
291 */
292
293 m_breathe(tp)
294 register struct thing *tp;
295 {
296 register int damage;
297 register char *breath = NULL;
298
299 damage = tp->t_stats.s_hpt;
300 turn_off(*tp, CANSURPRISE);
301
302 /* Will it breathe at random */
303 if (on(*tp, CANBRANDOM)) {
304 /* Turn off random breath */
305 turn_off(*tp, CANBRANDOM);
306
307 /* Select type of breath */
308 switch (rnd(10)) {
309 case 0: breath = "acid";
310 turn_on(*tp, NOACID);
311 when 1: breath = "flame";
312 turn_on(*tp, NOFIRE);
313 when 2: breath = "lightning bolt";
314 turn_on(*tp, NOBOLT);
315 when 3: breath = "chlorine gas";
316 turn_on(*tp, NOGAS);
317 when 4: breath = "ice";
318 turn_on(*tp, NOCOLD);
319 when 5: breath = "nerve gas";
320 turn_on(*tp, NOPARALYZE);
321 when 6: breath = "sleeping gas";
322 turn_on(*tp, NOSLEEP);
323 when 7: breath = "slow gas";
324 turn_on(*tp, NOSLOW);
325 when 8: breath = "confusion gas";
326 turn_on(*tp, ISCLEAR);
327 when 9: breath = "fear gas";
328 turn_on(*tp, NOFEAR);
329 }
330 }
331
332 /* Or can it breathe acid? */
333 else if (on(*tp, CANBACID)) {
334 turn_off(*tp, CANBACID);
335 breath = "acid";
336 }
337
338 /* Or can it breathe fire */
339 else if (on(*tp, CANBFIRE)) {
340 turn_off(*tp, CANBFIRE);
341 breath = "flame";
342 }
343
344 /* Or can it breathe electricity? */
345 else if (on(*tp, CANBBOLT)) {
346 turn_off(*tp, CANBBOLT);
347 breath = "lightning bolt";
348 }
349
350 /* Or can it breathe gas? */
351 else if (on(*tp, CANBGAS)) {
352 turn_off(*tp, CANBGAS);
353 breath = "chlorine gas";
354 }
355
356 /* Or can it breathe ice? */
357 else if (on(*tp, CANBICE)) {
358 turn_off(*tp, CANBICE);
359 breath = "ice";
360 }
361
362 else if (on(*tp, CANBPGAS)) {
363 turn_off(*tp, CANBPGAS);
364 breath = "nerve gas";
365 }
366
367 /* can it breathe sleeping gas */
368 else if (on(*tp, CANBSGAS)) {
369 turn_off(*tp, CANBSGAS);
370 breath = "sleeping gas";
371 }
372
373 /* can it breathe slow gas */
374 else if (on(*tp, CANBSLGAS)) {
375 turn_off(*tp, CANBSLGAS);
376 breath = "slow gas";
377 }
378
379 /* can it breathe confusion gas */
380 else if (on(*tp, CANBCGAS)) {
381 turn_off(*tp, CANBCGAS);
382 breath = "confusion gas";
383 }
384
385 /* can it breathe fear gas */
386 else {
387 turn_off(*tp, CANBFGAS);
388 breath = "fear gas";
389 }
390
391 /* Now breathe */
392 shoot_bolt(tp, tp->t_pos, tp->t_newpos, FALSE,
393 tp->t_index, breath, damage);
394
395 running = FALSE;
396 if (fight_flush) flushinp();
397 }
398
399 /*
400 * m_select:
401 * Select an action for the monster.
402 */
403
404 m_select(th, flee)
405 register struct thing *th;
406 register bool flee; /* True if running away or player is inaccessible in wall */
407 {
408 register struct room *rer, *ree; /* room of chaser, room of chasee */
409 int dist = INT_MIN;
410 int mindist = INT_MAX, maxdist = INT_MIN;
411 bool rundoor; /* TRUE means run to a door */
412 char sch;
413 coord *last_door=0, /* Door we just came from */
414 this; /* Temporary destination for chaser */
415
416 rer = roomin(&th->t_pos); /* Find room of chaser */
417 ree = roomin(th->t_dest); /* Find room of chasee */
418
419 /* First see if we want to use an ability or weapon */
420 if (m_use_it(th, flee, rer, ree)) return;
421
422 /*
423 * We don't count monsters on doors as inside rooms here because when
424 * a monster is in a room and the player is not in that room, the
425 * monster looks for the best door out. If we counted doors as part
426 * of the room, the monster would already be on the best door out;
427 * so he would never move.
428 */
429 if ((sch = mvwinch(stdscr, th->t_pos.y, th->t_pos.x)) == DOOR ||
430 sch == SECRETDOOR || sch == PASSAGE) {
431 rer = NULL;
432 }
433 this = *th->t_dest;
434
435 /*
436 * If we are in a room heading for the player and the player is not
437 * in the room with us, we run to the "best" door.
438 * If we are in a room fleeing from the player, then we run to the
439 * "best" door if he IS in the same room.
440 *
441 * Note: We don't bother with doors in mazes or if we can walk
442 * through walls.
443 */
444 if (rer != NULL && levtype != MAZELEV && off(*th, CANINWALL)) {
445 if (flee) rundoor = (rer == ree);
446 else rundoor = (rer != ree);
447 }
448 else rundoor = FALSE;
449
450 if (rundoor) {
451 register struct linked_list *exitptr; /* For looping through exits */
452 coord *exit, /* A particular door */
453 *entrance; /* Place just inside doorway */
454 int exity, exitx; /* Door's coordinates */
455 char dch='\0'; /* Door character */
456
457 if ((th->t_doorgoal.x != -1) && (th->t_doorgoal.y != -1))
458 dch = mvwinch(stdscr, th->t_doorgoal.y, th->t_doorgoal.x);
459
460 /* Do we have a valid goal? */
461 if ((dch == PASSAGE || dch == DOOR) && /* A real door */
462 (!flee || !ce(th->t_doorgoal, *th->t_dest))) { /* Prey should not
463 * be at door if
464 * we are running
465 * away
466 */
467 /* Make sure the player is not in the doorway, either */
468 entrance = doorway(rer, &th->t_doorgoal);
469 if (!flee || entrance == NULL || !ce(*entrance, *th->t_dest)) {
470 this = th->t_doorgoal;
471 dist = 0; /* Indicate that we have our door */
472 }
473 }
474
475 /* Go through all the doors */
476 else for (exitptr = rer->r_exit; exitptr; exitptr = next(exitptr)) {
477 exit = DOORPTR(exitptr);
478 exity = exit->y;
479 exitx = exit->x;
480
481 /* Make sure it is a real door */
482 dch = mvwinch(stdscr, exity, exitx);
483 if (dch == PASSAGE || dch == DOOR) {
484 /* Don't count a door if we are fleeing from someone and
485 * he is standing on it. Also, don't count it if he is
486 * standing in the doorway.
487 */
488 if (flee) {
489 if (ce(*exit, *th->t_dest)) continue;
490
491 entrance = doorway(rer, exit);
492 if (entrance != NULL && ce(*entrance, *th->t_dest))
493 continue;
494 }
495
496 /* Were we just on this door? */
497 if (ce(*exit, th->t_oldpos)) last_door = exit;
498
499 else {
500 dist = DISTANCE(th->t_dest->y, th->t_dest->x, exity, exitx);
501
502 /* If fleeing, we want to maximize distance from door to
503 * what we flee, and minimize distance from door to us.
504 */
505 if (flee)
506 dist -= DISTANCE(th->t_pos.y, th->t_pos.x, exity, exitx);
507
508 /* Maximize distance if fleeing, otherwise minimize it */
509 if ((flee && (dist > maxdist)) ||
510 (!flee && (dist < mindist))) {
511 th->t_doorgoal = *exit; /* Use this door */
512 this = *exit;
513 mindist = maxdist = dist;
514 }
515 }
516 }
517 }
518
519 /* Could we not find a door? */
520 if (dist == INT_MIN) {
521 /* If we were on a door, go ahead and use it */
522 if (last_door) {
523 th->t_doorgoal = *last_door;
524 this = th->t_oldpos;
525 dist = 0; /* Indicate that we found a door */
526 }
527 else th->t_doorgoal.x = th->t_doorgoal.y = -1; /* No more door goal */
528 }
529
530 /* Indicate that we do not want to flee from the door */
531 if (dist != INT_MIN) flee = FALSE;
532 }
533 else th->t_doorgoal.x = th->t_doorgoal.y = -1; /* Not going to any door */
534
535 /* Now select someplace to go and start the action */
536 chase(th, &this, rer, ree, flee);
537 }
538
539 /*
540 * m_sonic:
541 * The monster is sounding a sonic blast.
542 */
543
544 m_sonic(tp)
545 register struct thing *tp;
546 {
547 register int damage;
548 struct object blast =
549 {
550 MISSILE, {0, 0}, 0, "", "150" , NULL, 0, 0, 0, 0
551 };
552
553 turn_off(*tp, CANSONIC);
554 turn_off(*tp, CANSURPRISE);
555 do_motion(&blast, tp->t_newpos.y, tp->t_newpos.x, tp);
556 damage = rnd(61)+40;
557 if (save(VS_BREATH, &player, -3))
558 damage /= 2;
559 msg ("%s's ultra-sonic blast hits you", prname(monster_name(tp), TRUE));
560 if ((pstats.s_hpt -= damage) <= 0) {
561 pstats.s_hpt = -1;
562 death(tp->t_index);
563 }
564 running = FALSE;
565 if (fight_flush) flushinp();
566 dsrpt_player();
567 }
568
569 /*
570 * m_spell:
571 * The monster casts a spell. Currently this is limited to
572 * magic missile.
573 */
574 m_spell(tp)
575 register struct thing *tp;
576 {
577 struct object missile =
578 {
579 MISSILE, {0, 0}, 0, "", "0d4 " , NULL, 0, WS_MISSILE, 100, 1
580 };
581
582 sprintf(missile.o_hurldmg, "%dd4", tp->t_stats.s_lvl);
583 do_motion(&missile, tp->t_newpos.y, tp->t_newpos.x, tp);
584 hit_monster(unc(missile.o_pos), &missile, tp);
585 turn_off(*tp, CANMISSILE);
586 turn_off(*tp, CANSURPRISE);
587
588 running = FALSE;
589 if (fight_flush) flushinp();
590 }
591
592 /*
593 * m_summon:
594 * Summon aid.
595 */
596
597 m_summon(tp)
598 register struct thing *tp;
599 {
600 register char *helpname, *mname;
601 int fail, numsum;
602 register int which, i;
603
604 /* Let's make sure our prey is still here */
605 if (!cansee(unc(tp->t_pos)) || fallpos(&hero, FALSE, 2) == NULL) return;
606
607 /*
608 * Non-uniques can only summon once. Uniques get fewer
609 * creatures with each successive summoning. Also, the
610 * probability of summoning goes down
611 */
612 if (off(*tp, ISUNIQUE))
613 turn_off(*tp, CANSUMMON);
614
615 turn_off(*tp, CANSURPRISE);
616 mname = monster_name(tp);
617 helpname = monsters[tp->t_index].m_typesum;
618 which = findmindex(helpname);
619
620 if ((off(*tp, ISINVIS) || on(player, CANSEE)) &&
621 (off(*tp, ISSHADOW) || on(player, CANSEE)) &&
622 (off(*tp, CANSURPRISE) || ISWEARING(R_ALERT))) {
623 if (monsters[which].m_normal == FALSE) { /* genocided? */
624 msg("%s appears dismayed", prname(mname, TRUE));
625 monsters[tp->t_index].m_numsum = 0;
626 }
627 else {
628 msg("%s summons %ss for help", prname(mname, TRUE), helpname);
629 }
630 }
631 else {
632 if (monsters[which].m_normal == FALSE) /* genocided? */
633 monsters[tp->t_index].m_numsum = 0;
634 else {
635 msg("%ss seem to appear from nowhere!", helpname);
636 }
637 }
638 numsum = monsters[tp->t_index].m_numsum;
639 if (numsum && on(*tp, ISUNIQUE)) { /* UNIQUEs summon less each time */
640 monsters[tp->t_index].m_numsum--;
641 tp->t_summon *= 2; /* cut probability in half */
642 }
643
644 /*
645 * try to make all the creatures around player but remember
646 * if unsuccessful
647 */
648 for (i=0, fail=0; i<numsum; i++) {
649 if (!creat_mons(&player, which, FALSE))
650 fail++; /* remember the failures */
651 }
652
653 /*
654 * try once again to make the buggers
655 */
656 for (i=0; i<fail; i++)
657 creat_mons(tp, which, FALSE);
658
659 /* Now let the poor fellow see all the trouble */
660 light(&hero);
661 turn_on(*tp, HASSUMMONED);
662 }
663
664 /*
665 * m_use_it:
666 * See if the monster (tp) has anything useful it can do
667 * (ie. an ability or a weapon) other than just move.
668 */
669
670 bool
671 m_use_it(tp, flee, rer, ree)
672 register struct thing *tp;
673 bool flee;
674 register struct room *rer, *ree;
675 {
676 int dist;
677 register coord *ee = tp->t_dest, *er = &tp->t_pos;
678 coord *shoot_dir = NULL;
679 coord straight_dir;
680 int straight_shot = FALSE;
681 struct thing *prey;
682 bool dest_player; /* Are we after the player? */
683
684 /*
685 * If we are fleeing, there's a chance, depending on our
686 * intelligence, that we'll just run in terror.
687 */
688 if (flee && rnd(25) >= tp->t_stats.s_intel) return(FALSE);
689
690 /*
691 * Make sure that we have a living destination, and record whether
692 * it is the player.
693 */
694 if (ee != NULL) {
695 if (ce(*ee, hero)) {
696 dest_player = TRUE;
697 prey = &player;
698 }
699 else {
700 struct linked_list *item;
701
702 dest_player = FALSE;
703
704 /* What is the monster we're chasing? */
705 item = find_mons(ee->y, ee->x);
706 if (item != NULL) prey = THINGPTR(item);
707 else return(FALSE);
708 }
709 }
710 else return(FALSE);
711
712 /*
713 * If we are friendly to the hero, we don't do anything.
714 */
715 if (on(*tp, ISFRIENDLY) && dest_player) return(FALSE);
716
717 /*
718 * Also, for now, if our prey is in a wall, we won't do
719 * anything. The prey must be in the same room as we are OR
720 * we must have a straight shot at him. Note that
721 * shoot_dir must get set before rer is checked so
722 * that we get a valid value.
723 */
724
725 if (can_shoot(er, ee, &straight_dir) == 0)
726 shoot_dir = &straight_dir;
727 else
728 shoot_dir = NULL;
729
730 if (on(*prey, ISINWALL) ||
731 ( (shoot_dir == NULL) && (rer == NULL || rer != ree)))
732 return(FALSE);
733
734 /*
735 * If we can't see the prey then forget it
736 */
737 if (on(*prey, ISINVIS) && off(*tp, CANSEE))
738 return(FALSE);
739
740 /* How far are we from our prey? */
741 dist = DISTANCE(er->y, er->x, ee->y, ee->x);
742
743 /*
744 * Shall we summon aid so we don't have to get our hands dirty?
745 * For now, we will only summon aid against the player.
746 * We'll wait until he's within 2 dots of a missile length.
747 */
748 if (on(*tp, CANSUMMON) && dest_player &&
749 dist < (BOLT_LENGTH+2)*(BOLT_LENGTH+2) &&
750 rnd(tp->t_summon) < tp->t_stats.s_lvl &&
751 monsters[tp->t_index].m_numsum > 0 &&
752 fallpos(&hero, FALSE, 2) != NULL) {
753 tp->t_action = A_SUMMON; /* We're going to summon help */
754 tp->t_no_move = movement(tp); /* It takes time! */
755 return(TRUE);
756 }
757
758 /*
759 * If the creature can cast a slow spell and if the prey is within
760 * 2 dots of a missile fire, then see whether we will cast it.
761 * if next to player, lessen chance because we don't like being
762 * disrupted
763 */
764 if (on(*tp, CANSLOW) && dest_player &&
765 dist < (BOLT_LENGTH+5)*(BOLT_LENGTH+5) &&
766 rnd(100) < (dist > 3 ? tp->t_cast : tp->t_cast/2)) {
767 tp->t_action = A_SLOW; /* We're going to slow him */
768 tp->t_no_move = 3 * movement(tp); /* Takes time! */
769 debug("casting slow spell!");
770 return(TRUE);
771 }
772
773 /*
774 * If we have a special magic item, we might use it. We will restrict
775 * this options to uniques with relics and creatures with wands for now.
776 * Also check for the quartermaster. Don't want him shooting wands....
777 */
778 if ((on(*tp, ISUNIQUE) || on(*tp, CARRYSTICK)) &&
779 off(*tp, CANSELL) && dest_player &&
780 m_use_pack(tp, ee, dist, shoot_dir)) {
781 return(TRUE);
782 }
783
784 /* From now on, we must have a direct shot at the prey */
785 if (!straight_shot) return(FALSE);
786
787 /* We may use a sonic blast if we can, only on the player */
788 if (on(*tp, CANSONIC) &&
789 dest_player &&
790 (dist < BOLT_LENGTH*2) &&
791 (rnd(100) < tp->t_breathe)) {
792 tp->t_newpos = *shoot_dir; /* Save the direction */
793 tp->t_action = A_SONIC; /* We're going to sonic blast */
794 tp->t_no_move = 2 * movement(tp); /* Takes 2 movement periods */
795 }
796
797 /* If we can breathe, we may do so */
798 else if (on(*tp, CANBREATHE) &&
799 (dist < BOLT_LENGTH*BOLT_LENGTH) &&
800 (rnd(100) < tp->t_breathe)) {
801 tp->t_newpos = *shoot_dir; /* Save the direction */
802 tp->t_action = A_BREATHE; /* We're going to breathe */
803 tp->t_no_move = movement(tp); /* It takes 1 movement period */
804 }
805
806 /*
807 * We may shoot missiles if we can
808 * if next to player, lessen chance so we don't get disrupted as often
809 */
810 else if (on(*tp,CANMISSILE) &&
811 rnd(100) < (dist > 3 ? tp->t_cast : tp->t_cast/2)){
812 tp->t_newpos = *shoot_dir; /* Save the direction */
813 tp->t_action = A_MISSILE; /* We're going to shoot MM's */
814 tp->t_no_move = 3 * movement(tp); /* Takes time! */
815 }
816
817 /*
818 * If we can shoot or throw something, we might do so.
819 * If next to player, then forget it
820 */
821 else if ((on(*tp,CANSHOOT) || on(*tp,CARRYWEAPON) ||
822 on(*tp,CARRYDAGGER) || on(*tp, CARRYAXE)) &&
823 dist > 3 &&
824 off(*tp, CANSELL) &&
825 (get_hurl(tp) != NULL)) {
826 tp->t_newpos = *shoot_dir; /* Save the direction */
827 tp->t_action = A_THROW; /* We're going to throw something */
828 tp->t_using = get_hurl(tp); /* Save our weapon */
829 tp->t_no_move = 2 * movement(tp); /* Takes 2 movement periods */
830 }
831
832 /* We couldn't find anything to do */
833 else return(FALSE);
834
835 return(TRUE);
836
837 }
838
839 reap()
840 {
841 _t_free_list(&rlist);
842 }
843
844 /*
845 * runners:
846 * Make all the awake monsters try to do something.
847 */
848
849 runners(segments)
850 int segments; /* Number of segments since last called */
851 {
852 register struct linked_list *item;
853 register struct thing *tp = NULL;
854 register int min_time = 20; /* Minimum time until a monster can act */
855
856 /*
857 * loop thru the list of running (wandering) monsters and see what
858 * each one will do this time.
859 *
860 * Note: the special case that one of this buggers kills another.
861 * if this happens than we have to see if the monster killed
862 * himself or someone else. In case its himself we have to get next
863 * one immediately. If it wasn't we have to get next one at very
864 * end in case he killed the next one.
865 */
866 for (item = mlist; item != NULL; item = item->l_next)
867 {
868 tp = THINGPTR(item);
869 turn_on(*tp, NEEDSTOACT);
870 }
871
872 for(;;)
873 {
874 for (item = mlist; item != NULL; item = item->l_next)
875 {
876 tp = THINGPTR(item);
877
878 if (on(*tp, NEEDSTOACT))
879 break;
880 }
881
882 if (item == NULL)
883 break;
884
885 turn_off(*tp, NEEDSTOACT);
886
887 /* If we are not awake, just skip us */
888
889 if (off(*tp, ISRUN) && off(*tp, ISHELD))
890 continue;
891
892 /* See if it's our turn */
893
894 tp->t_no_move -= segments;
895
896 if (tp->t_no_move > 0)
897 {
898 if (tp->t_no_move < min_time) min_time = tp->t_no_move;
899 continue;
900 }
901
902 /* If we were frozen, we're moving now */
903
904 if (tp->t_action == A_FREEZE)
905 tp->t_action = A_NIL;
906
907 if (on(*tp, ISHELD))
908 {
909 /* Make sure the action and using are nil */
910
911 tp->t_action = A_NIL;
912 tp->t_using = NULL;
913
914 /* Can we break free? */
915
916 if (rnd(tp->t_stats.s_lvl) > 11)
917 {
918 turn_off(*tp, ISHELD);
919
920 runto(tp, &hero);
921
922 if (cansee(tp->t_pos.y, tp->t_pos.x))
923 msg("%s breaks free from the hold spell",
924 prname(monster_name(tp), TRUE));
925 }
926 else /* Too bad -- try again later */
927 tp->t_no_move = movement(tp);
928 }
929
930 /* Heal the creature if it's not in the middle of some action */
931
932 if (tp->t_action == A_NIL)
933 doctor(tp);
934
935 while (off(*tp, ISELSEWHERE) &&
936 off(*tp, ISDEAD) &&
937 tp->t_no_move <= 0 &&
938 off(*tp, ISHELD) &&
939 on(*tp, ISRUN) )
940 {
941 /* Let's act (or choose an action if t_action = A_NIL) */
942
943 m_act(tp);
944 }
945
946 if ( off(*tp,ISELSEWHERE) && off(*tp,ISDEAD) )
947 {
948 if (tp->t_no_move < min_time)
949 min_time = tp->t_no_move;
950
951 if (tp->t_quiet < 0)
952 tp->t_quiet = 0;
953 }
954 }
955
956 return(min_time);
957 }
958
959 /*
960 * See if a monster has some magic it can use. Return TRUE if so.
961 * Only care about relics and wands for now.
962 */
963 bool
964 m_use_pack(monster, defend_pos, dist, shoot_dir)
965 register struct thing *monster;
966 coord *defend_pos;
967 register int dist;
968 register coord *shoot_dir;
969 {
970 register struct object *obj;
971 register struct linked_list *pitem, *relic, *stick;
972 register int units = -1;
973
974 relic = stick = NULL;
975
976 for (pitem=monster->t_pack; pitem; pitem=next(pitem)) {
977 obj = OBJPTR(pitem);
978 if (obj->o_flags & ISCURSED) continue;
979 if (obj->o_type == RELIC) {
980 switch (obj->o_which) {
981 case MING_STAFF:
982 if (shoot_dir != NULL) {
983 units = 2; /* Use 2 time units */
984 relic = pitem;
985 }
986
987 when EMORI_CLOAK:
988 if (obj->o_charges != 0 &&
989 shoot_dir != NULL) {
990 units = 2; /* Use 2 time units */
991 relic = pitem;
992 }
993
994 when ASMO_ROD:
995 /* The bolt must be able to reach the defendant */
996 if (shoot_dir != NULL &&
997 dist < BOLT_LENGTH * BOLT_LENGTH) {
998 units = 2; /* Use 2 time units */
999 relic = pitem;
1000 }
1001
1002 when BRIAN_MANDOLIN:
1003 /* The defendant must be the player and within 4 spaces */
1004 if (ce(*defend_pos, hero) &&
1005 dist < 25 &&
1006 player.t_action != A_FREEZE) {
1007 units = 4;
1008 relic = pitem;
1009 }
1010
1011 when GERYON_HORN:
1012 /* The defendant must be the player and within 5 spaces */
1013 if (ce(*defend_pos, hero) &&
1014 dist < 25 &&
1015 (off(player,ISFLEE)|| player.t_dest!=&monster->t_pos)) {
1016 units = 3;
1017 relic = pitem;
1018 }
1019 }
1020 }
1021 if (obj->o_type == STICK) {
1022 if (obj->o_charges < 1) continue;
1023 switch(obj->o_which) {
1024 case WS_ELECT:
1025 case WS_FIRE:
1026 case WS_COLD:
1027 /* The bolt must be able to reach the defendant */
1028 if (shoot_dir != NULL &&
1029 dist < BOLT_LENGTH * BOLT_LENGTH) {
1030 units = 3;
1031 stick = pitem;
1032 }
1033
1034 when WS_MISSILE:
1035 case WS_SLOW_M:
1036 case WS_CONFMON:
1037 case WS_PARALYZE:
1038 case WS_MDEG:
1039 case WS_FEAR:
1040 if (shoot_dir != NULL) {
1041 units = 3;
1042 stick = pitem;
1043 }
1044
1045 otherwise:
1046 break;
1047 }
1048 }
1049 }
1050
1051 /* use relics in preference to all others */
1052 if (relic) debug("chance to use relic = %d%%", monster->t_artifact);
1053 if (stick) debug("chance to use stick = %d%%", monster->t_wand);
1054 if (relic && rnd(100) < monster->t_artifact) {
1055 monster->t_action = A_USERELIC;
1056 pitem = relic;
1057 }
1058 else if (stick && rnd(100) < monster->t_wand) {
1059 /*
1060 * see if the monster will use the wand
1061 */
1062 pitem = stick;
1063 monster->t_action = A_USEWAND;
1064 }
1065 else {
1066 return(FALSE);
1067 }
1068
1069 monster->t_no_move = units * movement(monster);
1070 monster->t_using = pitem;
1071 monster->t_newpos = *shoot_dir;
1072 return(TRUE);
1073 }
1074