Mercurial > hg > early-roguelike
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 } | |
