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