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