comparison rogue3/misc.c @ 0:527e2150eaf0

Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
author edwarj4
date Tue, 13 Oct 2009 13:33:34 +0000
parents
children e7862a021609
comparison
equal deleted inserted replaced
-1:000000000000 0:527e2150eaf0
1 /*
2 * all sorts of miscellaneous routines
3 *
4 * @(#)misc.c 3.13 (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 <ctype.h>
16
17 /*
18 * tr_name:
19 * print the name of a trap
20 */
21
22 char *
23 tr_name(int ch)
24 {
25 char *s = "";
26
27 switch (ch)
28 {
29 case TRAPDOOR:
30 s = terse ? "A trapdoor." : "You found a trapdoor.";
31 when BEARTRAP:
32 s = terse ? "A beartrap." : "You found a beartrap.";
33 when SLEEPTRAP:
34 s = terse ? "A sleeping gas trap.":"You found a sleeping gas trap.";
35 when ARROWTRAP:
36 s = terse ? "An arrow trap." : "You found an arrow trap.";
37 when TELTRAP:
38 s = terse ? "A teleport trap." : "You found a teleport trap.";
39 when DARTTRAP:
40 s = terse ? "A dart trap." : "You found a poison dart trap.";
41 }
42 return s;
43 }
44
45 /*
46 * Look:
47 * A quick glance all around the player
48 */
49
50 void
51 look(int wakeup)
52 {
53 int x, y;
54 int ch;
55 int oldx, oldy;
56 int inpass;
57 int passcount = 0;
58 struct room *rp;
59 int ey, ex;
60
61 getyx(cw, oldy, oldx);
62 if (oldrp != NULL && (oldrp->r_flags & ISDARK) && off(player, ISBLIND))
63 {
64 for (x = oldpos.x - 1; x <= oldpos.x + 1; x++)
65 for (y = oldpos.y - 1; y <= oldpos.y + 1; y++)
66 if ((y != hero.y || x != hero.x) && show(y, x) == FLOOR)
67 mvwaddch(cw, y, x, ' ');
68 }
69 inpass = ((rp = roomin(&hero)) == NULL);
70 ey = hero.y + 1;
71 ex = hero.x + 1;
72 for (x = hero.x - 1; x <= ex; x++)
73 if (x >= 0 && x < COLS) for (y = hero.y - 1; y <= ey; y++)
74 {
75 if (y <= 0 || y >= LINES - 1)
76 continue;
77 if (isupper(mvwinch(mw, y, x)))
78 {
79 struct linked_list *it;
80 struct thing *tp;
81
82 if (wakeup)
83 it = wake_monster(y, x);
84 else
85 it = find_mons(y, x);
86 tp = (struct thing *) ldata(it);
87 if ((tp->t_oldch = mvinch(y, x)) == TRAP)
88 tp->t_oldch =
89 (trap_at(y,x)->tr_flags&ISFOUND) ? TRAP : FLOOR;
90 if (tp->t_oldch == FLOOR && (rp != NULL) && (rp->r_flags & ISDARK)
91 && off(player, ISBLIND))
92 tp->t_oldch = ' ';
93 }
94 /*
95 * Secret doors show as walls
96 */
97 if ((ch = show(y, x)) == SECRETDOOR)
98 ch = secretdoor(y, x);
99 /*
100 * Don't show room walls if he is in a passage
101 */
102 if (off(player, ISBLIND))
103 {
104 if (y == hero.y && x == hero.x
105 || (inpass && (ch == '-' || ch == '|')))
106 continue;
107 }
108 else if (y != hero.y || x != hero.x)
109 continue;
110 wmove(cw, y, x);
111 waddch(cw, ch);
112 if (door_stop && !firstmove && running)
113 {
114 switch (runch)
115 {
116 case 'h':
117 if (x == ex)
118 continue;
119 when 'j':
120 if (y == hero.y - 1)
121 continue;
122 when 'k':
123 if (y == ey)
124 continue;
125 when 'l':
126 if (x == hero.x - 1)
127 continue;
128 when 'y':
129 if ((x + y) - (hero.x + hero.y) >= 1)
130 continue;
131 when 'u':
132 if ((y - x) - (hero.y - hero.x) >= 1)
133 continue;
134 when 'n':
135 if ((x + y) - (hero.x + hero.y) <= -1)
136 continue;
137 when 'b':
138 if ((y - x) - (hero.y - hero.x) <= -1)
139 continue;
140 }
141 switch (ch)
142 {
143 case DOOR:
144 if (x == hero.x || y == hero.y)
145 running = FALSE;
146 break;
147 case PASSAGE:
148 if (x == hero.x || y == hero.y)
149 passcount++;
150 break;
151 case FLOOR:
152 case '|':
153 case '-':
154 case ' ':
155 break;
156 default:
157 running = FALSE;
158 break;
159 }
160 }
161 }
162 if (door_stop && !firstmove && passcount > 1)
163 running = FALSE;
164 mvwaddch(cw, hero.y, hero.x, PLAYER);
165 wmove(cw, oldy, oldx);
166 oldpos = hero;
167 oldrp = rp;
168 }
169
170 /*
171 * secret_door:
172 * Figure out what a secret door looks like.
173 */
174
175 int
176 secretdoor(int y, int x)
177 {
178 int i;
179 struct room *rp;
180 coord *cpp;
181 static coord cp;
182
183 cp.y = y;
184 cp.x = x;
185 cpp = &cp;
186 for (rp = rooms, i = 0; i < MAXROOMS; rp++, i++)
187 if (inroom(rp, cpp))
188 if (y == rp->r_pos.y || y == rp->r_pos.y + rp->r_max.y - 1)
189 return('-');
190 else
191 return('|');
192
193 return('p');
194 }
195
196 /*
197 * find_obj:
198 * find the unclaimed object at y, x
199 */
200
201 struct linked_list *
202 find_obj(int y, int x)
203 {
204 struct linked_list *obj;
205 struct object *op;
206
207 for (obj = lvl_obj; obj != NULL; obj = next(obj))
208 {
209 op = (struct object *) ldata(obj);
210 if (op->o_pos.y == y && op->o_pos.x == x)
211 return obj;
212 }
213 sprintf(prbuf, "Non-object %d,%d", y, x);
214 debug(prbuf);
215 return NULL;
216 }
217
218 /*
219 * eat:
220 * She wants to eat something, so let her try
221 */
222
223 void
224 eat()
225 {
226 struct linked_list *item;
227 struct object *obj;
228
229 if ((item = get_item("eat", FOOD)) == NULL)
230 return;
231 obj = (struct object *) ldata(item);
232 if (obj->o_type != FOOD)
233 {
234 if (!terse)
235 msg("Ugh, you would get ill if you ate that.");
236 else
237 msg("That's Inedible!");
238 return;
239 }
240 inpack--;
241 if (obj->o_which == 1)
242 msg("My, that was a yummy %s", fruit);
243 else
244 if (rnd(100) > 70)
245 {
246 msg("Yuk, this food tastes awful");
247 pstats.s_exp++;
248 check_level();
249 }
250 else
251 msg("Yum, that tasted good");
252 if ((food_left += HUNGERTIME + rnd(400) - 200) > STOMACHSIZE)
253 food_left = STOMACHSIZE;
254 hungry_state = 0;
255 if (obj == cur_weapon)
256 cur_weapon = NULL;
257 if (--obj->o_count < 1)
258 {
259 detach(pack, item);
260 discard(item);
261 }
262 }
263
264 /*
265 * Used to modify the playes strength
266 * it keeps track of the highest it has been, just in case
267 */
268
269 void
270 chg_str(int amt)
271 {
272 if (amt == 0)
273 return;
274 if (amt > 0)
275 {
276 while (amt--)
277 {
278 if (pstats.s_str.st_str < 18)
279 pstats.s_str.st_str++;
280 else if (pstats.s_str.st_add == 0)
281 pstats.s_str.st_add = rnd(50) + 1;
282 else if (pstats.s_str.st_add <= 50)
283 pstats.s_str.st_add = 51 + rnd(24);
284 else if (pstats.s_str.st_add <= 75)
285 pstats.s_str.st_add = 76 + rnd(14);
286 else if (pstats.s_str.st_add <= 90)
287 pstats.s_str.st_add = 91;
288 else if (pstats.s_str.st_add < 100)
289 pstats.s_str.st_add++;
290 }
291 if (pstats.s_str.st_str > max_stats.s_str.st_str ||
292 (pstats.s_str.st_str == 18 &&
293 pstats.s_str.st_add > max_stats.s_str.st_add))
294 max_stats.s_str = pstats.s_str;
295 }
296 else
297 {
298 while (amt++)
299 {
300 if (pstats.s_str.st_str < 18 || pstats.s_str.st_add == 0)
301 pstats.s_str.st_str--;
302 else if (pstats.s_str.st_add < 51)
303 pstats.s_str.st_add = 0;
304 else if (pstats.s_str.st_add < 76)
305 pstats.s_str.st_add = 1 + rnd(50);
306 else if (pstats.s_str.st_add < 91)
307 pstats.s_str.st_add = 51 + rnd(25);
308 else if (pstats.s_str.st_add < 100)
309 pstats.s_str.st_add = 76 + rnd(14);
310 else
311 pstats.s_str.st_add = 91 + rnd(8);
312 }
313 if (pstats.s_str.st_str < 3)
314 pstats.s_str.st_str = 3;
315 }
316 }
317
318 /*
319 * add_haste:
320 * add a haste to the player
321 */
322
323 void
324 add_haste(int potion)
325 {
326 if (on(player, ISHASTE))
327 {
328 msg("You faint from exhaustion.");
329 no_command += rnd(8);
330 extinguish(nohaste);
331 }
332 else
333 {
334 player.t_flags |= ISHASTE;
335 if (potion)
336 fuse(nohaste, 0, rnd(4)+4, AFTER);
337 }
338 }
339
340 /*
341 * aggravate:
342 * aggravate all the monsters on this level
343 */
344
345 void
346 aggravate()
347 {
348 struct linked_list *mi;
349
350 for (mi = mlist; mi != NULL; mi = next(mi))
351 runto(&((struct thing *) ldata(mi))->t_pos, &hero);
352 }
353
354 /*
355 * for printfs: if string starts with a vowel, return "n" for an "an"
356 */
357 char *
358 vowelstr(char *str)
359 {
360 switch (*str)
361 {
362 case 'a':
363 case 'e':
364 case 'i':
365 case 'o':
366 case 'u':
367 return "n";
368 default:
369 return "";
370 }
371 }
372
373 /*
374 * see if the object is one of the currently used items
375 */
376 int
377 is_current(struct object *obj)
378 {
379 if (obj == NULL)
380 return FALSE;
381 if (obj == cur_armor || obj == cur_weapon || obj == cur_ring[LEFT]
382 || obj == cur_ring[RIGHT])
383 {
384 msg(terse ? "In use." : "That's already in use.");
385 return TRUE;
386 }
387 return FALSE;
388 }
389
390 /*
391 * set up the direction co_ordinate for use in varios "prefix" commands
392 */
393 int
394 get_dir()
395 {
396 char *prompt;
397 int gotit;
398
399 if (!terse)
400 msg(prompt = "Which direction? ");
401 else
402 prompt = "Direction: ";
403 do
404 {
405 gotit = TRUE;
406 switch (readchar(cw))
407 {
408 case 'h': case'H': delta.y = 0; delta.x = -1;
409 when 'j': case'J': delta.y = 1; delta.x = 0;
410 when 'k': case'K': delta.y = -1; delta.x = 0;
411 when 'l': case'L': delta.y = 0; delta.x = 1;
412 when 'y': case'Y': delta.y = -1; delta.x = -1;
413 when 'u': case'U': delta.y = -1; delta.x = 1;
414 when 'b': case'B': delta.y = 1; delta.x = -1;
415 when 'n': case'N': delta.y = 1; delta.x = 1;
416 when ESCAPE: return FALSE;
417 otherwise:
418 mpos = 0;
419 msg(prompt);
420 gotit = FALSE;
421 }
422 } until (gotit);
423 if (on(player, ISHUH) && rnd(100) > 80)
424 do
425 {
426 delta.y = rnd(3) - 1;
427 delta.x = rnd(3) - 1;
428 } while (delta.y == 0 && delta.x == 0);
429 mpos = 0;
430 return TRUE;
431 }