Annotation of early-roguelike/rogue3/monsters.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: * File with various monster functions in it
3: *
4: * @(#)monsters.c 3.18 (Berkeley) 6/15/81
5: *
6: * Rogue: Exploring the Dungeons of Doom
7: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
8: * All rights reserved.
9: *
10: * See the file LICENSE.TXT for full copyright and licensing information.
11: */
12:
13: #include "curses.h"
14: #include "rogue.h"
15: #include <string.h>
16: #include <ctype.h>
17:
18: /*
19: * List of monsters in rough order of vorpalness
20: */
21: char lvl_mons[27] = "KJBSHEAOZGLCRQNYTWFIXUMVDP";
22: char wand_mons[27] = "KJBSH AOZG CRQ Y W IXU V ";
23:
24: /*
25: * randmonster:
26: * Pick a monster to show up. The lower the level,
27: * the meaner the monster.
28: */
29:
30: int
31: randmonster(int wander)
32: {
33: int d;
34: char *mons;
35:
36: mons = wander ? wand_mons : lvl_mons;
37: do
38: {
39: d = level + (rnd(10) - 5);
40: if (d < 1)
41: d = rnd(5) + 1;
42: if (d > 26)
43: d = rnd(5) + 22;
44: } while (mons[--d] == ' ');
45: return mons[d];
46: }
47:
48: /*
49: * new_monster:
50: * Pick a new monster and add it to the list
51: */
52:
53: void
54: new_monster(struct linked_list *item, int type, coord *cp)
55: {
56: struct thing *tp;
57: struct monster *mp;
58:
59: attach(mlist, item);
60: tp = (struct thing *) ldata(item);
61: tp->t_type = type;
62: tp->t_pos = *cp;
63: tp->t_oldch = mvwinch(cw, cp->y, cp->x);
64: mvwaddch(mw, cp->y, cp->x, tp->t_type);
65: mp = &monsters[tp->t_type-'A'];
66: tp->t_stats.s_hpt = roll(mp->m_stats.s_lvl, 8);
67: tp->t_stats.s_lvl = mp->m_stats.s_lvl;
68: tp->t_stats.s_arm = mp->m_stats.s_arm;
69: strcpy(tp->t_stats.s_dmg,mp->m_stats.s_dmg);
70: tp->t_stats.s_exp = mp->m_stats.s_exp;
71: tp->t_stats.s_str.st_str = 10;
72: tp->t_flags = mp->m_flags;
73: tp->t_turn = TRUE;
74: tp->t_pack = NULL;
75: if (ISWEARING(R_AGGR))
76: runto(cp, &hero);
77: if (type == 'M')
78: {
79: int mch = 0;
80:
81: if (tp->t_pack != NULL)
82: mch = ((struct object *) ldata(tp->t_pack))->o_type;
83: else
84: switch (rnd(level > 25 ? 9 : 8))
85: {
86: case 0: mch = GOLD;
87: when 1: mch = POTION;
88: when 2: mch = SCROLL;
89: when 3: mch = STAIRS;
90: when 4: mch = WEAPON;
91: when 5: mch = ARMOR;
92: when 6: mch = RING;
93: when 7: mch = STICK;
94: when 8: mch = AMULET;
95: }
96: tp->t_disguise = mch;
97: }
98: }
99:
100: /*
101: * wanderer:
102: * A wandering monster has awakened and is headed for the player
103: */
104:
105: void
106: wanderer()
107: {
108: int i, ch;
109: struct room *rp, *hr = roomin(&hero);
110: struct linked_list *item;
111: struct thing *tp;
112: coord cp;
113:
114: item = new_item(sizeof *tp);
115: do
116: {
117: i = rnd_room();
118: if ((rp = &rooms[i]) == hr)
119: continue;
120: rnd_pos(rp, &cp);
121: if ((ch = mvwinch(stdscr, cp.y, cp.x)) == ERR)
122: {
123: debug("Routine wanderer: mvwinch failed to %d,%d", cp.y, cp.x);
124: if (wizard)
125: wait_for(cw,'\n');
126: return;
127: }
128: } until(hr != rp && step_ok(ch));
129: new_monster(item, randmonster(TRUE), &cp);
130: tp = (struct thing *) ldata(item);
131: tp->t_flags |= ISRUN;
132: tp->t_pos = cp;
133: tp->t_dest = &hero;
134: if (wizard)
135: msg("Started a wandering %s", monsters[tp->t_type-'A'].m_name);
136: }
137:
138: /*
139: * what to do when the hero steps next to a monster
140: */
141: struct linked_list *
142: wake_monster(int y, int x)
143: {
144: struct thing *tp;
145: struct linked_list *it;
146: struct room *rp;
147: int ch;
148:
149: if ((it = find_mons(y, x)) == NULL)
150: {
151: fatal("Can't find monster in wake");
152: return NULL;
153: }
154:
155: tp = (struct thing *) ldata(it);
156: ch = tp->t_type;
157: /*
158: * Every time he sees mean monster, it might start chasing him
159: */
160: if (rnd(100) > 33 && on(*tp, ISMEAN) && off(*tp, ISHELD)
161: && !ISWEARING(R_STEALTH))
162: {
163: tp->t_dest = &hero;
164: tp->t_flags |= ISRUN;
165: }
166: if (ch == 'U' && off(player, ISBLIND))
167: {
168: rp = roomin(&hero);
169: if ((rp != NULL && !(rp->r_flags&ISDARK))
170: || DISTANCE(y, x, hero.y, hero.x) < 3)
171: {
172: if (off(*tp, ISFOUND) && !save(VS_MAGIC))
173: {
174: msg("The umber hulk's gaze has confused you.");
175: if (on(player, ISHUH))
176: lengthen(unconfuse, rnd(20)+HUHDURATION);
177: else
178: fuse(unconfuse, 0, rnd(20)+HUHDURATION, AFTER);
179: player.t_flags |= ISHUH;
180: }
181: tp->t_flags |= ISFOUND;
182: }
183: }
184: /*
185: * Hide invisible monsters
186: */
187: if (on(*tp, ISINVIS) && off(player, CANSEE))
188: ch = mvwinch(stdscr, y, x);
189: /*
190: * Let greedy ones guard gold
191: */
192: if (on(*tp, ISGREED) && off(*tp, ISRUN))
193: {
194: rp = roomin(&hero);
195:
196: if (rp != NULL && rp->r_goldval)
197: {
198: tp->t_dest = &rp->r_gold;
199: tp->t_flags |= ISRUN;
200: }
201: }
202:
203: return it;
204: }
205:
206: void
207: genocide()
208: {
209: struct linked_list *ip;
210: struct thing *mp;
211: int c;
212: int i;
213: struct linked_list *nip;
214:
215: addmsg("Which monster");
216: if (!terse)
217: addmsg(" do you wish to wipe out");
218: msg("? ");
219: while (!isalpha(c = readchar(cw)))
220: if (c == ESCAPE)
221: return;
222: else
223: {
224: mpos = 0;
225: msg("Please specify a letter between 'A' and 'Z'");
226: }
227: if (islower(c))
228: c = toupper(c);
229: for (ip = mlist; ip; ip = nip)
230: {
231: mp = (struct thing *) ldata(ip);
232: nip = next(ip);
233: if (mp->t_type == c)
234: remove_monster(&mp->t_pos, ip);
235: }
236: for (i = 0; i < 26; i++)
237: if (lvl_mons[i] == c)
238: {
239: lvl_mons[i] = ' ';
240: wand_mons[i] = ' ';
241: break;
242: }
243: }
CVSweb