comparison arogue7/monsters.c @ 125:adfa37e67084

Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Fri, 08 May 2015 15:24:40 -0400
parents
children b786053d2f37
comparison
equal deleted inserted replaced
124:d10fc4a065ac 125:adfa37e67084
1 /*
2 * monsters.c - File with various monster functions in it
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 /*
16 * File with various monster functions in it
17 *
18 */
19
20 #include "curses.h"
21 #include "rogue.h"
22 #include <ctype.h>
23
24
25 /*
26 * Check_residue takes care of any effect of the monster
27 */
28 check_residue(tp)
29 register struct thing *tp;
30 {
31 /*
32 * Take care of special abilities
33 */
34 if (on(*tp, DIDHOLD) && (--hold_count == 0)) {
35 turn_off(player, ISHELD);
36 turn_off(*tp, DIDHOLD);
37 }
38
39 /* If frightened of this monster, stop */
40 if (on(player, ISFLEE) &&
41 player.t_dest == &tp->t_pos) turn_off(player, ISFLEE);
42
43 /* If monster was suffocating player, stop it */
44 if (on(*tp, DIDSUFFOCATE)) {
45 extinguish(suffocate);
46 turn_off(*tp, DIDSUFFOCATE);
47 }
48
49 /* If something with fire, may darken */
50 if (on(*tp, HASFIRE)) {
51 register struct room *rp=roomin(&tp->t_pos);
52 register struct linked_list *fire_item;
53
54 if (rp) {
55 for (fire_item = rp->r_fires; fire_item != NULL;
56 fire_item = next(fire_item)) {
57 if (THINGPTR(fire_item) == tp) {
58 detach(rp->r_fires, fire_item);
59 destroy_item(fire_item);
60 if (rp->r_fires == NULL) {
61 rp->r_flags &= ~HASFIRE;
62 if (cansee(tp->t_pos.y, tp->t_pos.x)) light(&hero);
63 }
64 break;
65 }
66 }
67 }
68 }
69 }
70
71 /*
72 * Creat_mons creates the specified monster -- any if 0
73 */
74
75 bool
76 creat_mons(person, monster, report)
77 struct thing *person; /* Where to create next to */
78 short monster;
79 bool report;
80 {
81 struct linked_list *nitem;
82 register struct thing *tp;
83 struct room *rp;
84 coord *mp;
85
86 if (levtype == POSTLEV)
87 return(FALSE);
88 if ((mp = fallpos(&(person->t_pos), FALSE, 2)) != NULL) {
89 nitem = new_item(sizeof (struct thing));
90 new_monster(nitem,
91 monster == 0 ? randmonster(FALSE, FALSE)
92 : monster,
93 mp,
94 TRUE);
95 tp = THINGPTR(nitem);
96 runto(tp, &hero);
97 carry_obj(tp, monsters[tp->t_index].m_carry/2); /* only half chance */
98
99 /* since it just got here, it is disoriented */
100 tp->t_no_move = 2 * movement(tp);
101
102 if (on(*tp, HASFIRE)) {
103 rp = roomin(&tp->t_pos);
104 if (rp) {
105 register struct linked_list *fire_item;
106
107 /* Put the new fellow in the room list */
108 fire_item = creat_item();
109 ldata(fire_item) = (char *) tp;
110 attach(rp->r_fires, fire_item);
111
112 rp->r_flags |= HASFIRE;
113 }
114 }
115
116 /*
117 * If we can see this monster, set oldch to ' ' to make light()
118 * think the creature used to be invisible (ie. not seen here)
119 */
120 if (cansee(tp->t_pos.y, tp->t_pos.x)) tp->t_oldch = ' ';
121 return(TRUE);
122 }
123 if (report) msg("You hear a faint cry of anguish in the distance.");
124 return(FALSE);
125 }
126
127 /*
128 * Genmonsters:
129 * Generate at least 'least' monsters for this single room level.
130 * 'Treas' indicates whether this is a "treasure" level.
131 */
132
133 void
134 genmonsters(least, treas)
135 register int least;
136 bool treas;
137 {
138 reg int i;
139 reg struct room *rp = &rooms[0];
140 reg struct linked_list *item;
141 reg struct thing *mp;
142 coord tp;
143
144 for (i = 0; i < level + least; i++) {
145 if (!treas && rnd(100) < 50) /* put in some little buggers */
146 continue;
147 /*
148 * Put the monster in
149 */
150 item = new_item(sizeof *mp);
151 mp = THINGPTR(item);
152 do {
153 rnd_pos(rp, &tp);
154 } until(mvwinch(stdscr, tp.y, tp.x) == FLOOR);
155
156 new_monster(item, randmonster(FALSE, FALSE), &tp, FALSE);
157 /*
158 * See if we want to give it a treasure to carry around.
159 */
160 carry_obj(mp, monsters[mp->t_index].m_carry);
161
162 /* Calculate a movement rate */
163 mp->t_no_move = movement(mp);
164
165 /* Is it going to give us some light? */
166 if (on(*mp, HASFIRE)) {
167 register struct linked_list *fire_item;
168
169 fire_item = creat_item();
170 ldata(fire_item) = (char *) mp;
171 attach(rp->r_fires, fire_item);
172 rp->r_flags |= HASFIRE;
173 }
174 }
175 }
176
177 /*
178 * id_monst returns the index of the monster given its letter
179 */
180
181 short
182 id_monst(monster)
183 register char monster;
184 {
185 register short result;
186
187 result = NLEVMONS*vlevel;
188 if (result > NUMMONST) result = NUMMONST;
189
190 for(; result>0; result--)
191 if (monsters[result].m_appear == monster) return(result);
192 for (result=(NLEVMONS*vlevel)+1; result <= NUMMONST; result++)
193 if (monsters[result].m_appear == monster) return(result);
194 return(0);
195 }
196
197
198 /*
199 * new_monster:
200 * Pick a new monster and add it to the list
201 */
202
203 new_monster(item, type, cp, max_monster)
204 struct linked_list *item;
205 short type;
206 coord *cp;
207 bool max_monster;
208 {
209 register struct thing *tp;
210 register struct monster *mp;
211 register char *ip, *hitp;
212 register int i, min_intel, max_intel;
213 register int num_dice, num_sides=8, num_extra=0;
214 char *strchr();
215
216 attach(mlist, item);
217 tp = THINGPTR(item);
218 tp->t_pack = NULL;
219 tp->t_index = type;
220 tp->t_wasshot = FALSE;
221 tp->t_type = monsters[type].m_appear;
222 tp->t_ctype = C_MONSTER;
223 tp->t_action = A_NIL;
224 tp->t_doorgoal = 0;
225 tp->t_quiet = 0;
226 tp->t_dest = NULL;
227 tp->t_name = NULL;
228 tp->t_pos = tp->t_oldpos = *cp;
229 tp->t_oldch = CCHAR( mvwinch(cw, cp->y, cp->x) );
230 mvwaddch(mw, cp->y, cp->x, tp->t_type);
231 mp = &monsters[tp->t_index];
232
233 /* Figure out monster's hit points */
234 hitp = mp->m_stats.s_hpt;
235 num_dice = atoi(hitp);
236 if ((hitp = strchr(hitp, 'd')) != NULL) {
237 num_sides = atoi(++hitp);
238 if ((hitp = strchr(hitp, '+')) != NULL)
239 num_extra = atoi(++hitp);
240 }
241
242 tp->t_stats.s_lvladj = 0;
243 tp->t_stats.s_lvl = mp->m_stats.s_lvl;
244 tp->t_stats.s_arm = mp->m_stats.s_arm;
245 strncpy(tp->t_stats.s_dmg, mp->m_stats.s_dmg, sizeof(tp->t_stats.s_dmg));
246 tp->t_stats.s_str = mp->m_stats.s_str;
247 tp->t_stats.s_dext = mp->m_stats.s_dex;
248 tp->t_movement = mp->m_stats.s_move;
249 if (vlevel > HARDER) { /* the deeper, the meaner we get */
250 tp->t_stats.s_lvl += (vlevel - HARDER);
251 num_dice += (vlevel - HARDER)/2;
252 tp->t_stats.s_arm -= (vlevel - HARDER) / 4;
253 }
254 if (max_monster)
255 tp->t_stats.s_hpt = num_dice * num_sides + num_extra;
256 else
257 tp->t_stats.s_hpt = roll(num_dice, num_sides) + num_extra;
258 tp->t_stats.s_exp = mp->m_stats.s_exp + mp->m_add_exp*tp->t_stats.s_hpt;
259
260 /*
261 * just initailize others values to something reasonable for now
262 * maybe someday will *really* put these in monster table
263 */
264 tp->t_stats.s_wisdom = 8 + rnd(4);
265 tp->t_stats.s_const = 8 + rnd(4);
266 tp->t_stats.s_charisma = 8 + rnd(4);
267
268 /* Set the initial flags */
269 for (i=0; i<16; i++) tp->t_flags[i] = 0;
270 for (i=0; i<MAXFLAGS; i++)
271 turn_on(*tp, mp->m_flags[i]);
272
273 /*
274 * these are the base chances that a creatures will do something
275 * assuming it can. These are(or can be) modified at runtime
276 * based on what the creature experiences
277 */
278 tp->t_breathe = 75; /* base chance of breathing */
279 tp->t_artifact = 90; /* base chance of using artifact */
280 tp->t_summon = 40; /* base chance of summoning */
281 tp->t_cast = 75; /* base chance of casting a spell */
282 tp->t_wand = on(*tp, ISUNIQUE) ? 35 : 50; /* base chance of using wands */
283
284 /* suprising monsters don't always surprise you */
285 if (!max_monster && on(*tp, CANSURPRISE) &&
286 off(*tp, ISUNIQUE) && rnd(100) < 20)
287 turn_off(*tp, CANSURPRISE);
288
289 /* If this monster is unique, gen it */
290 if (on(*tp, ISUNIQUE)) mp->m_normal = FALSE;
291
292 /*
293 * If it is the quartermaster, then compute his level and exp pts
294 * based on the level. This will make it fair when thieves try to
295 * steal and give them reasonable experience if they succeed.
296 * Then fill his pack with his wares.
297 */
298 if (on(*tp, CANSELL)) {
299 tp->t_stats.s_exp = vlevel * 100;
300 tp->t_stats.s_lvl = vlevel/2 + 1;
301 make_sell_pack(tp);
302 }
303
304 /* Normally scared monsters have a chance to not be scared */
305 if (on(*tp, ISFLEE) && (rnd(4) == 0)) turn_off(*tp, ISFLEE);
306
307 /* Figure intelligence */
308 min_intel = atoi(mp->m_intel);
309 if ((ip = (char *) strchr(mp->m_intel, '-')) == NULL)
310 tp->t_stats.s_intel = min_intel;
311 else {
312 max_intel = atoi(++ip);
313 if (max_monster)
314 tp->t_stats.s_intel = max_intel;
315 else
316 tp->t_stats.s_intel = min_intel + rnd(max_intel - min_intel);
317 }
318 if (vlevel > HARDER)
319 tp->t_stats.s_intel += ((vlevel - HARDER)/2);
320 tp->maxstats = tp->t_stats;
321
322 /* If the monster can shoot, it may have a weapon */
323 if (on(*tp, CANSHOOT) && ((rnd(100) < (22 + vlevel)) || max_monster)) {
324 struct linked_list *item1;
325 register struct object *cur, *cur1;
326
327 item = new_item(sizeof *cur);
328 item1 = new_item(sizeof *cur1);
329 cur = OBJPTR(item);
330 cur1 = OBJPTR(item1);
331 cur->o_hplus = (rnd(4) < 3) ? 0
332 : (rnd(3) + 1) * ((rnd(3) < 2) ? 1 : -1);
333 cur->o_dplus = (rnd(4) < 3) ? 0
334 : (rnd(3) + 1) * ((rnd(3) < 2) ? 1 : -1);
335 cur1->o_hplus = (rnd(4) < 3) ? 0
336 : (rnd(3) + 1) * ((rnd(3) < 2) ? 1 : -1);
337 cur1->o_dplus = (rnd(4) < 3) ? 0
338 : (rnd(3) + 1) * ((rnd(3) < 2) ? 1 : -1);
339
340 strncpy(cur->o_damage, "0d0", sizeof(cur->o_damage));
341 strncpy(cur->o_hurldmg, "0d0", sizeof(cur->o_hurldmg));
342 strncpy(cur1->o_damage, "0d0", sizeof(cur1->o_damage));
343 strncpy(cur1->o_hurldmg, "0d0", sizeof(cur1->o_hurldmg));
344
345 cur->o_ac = cur1->o_ac = 11;
346 cur->o_count = cur1->o_count = 1;
347 cur->o_group = cur1->o_group = 0;
348 cur->contents = cur1->contents = NULL;
349 if ((cur->o_hplus <= 0) && (cur->o_dplus <= 0)) cur->o_flags = ISCURSED;
350 if ((cur1->o_hplus <= 0) && (cur1->o_dplus <= 0))
351 cur1->o_flags = ISCURSED;
352 cur->o_flags = cur1->o_flags = 0;
353 cur->o_type = cur1->o_type = WEAPON;
354 cur->o_mark[0] = cur1->o_mark[0] = '\0';
355
356 /* The monster may use a crossbow, sling, or an arrow */
357 i = rnd(100);
358 if (i < 10) {
359 cur->o_which = CROSSBOW;
360 cur1->o_which = BOLT;
361 init_weapon(cur, CROSSBOW);
362 init_weapon(cur1, BOLT);
363 }
364 else if (i < 70) {
365 cur->o_which = BOW;
366 cur1->o_which = ARROW;
367 init_weapon(cur, BOW);
368 init_weapon(cur1, ARROW);
369 }
370 else {
371 cur->o_which = SLING;
372 cur1->o_which = ROCK;
373 init_weapon(cur, SLING);
374 init_weapon(cur1, ROCK);
375 }
376
377 attach(tp->t_pack, item);
378 attach(tp->t_pack, item1);
379 }
380
381
382 /* Calculate the initial movement rate */
383 updpack(TRUE, tp);
384 tp->t_no_move = movement(tp);
385
386 if (ISWEARING(R_AGGR))
387 runto(tp, &hero);
388 if (on(*tp, ISDISGUISE))
389 {
390 char mch;
391
392 if (tp->t_pack != NULL)
393 mch = (OBJPTR(tp->t_pack))->o_type;
394 else
395 switch (rnd(10)) {
396 case 0: mch = GOLD;
397 when 1: mch = POTION;
398 when 2: mch = SCROLL;
399 when 3: mch = FOOD;
400 when 4: mch = WEAPON;
401 when 5: mch = ARMOR;
402 when 6: mch = RING;
403 when 7: mch = STICK;
404 when 8: mch = monsters[randmonster(FALSE, FALSE)].m_appear;
405 when 9: mch = MM;
406 }
407 tp->t_disguise = mch;
408 }
409 }
410
411 /*
412 * randmonster:
413 * Pick a monster to show up. The lower the level,
414 * the meaner the monster.
415 */
416
417 short
418 randmonster(wander, no_unique)
419 register bool wander, no_unique;
420 {
421 register int d, cur_level, range, i;
422
423 /*
424 * Do we want a merchant? Merchant is always in place 'NUMMONST'
425 */
426 if (wander && monsters[NUMMONST].m_wander && rnd(100) < pstats.s_charisma/4)
427 return NUMMONST;
428
429 cur_level = vlevel;
430 range = 4*NLEVMONS;
431 i = 0;
432 do
433 {
434 if (i++ > range*10) { /* just in case all have be genocided */
435 i = 0;
436 if (--cur_level <= 0)
437 fatal("Rogue could not find a monster to make");
438 }
439 d = NLEVMONS*(cur_level - 1) + (rnd(range) - (range - 1 - NLEVMONS));
440 if (d < 1)
441 d = rnd(NLEVMONS) + 1;
442 if (d > NUMMONST - NUMUNIQUE - 1) {
443 if (no_unique)
444 d = rnd(range) + (NUMMONST - NUMUNIQUE - 1) - (range - 1);
445 else if (d > NUMMONST - 1)
446 d = rnd(range+NUMUNIQUE) + (NUMMONST-1) - (range+NUMUNIQUE-1);
447 }
448 }
449 while (wander ? !monsters[d].m_wander || !monsters[d].m_normal
450 : !monsters[d].m_normal);
451 return d;
452 }
453
454 /* Sell displays a menu of goods from which the player may choose
455 * to purchase something.
456 */
457
458 sell(tp)
459 register struct thing *tp;
460 {
461 register struct linked_list *item, *seller;
462 register struct linked_list *sellpack;
463 register struct object *obj;
464 register int worth, min_worth;
465 char buffer[LINELEN];
466
467
468 /*
469 * Get a linked_list pointer to the seller. We need this in case
470 * he disappears so we can set monst_dead.
471 */
472 seller = find_mons(tp->t_pos.y, tp->t_pos.x);
473
474 sellpack = tp->t_pack;
475 if (sellpack == NULL) {
476 msg("%s looks puzzled and departs.", prname(monster_name(tp), TRUE));
477
478 /* Get rid of the monster */
479 killed(seller, FALSE, FALSE, FALSE);
480 return;
481 }
482
483 /* See how much the minimum pack item is worth */
484 min_worth = 100000;
485 for (item = sellpack; item != NULL; item = next(item)) {
486 obj = OBJPTR(item);
487 obj->o_flags |= ISPOST; /* Force a long description of the item */
488 worth = get_worth(obj);
489 if (worth < min_worth) min_worth = worth;
490 }
491
492 /* See if player can afford an item */
493 if (min_worth > purse) {
494 msg("%s eyes your small purse and departs.",
495 prname(monster_name(tp), TRUE));
496
497 /* Get rid of the monster */
498 killed(seller, FALSE, FALSE, FALSE);
499 return;
500 }
501
502 /* Announce our intentions */
503 msg("%s opens his pack.--More--", prname(monster_name(tp), TRUE));
504 wait_for(' ');
505
506 /* Try to sell something */
507 sprintf(buffer, "You got %d gold pieces. Buy", purse);
508 item = get_item(sellpack, buffer, ALL, TRUE, TRUE);
509
510 /* Get rid of the monster */
511 if (item != NULL) detach(tp->t_pack, item); /* Take it out of the pack */
512 killed(seller, FALSE, FALSE, FALSE);
513
514 if (item == NULL) return;
515
516 /* Can he afford the selected item? */
517 obj = OBJPTR(item);
518
519 worth = get_worth(obj);
520 if (worth > purse) {
521 msg("You cannot afford it.");
522 o_discard(item);
523 return;
524 }
525
526 /* Charge him through the nose */
527 purse -= worth;
528
529 /* If a stick or ring, let player know the type */
530 switch (obj->o_type) {
531 case RING: r_know[obj->o_which] = TRUE;
532 when POTION:p_know[obj->o_which] = TRUE;
533 when SCROLL:s_know[obj->o_which] = TRUE;
534 when STICK: ws_know[obj->o_which] = TRUE;
535 when MM: m_know[obj->o_which] = TRUE;
536
537 }
538
539 /* Remove the POST flag that we used for get_item() */
540 obj->o_flags &= ~ISPOST;
541
542 if (add_pack(item, FALSE, NULL) == FALSE) {
543 obj->o_pos = hero;
544 fall(item, TRUE);
545 }
546 }
547
548
549
550 /*
551 * what to do when the hero steps next to a monster
552 */
553 struct linked_list *
554 wake_monster(y, x)
555 int y, x;
556 {
557 register struct thing *tp;
558 register struct linked_list *it;
559 register struct room *trp;
560 register char *mname;
561 bool nasty; /* Will the monster "attack"? */
562
563 if ((it = find_mons(y, x)) == NULL) {
564 msg("Wake: can't find monster in show (%d, %d)", y, x);
565 return (NULL);
566 }
567 tp = THINGPTR(it);
568 if (on(*tp, ISSTONE)) /* if stoned, don't do anything */
569 return it;
570
571 /*
572 * For now, if we are a friendly monster, we won't do any of
573 * our special effects.
574 */
575 if (on(*tp, ISFRIENDLY)) return it;
576
577 trp = roomin(&tp->t_pos); /* Current room for monster */
578
579 /*
580 * Let greedy ones in a room guard gold
581 * (except in a maze where lots of creatures would all go for the
582 * same piece of gold)
583 */
584 if (on(*tp, ISGREED) && off(*tp, ISRUN) &&
585 levtype != MAZELEV && trp != NULL &&
586 lvl_obj != NULL) {
587 register struct linked_list *item;
588 register struct object *cur;
589
590 for (item = lvl_obj; item != NULL; item = next(item)) {
591 cur = OBJPTR(item);
592 if ((cur->o_type == GOLD) && (roomin(&cur->o_pos) == trp)) {
593 /* Run to the gold */
594 runto(tp, &cur->o_pos);
595
596 /* Make it worth protecting */
597 cur->o_count += GOLDCALC + GOLDCALC;
598 break;
599 }
600 }
601 }
602
603 /*
604 * Every time he sees mean monster, it might start chasing him
605 */
606 if (on(*tp, ISMEAN) &&
607 off(*tp, ISHELD) &&
608 off(*tp, ISRUN) &&
609 rnd(100) > 33 &&
610 (!is_stealth(&player) || (on(*tp, ISUNIQUE) && rnd(100) > 50)) &&
611 (off(player, ISINVIS) || on(*tp, CANSEE)) ||
612 (trp != NULL && (trp->r_flags & ISTREAS))) {
613 runto(tp, &hero);
614 }
615
616 /*
617 * Get the name; we don't want to do it until here because we need to
618 * know whether the monster is still sleeping or not.
619 */
620 mname = monster_name(tp);
621
622 /* See if the monster will bother the player */
623 nasty = (on(*tp, ISRUN) && cansee(tp->t_pos.y, tp->t_pos.x));
624
625 /*
626 * if the creature is awake and can see the player and the
627 * player has the dreaded "eye of vecna" then see if the
628 * creature is turned to stone
629 */
630 if (cur_relic[EYE_VECNA] && nasty && off(*tp, NOSTONE) &&
631 (off(player, ISINVIS) || on(*tp, CANSEE))) {
632 turn_on(*tp, NOSTONE); /* only have to save once */
633 if (!save(VS_PETRIFICATION, tp, -2)) {
634 turn_on(*tp, ISSTONE);
635 turn_off(*tp, ISRUN);
636 turn_off(*tp, ISINVIS);
637 turn_off(*tp, CANSURPRISE);
638 turn_off(*tp, ISDISGUISE);
639 msg("%s is turned to stone!", prname(mname, TRUE));
640 return it;
641 }
642 }
643
644 /*
645 * Handle monsters that can gaze and do things while running
646 * Player must be able to see the monster and the monster must
647 * not be asleep
648 */
649 if (nasty && !invisible(tp)) {
650 /*
651 * Confusion
652 */
653 if (on(*tp, CANHUH) &&
654 (off(*tp, ISINVIS) || on(player, CANSEE)) &&
655 (off(*tp, CANSURPRISE) || ISWEARING(R_ALERT))) {
656 if (!save(VS_MAGIC, &player, 0)) {
657 if (off(player, ISCLEAR)) {
658 if (find_slot(unconfuse))
659 lengthen(unconfuse, HUHDURATION);
660 else {
661 fuse(unconfuse, 0, HUHDURATION, AFTER);
662 msg("%s's gaze has confused you.",prname(mname, TRUE));
663 turn_on(player, ISHUH);
664 }
665 }
666 else msg("You feel dizzy for a moment, but it quickly passes.");
667 }
668 else if (rnd(100) < 67)
669 turn_off(*tp, CANHUH); /* Once you save, maybe that's it */
670 }
671
672 /* Sleep */
673 if(on(*tp, CANSNORE) &&
674 player.t_action != A_FREEZE &&
675 !save(VS_PARALYZATION, &player, 0)) {
676 if (ISWEARING(R_ALERT))
677 msg("You feel slightly drowsy for a moment.");
678 else {
679 msg("%s's gaze puts you to sleep.", prname(mname, TRUE));
680 player.t_no_move += movement(&player) * SLEEPTIME;
681 player.t_action = A_FREEZE;
682 if (rnd(100) < 50) turn_off(*tp, CANSNORE);
683 }
684 }
685
686 /* Fear */
687 if (on(*tp, CANFRIGHTEN) && !on(player, ISFLEE)) {
688 turn_off(*tp, CANFRIGHTEN);
689 if (!ISWEARING(R_HEROISM) &&
690 !save(VS_WAND, &player, -(tp->t_stats.s_lvl/10))) {
691 turn_on(player, ISFLEE);
692 player.t_dest = &tp->t_pos;
693 msg("The sight of %s terrifies you.", prname(mname, FALSE));
694 }
695 }
696
697 /* blinding creatures */
698 if(on(*tp, CANBLIND) && !find_slot(sight)) {
699 turn_off(*tp, CANBLIND);
700 if (!save(VS_WAND, &player, 0)) {
701 msg("The gaze of %s blinds you", prname(mname, FALSE));
702 turn_on(player, ISBLIND);
703 fuse(sight, 0, rnd(30)+20, AFTER);
704 light(&hero);
705 }
706 }
707
708 /* the sight of the ghost can age you! */
709 if (on(*tp, CANAGE)) {
710 turn_off (*tp, CANAGE);
711 if (!save(VS_MAGIC, &player, 0)) {
712 msg ("The sight of %s ages you!", prname(mname, FALSE));
713 pstats.s_const--;
714 max_stats.s_const--;
715 if (pstats.s_const < 0)
716 death (D_CONSTITUTION);
717 }
718 }
719
720
721 /* Turning to stone */
722 if (on(*tp, LOOKSTONE)) {
723 turn_off(*tp, LOOKSTONE);
724
725 if (on(player, CANINWALL))
726 msg("The gaze of %s has no effect.", prname(mname, FALSE));
727 else {
728 if (!save(VS_PETRIFICATION, &player, 0) && rnd(100) < 5) {
729 pstats.s_hpt = -1;
730 msg("The gaze of %s petrifies you.", prname(mname, FALSE));
731 msg("You are turned to stone !!! --More--");
732 wait_for(' ');
733 death(D_PETRIFY);
734 }
735 else {
736 msg("The gaze of %s stiffens your limbs.",
737 prname(mname, FALSE));
738 player.t_no_move += movement(&player) * STONETIME;
739 player.t_action = A_FREEZE;
740 }
741 }
742 }
743 }
744
745 return it;
746 }
747 /*
748 * wanderer:
749 * A wandering monster has awakened and is headed for the player
750 */
751
752 wanderer()
753 {
754 register int i;
755 register struct room *hr = roomin(&hero);
756 register struct linked_list *item;
757 register struct thing *tp;
758 register long *attr; /* Points to monsters' attributes */
759 int carry; /* Chance of wanderer carrying anything */
760 short rmonst; /* Our random wanderer */
761 bool canteleport = FALSE, /* Can the monster teleport? */
762 seehim; /* Is monster within sight? */
763 coord cp;
764
765 rmonst = randmonster(TRUE, FALSE); /* Choose a random wanderer */
766 attr = &monsters[rmonst].m_flags[0]; /* Start of attributes */
767 for (i=0; i<MAXFLAGS; i++)
768 if (*attr++ == CANTELEPORT) {
769 canteleport = TRUE;
770 break;
771 }
772
773 /* Find a place for it -- avoid the player's room if can't teleport */
774 do {
775 do {
776 i = rnd_room();
777 } until (canteleport || hr != &rooms[i] || levtype == MAZELEV ||
778 levtype == OUTSIDE || levtype == POSTLEV);
779
780 /* Make sure the monster does not teleport on top of the player */
781 do {
782 rnd_pos(&rooms[i], &cp);
783 } while (hr == &rooms[i] && ce(cp, hero));
784 } until (step_ok(cp.y, cp.x, NOMONST, NULL));
785
786 /* Create a new wandering monster */
787 item = new_item(sizeof *tp);
788 new_monster(item, rmonst, &cp, FALSE);
789 tp = THINGPTR(item);
790 runto(tp, &hero);
791 tp->t_pos = cp; /* Assign the position to the monster */
792 seehim = cansee(tp->t_pos.y, tp->t_pos.x);
793 if (on(*tp, HASFIRE)) {
794 register struct room *rp;
795
796 rp = roomin(&tp->t_pos);
797 if (rp) {
798 register struct linked_list *fire_item;
799
800 fire_item = creat_item();
801 ldata(fire_item) = (char *) tp;
802 attach(rp->r_fires, fire_item);
803
804 rp->r_flags |= HASFIRE;
805 if (seehim && next(rp->r_fires) == NULL)
806 light(&hero);
807 }
808 }
809
810 /* See if we give the monster anything */
811 carry = monsters[tp->t_index].m_carry;
812 if (off(*tp, ISUNIQUE)) carry /= 2; /* Non-unique has only a half chance */
813 carry_obj(tp, carry);
814
815 /* Calculate its movement rate */
816 tp->t_no_move = movement(tp);
817
818 /* Alert the player if a monster just teleported in */
819 if (hr == &rooms[i] && canteleport && seehim && !invisible(tp)) {
820 msg("A %s just teleported in", monster_name(tp));
821 light(&hero);
822 running = FALSE;
823 }
824
825 if (wizard)
826 msg("Started a wandering %s", monster_name(tp));
827 }