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