Mercurial > hg > early-roguelike
comparison rogue5/misc.c @ 33:f502bf60e6e4
Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Mon, 24 May 2010 20:10:59 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
32:2dcd75e6a736 | 33:f502bf60e6e4 |
---|---|
1 /* | |
2 * All sorts of miscellaneous routines | |
3 * | |
4 * @(#)misc.c 4.66 (Berkeley) 08/06/83 | |
5 * | |
6 * Rogue: Exploring the Dungeons of Doom | |
7 * Copyright (C) 1980-1983, 1985, 1999 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 <stdlib.h> | |
14 #include <curses.h> | |
15 #include <string.h> | |
16 #include <ctype.h> | |
17 #include "rogue.h" | |
18 | |
19 /* | |
20 * look: | |
21 * A quick glance all around the player | |
22 */ | |
23 #undef DEBUG | |
24 | |
25 | |
26 void | |
27 look(int wakeup) | |
28 { | |
29 int x, y; | |
30 chtype ch; | |
31 THING *tp; | |
32 PLACE *pp; | |
33 struct room *rp; | |
34 int ey, ex; | |
35 int passcount; | |
36 int pfl, *fp, pch; | |
37 int sy, sx, sumhero = 0, diffhero = 0; | |
38 # ifdef DEBUG | |
39 static int done = FALSE; | |
40 | |
41 if (done) | |
42 return; | |
43 done = TRUE; | |
44 # endif /* DEBUG */ | |
45 passcount = 0; | |
46 rp = proom; | |
47 if (!ce(oldpos, hero)) | |
48 { | |
49 erase_lamp(&oldpos, oldrp); | |
50 oldpos = hero; | |
51 oldrp = rp; | |
52 } | |
53 ey = hero.y + 1; | |
54 ex = hero.x + 1; | |
55 sx = hero.x - 1; | |
56 sy = hero.y - 1; | |
57 if (door_stop && !firstmove && running) | |
58 { | |
59 sumhero = hero.y + hero.x; | |
60 diffhero = hero.y - hero.x; | |
61 } | |
62 pp = INDEX(hero.y, hero.x); | |
63 pch = pp->p_ch; | |
64 pfl = pp->p_flags; | |
65 | |
66 for (y = sy; y <= ey; y++) | |
67 if (y > 0 && y < NUMLINES - 1) for (x = sx; x <= ex; x++) | |
68 { | |
69 if (x < 0 || x >= NUMCOLS) | |
70 continue; | |
71 if (!on(player, ISBLIND)) | |
72 { | |
73 if (y == hero.y && x == hero.x) | |
74 continue; | |
75 } | |
76 | |
77 pp = INDEX(y, x); | |
78 ch = pp->p_ch; | |
79 if (ch == ' ') /* nothing need be done with a ' ' */ | |
80 continue; | |
81 fp = &pp->p_flags; | |
82 if (pch != DOOR && ch != DOOR) | |
83 if ((pfl & F_PASS) != (*fp & F_PASS)) | |
84 continue; | |
85 if (((*fp & F_PASS) || ch == DOOR) && | |
86 ((pfl & F_PASS) || pch == DOOR)) | |
87 { | |
88 if (hero.x != x && hero.y != y && | |
89 !step_ok(chat(y, hero.x)) && !step_ok(chat(hero.y, x))) | |
90 continue; | |
91 } | |
92 | |
93 if ((tp = pp->p_monst) == NULL) | |
94 ch = trip_ch(y, x, ch); | |
95 else | |
96 if (on(player, SEEMONST) && on(*tp, ISINVIS)) | |
97 { | |
98 if (door_stop && !firstmove) | |
99 running = FALSE; | |
100 continue; | |
101 } | |
102 else | |
103 { | |
104 if (wakeup) | |
105 wake_monster(y, x); | |
106 if (see_monst(tp)) | |
107 { | |
108 if (on(player, ISHALU)) | |
109 ch = rnd(26) + 'A'; | |
110 else | |
111 ch = tp->t_disguise; | |
112 } | |
113 } | |
114 if (on(player, ISBLIND) && (y != hero.y || x != hero.x)) | |
115 continue; | |
116 | |
117 move(y, x); | |
118 | |
119 if ((proom->r_flags & ISDARK) && !see_floor && ch == FLOOR) | |
120 ch = ' '; | |
121 | |
122 if (tp != NULL || ch != CCHAR( inch() )) | |
123 addch(ch); | |
124 | |
125 if (door_stop && !firstmove && running) | |
126 { | |
127 switch (runch) | |
128 { | |
129 case 'h': | |
130 if (x == ex) | |
131 continue; | |
132 when 'j': | |
133 if (y == sy) | |
134 continue; | |
135 when 'k': | |
136 if (y == ey) | |
137 continue; | |
138 when 'l': | |
139 if (x == sx) | |
140 continue; | |
141 when 'y': | |
142 if ((y + x) - sumhero >= 1) | |
143 continue; | |
144 when 'u': | |
145 if ((y - x) - diffhero >= 1) | |
146 continue; | |
147 when 'n': | |
148 if ((y + x) - sumhero <= -1) | |
149 continue; | |
150 when 'b': | |
151 if ((y - x) - diffhero <= -1) | |
152 continue; | |
153 } | |
154 switch (ch) | |
155 { | |
156 case DOOR: | |
157 if (x == hero.x || y == hero.y) | |
158 running = FALSE; | |
159 break; | |
160 case PASSAGE: | |
161 if (x == hero.x || y == hero.y) | |
162 passcount++; | |
163 break; | |
164 case FLOOR: | |
165 case '|': | |
166 case '-': | |
167 case ' ': | |
168 break; | |
169 default: | |
170 running = FALSE; | |
171 break; | |
172 } | |
173 } | |
174 } | |
175 if (door_stop && !firstmove && passcount > 1) | |
176 running = FALSE; | |
177 if (!running || !jump) | |
178 mvaddch(hero.y, hero.x, PLAYER); | |
179 # ifdef DEBUG | |
180 done = FALSE; | |
181 # endif /* DEBUG */ | |
182 } | |
183 | |
184 /* | |
185 * trip_ch: | |
186 * Return the character appropriate for this space, taking into | |
187 * account whether or not the player is tripping. | |
188 */ | |
189 int | |
190 trip_ch(int y, int x, int ch) | |
191 { | |
192 if (on(player, ISHALU) && after) | |
193 switch (ch) | |
194 { | |
195 case FLOOR: | |
196 case ' ': | |
197 case PASSAGE: | |
198 case '-': | |
199 case '|': | |
200 case DOOR: | |
201 case TRAP: | |
202 break; | |
203 default: | |
204 if (y != stairs.y || x != stairs.x || !seenstairs) | |
205 ch = rnd_thing(); | |
206 break; | |
207 } | |
208 return ch; | |
209 } | |
210 | |
211 /* | |
212 * erase_lamp: | |
213 * Erase the area shown by a lamp in a dark room. | |
214 */ | |
215 | |
216 void | |
217 erase_lamp(const coord *pos, const struct room *rp) | |
218 { | |
219 int y, x, ey, sy, ex; | |
220 | |
221 if (!(see_floor && (rp->r_flags & (ISGONE|ISDARK)) == ISDARK | |
222 && !on(player,ISBLIND))) | |
223 return; | |
224 | |
225 ey = pos->y + 1; | |
226 ex = pos->x + 1; | |
227 sy = pos->y - 1; | |
228 for (x = pos->x - 1; x <= ex; x++) | |
229 for (y = sy; y <= ey; y++) | |
230 { | |
231 if (y == hero.y && x == hero.x) | |
232 continue; | |
233 move(y, x); | |
234 if (CCHAR( inch() ) == FLOOR) | |
235 addch(' '); | |
236 } | |
237 } | |
238 | |
239 /* | |
240 * show_floor: | |
241 * Should we show the floor in her room at this time? | |
242 */ | |
243 int | |
244 show_floor(void) | |
245 { | |
246 if ((proom->r_flags & (ISGONE|ISDARK)) == ISDARK && !on(player, ISBLIND)) | |
247 return see_floor; | |
248 else | |
249 return TRUE; | |
250 } | |
251 | |
252 /* | |
253 * find_obj: | |
254 * Find the unclaimed object at y, x | |
255 */ | |
256 THING * | |
257 find_obj(int y, int x) | |
258 { | |
259 THING *obj; | |
260 | |
261 for (obj = lvl_obj; obj != NULL; obj = next(obj)) | |
262 { | |
263 if (obj->o_pos.y == y && obj->o_pos.x == x) | |
264 return obj; | |
265 } | |
266 #ifdef MASTER | |
267 sprintf(prbuf, "Non-object %d,%d", y, x); | |
268 msg(prbuf); | |
269 return NULL; | |
270 #else | |
271 /* NOTREACHED */ | |
272 return NULL; | |
273 #endif | |
274 } | |
275 | |
276 /* | |
277 * eat: | |
278 * She wants to eat something, so let her try | |
279 */ | |
280 | |
281 void | |
282 eat(void) | |
283 { | |
284 THING *obj; | |
285 | |
286 if ((obj = get_item("eat", FOOD)) == NULL) | |
287 return; | |
288 if (obj->o_type != FOOD) | |
289 { | |
290 if (!terse) | |
291 msg("ugh, you would get ill if you ate that"); | |
292 else | |
293 msg("that's Inedible!"); | |
294 return; | |
295 } | |
296 if (food_left < 0) | |
297 food_left = 0; | |
298 if ((food_left += HUNGERTIME - 200 + rnd(400)) > STOMACHSIZE) | |
299 food_left = STOMACHSIZE; | |
300 hungry_state = 0; | |
301 if (obj == cur_weapon) | |
302 cur_weapon = NULL; | |
303 if (obj->o_which == 1) | |
304 msg("my, that was a yummy %s", fruit); | |
305 else | |
306 if (rnd(100) > 70) | |
307 { | |
308 pstats.s_exp++; | |
309 msg("%s, this food tastes awful", choose_str("bummer", "yuk")); | |
310 check_level(); | |
311 } | |
312 else | |
313 msg("%s, that tasted good", choose_str("oh, wow", "yum")); | |
314 leave_pack(obj, FALSE, FALSE); | |
315 } | |
316 | |
317 /* | |
318 * check_level: | |
319 * Check to see if the guy has gone up a level. | |
320 */ | |
321 | |
322 void | |
323 check_level(void) | |
324 { | |
325 int i, add, olevel; | |
326 | |
327 for (i = 0; e_levels[i] != 0; i++) | |
328 if (e_levels[i] > pstats.s_exp) | |
329 break; | |
330 i++; | |
331 olevel = pstats.s_lvl; | |
332 pstats.s_lvl = i; | |
333 if (i > olevel) | |
334 { | |
335 add = roll(i - olevel, 10); | |
336 max_hp += add; | |
337 pstats.s_hpt += add; | |
338 msg("welcome to level %d", i); | |
339 } | |
340 } | |
341 | |
342 /* | |
343 * chg_str: | |
344 * used to modify the playes strength. It keeps track of the | |
345 * highest it has been, just in case | |
346 */ | |
347 | |
348 void | |
349 chg_str(int amt) | |
350 { | |
351 int comp; | |
352 | |
353 if (amt == 0) | |
354 return; | |
355 add_str(&pstats.s_str, amt); | |
356 comp = pstats.s_str; | |
357 if (ISRING(LEFT, R_ADDSTR)) | |
358 add_str(&comp, -cur_ring[LEFT]->o_arm); | |
359 if (ISRING(RIGHT, R_ADDSTR)) | |
360 add_str(&comp, -cur_ring[RIGHT]->o_arm); | |
361 if (comp > max_stats.s_str) | |
362 max_stats.s_str = comp; | |
363 } | |
364 | |
365 /* | |
366 * add_str: | |
367 * Perform the actual add, checking upper and lower bound limits | |
368 */ | |
369 void | |
370 add_str(int *sp, int amt) | |
371 { | |
372 if ((*sp += amt) < 3) | |
373 *sp = 3; | |
374 else if (*sp > 31) | |
375 *sp = 31; | |
376 } | |
377 | |
378 /* | |
379 * add_haste: | |
380 * Add a haste to the player | |
381 */ | |
382 int | |
383 add_haste(int potion) | |
384 { | |
385 if (on(player, ISHASTE)) | |
386 { | |
387 no_command += rnd(8); | |
388 player.t_flags &= ~(ISRUN|ISHASTE); | |
389 extinguish(nohaste); | |
390 msg("you faint from exhaustion"); | |
391 |