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 |
