Mercurial > hg > early-roguelike
comparison srogue/misc.c @ 36:2128c7dc8a40
Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)
| author | elwin |
|---|---|
| date | Thu, 25 Nov 2010 12:21:41 +0000 |
| parents | |
| children | 94a0d9dd5ce1 |
comparison
equal
deleted
inserted
replaced
| 35:05018c63a721 | 36:2128c7dc8a40 |
|---|---|
| 1 /* | |
| 2 * all sorts of miscellaneous routines | |
| 3 * | |
| 4 * @(#)misc.c 9.0 (rdk) 7/17/84 | |
| 5 * | |
| 6 * Super-Rogue | |
| 7 * Copyright (C) 1984 Robert D. Kindelberger | |
| 8 * All rights reserved. | |
| 9 * | |
| 10 * Based on "Rogue: Exploring the Dungeons of Doom" | |
| 11 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
| 12 * All rights reserved. | |
| 13 * | |
| 14 * See the file LICENSE.TXT for full copyright and licensing information. | |
| 15 */ | |
| 16 | |
| 17 #include "rogue.h" | |
| 18 #include <ctype.h> | |
| 19 #include "rogue.ext" | |
| 20 | |
| 21 /* | |
| 22 * waste_time: | |
| 23 * Do nothing but let other things happen | |
| 24 */ | |
| 25 waste_time() | |
| 26 { | |
| 27 if (inwhgt) /* if from wghtchk, then done */ | |
| 28 return; | |
| 29 do_daemons(BEFORE); | |
| 30 do_daemons(AFTER); | |
| 31 do_fuses(); | |
| 32 } | |
| 33 | |
| 34 /* | |
| 35 * getindex: | |
| 36 * Convert a type into an index for the things structures | |
| 37 */ | |
| 38 getindex(what) | |
| 39 char what; | |
| 40 { | |
| 41 int index = -1; | |
| 42 | |
| 43 switch (what) { | |
| 44 case POTION: index = TYP_POTION; | |
| 45 when SCROLL: index = TYP_SCROLL; | |
| 46 when FOOD: index = TYP_FOOD; | |
| 47 when RING: index = TYP_RING; | |
| 48 when AMULET: index = TYP_AMULET; | |
| 49 when ARMOR: index = TYP_ARMOR; | |
| 50 when WEAPON: index = TYP_WEAPON; | |
| 51 when STICK: index = TYP_STICK; | |
| 52 } | |
| 53 return index; | |
| 54 } | |
| 55 | |
| 56 /* | |
| 57 * tr_name: | |
| 58 * print the name of a trap | |
| 59 */ | |
| 60 char * | |
| 61 tr_name(ch) | |
| 62 char ch; | |
| 63 { | |
| 64 reg char *s; | |
| 65 | |
| 66 switch (ch) { | |
| 67 case TRAPDOOR: | |
| 68 s = "A trapdoor."; | |
| 69 when BEARTRAP: | |
| 70 s = "A beartrap."; | |
| 71 when SLEEPTRAP: | |
| 72 s = "A sleeping gas trap."; | |
| 73 when ARROWTRAP: | |
| 74 s = "An arrow trap."; | |
| 75 when TELTRAP: | |
| 76 s = "A teleport trap."; | |
| 77 when DARTTRAP: | |
| 78 s = "A dart trap."; | |
| 79 when POOL: | |
| 80 s = "A magic pool."; | |
| 81 when POST: | |
| 82 s = "A trading post."; | |
| 83 when MAZETRAP: | |
| 84 s = "A maze trap."; | |
| 85 otherwise: | |
| 86 s = "A bottomless pit."; /* shouldn't get here */ | |
| 87 } | |
| 88 return s; | |
| 89 } | |
| 90 | |
| 91 /* | |
| 92 * Look: | |
| 93 * A quick glance all around the player | |
| 94 */ | |
| 95 look(wakeup) | |
| 96 bool wakeup; | |
| 97 { | |
| 98 reg char ch; | |
| 99 reg int oldx, oldy, y, x; | |
| 100 reg struct room *rp; | |
| 101 int ey, ex, oex, oey; | |
| 102 int passcount = 0; | |
| 103 bool inpass, blind; | |
| 104 | |
| 105 getyx(cw, oldy, oldx); | |
| 106 oex = player.t_oldpos.x; | |
| 107 oey = player.t_oldpos.y; | |
| 108 blind = pl_on(ISBLIND); | |
| 109 if ((oldrp != NULL && rf_on(oldrp,ISDARK)) || blind) { | |
| 110 for (x = oex - 1; x <= oex + 1; x += 1) | |
| 111 for (y = oey - 1; y <= oey + 1; y += 1) | |
| 112 if ((y != hero.y || x != hero.x) && show(y, x) == FLOOR) | |
| 113 mvwaddch(cw, y, x, ' '); | |
| 114 } | |
| 115 rp = player.t_room; | |
| 116 inpass = (rp == NULL); /* TRUE when not in a room */ | |
| 117 ey = hero.y + 1; | |
| 118 ex = hero.x + 1; | |
| 119 for (x = hero.x - 1; x <= ex; x += 1) { | |
| 120 if (x >= 0 && x <= COLS - 1) { | |
| 121 for (y = hero.y - 1; y <= ey; y += 1) { | |
| 122 if (y <= 0 || y >= LINES - 2) | |
| 123 continue; | |
| 124 if (isalpha(mvwinch(mw, y, x))) { | |
| 125 reg struct linked_list *it; | |
| 126 reg struct thing *tp; | |
| 127 | |
| 128 if (wakeup || (!inpass && rf_on(rp, ISTREAS))) | |
| 129 it = wake_monster(y, x); | |
| 130 else | |
| 131 it = find_mons(y, x); | |
| 132 if (it == NULL) /* lost monster */ | |
| 133 mvaddch(y, x, FLOOR); | |
| 134 else { | |
| 135 tp = THINGPTR(it); | |
| 136 if (isatrap(tp->t_oldch = mvinch(y, x))) { | |
| 137 struct trap *trp; | |
| 138 | |
| 139 if ((trp = trap_at(y,x)) == NULL) | |
| 140 break; | |
| 141 if (trp->tr_flags & ISFOUND) | |
| 142 tp->t_oldch = trp->tr_type; | |
| 143 else | |
| 144 tp->t_oldch = FLOOR; | |
| 145 } | |
| 146 if (tp->t_oldch == FLOOR && rf_on(rp,ISDARK)) | |
| 147 if (!blind) | |
| 148 tp->t_oldch = ' '; | |
| 149 } | |
| 150 } | |
| 151 /* | |
| 152 * Secret doors show as walls | |
| 153 */ | |
| 154 if ((ch = show(y, x)) == SECRETDOOR) { | |
| 155 if (inpass || y == rp->r_pos.y || y == rp->r_pos.y + rp->r_max.y - 1) | |
| 156 ch = '-'; | |
| 157 else | |
| 158 ch = '|'; | |
| 159 } | |
| 160 /* | |
| 161 * Don't show room walls if he is in a passage | |
| 162 */ | |
| 163 if (!blind) { | |
| 164 if ((y == hero.y && x == hero.x) || (inpass && (ch == '-' || ch == '|'))) | |
| 165 continue; | |
| 166 } | |
| 167 else | |
| 168 ch = ' '; | |
| 169 wmove(cw, y, x); | |
| 170 waddch(cw, ch); | |
| 171 if (door_stop && !firstmove && running) { | |
| 172 switch (runch) { | |
| 173 case 'h': | |
| 174 if (x == ex) | |
| 175 continue; | |
| 176 when 'j': | |
| 177 if (y == hero.y - 1) | |
| 178 continue; | |
| 179 when 'k': | |
| 180 if (y == ey) | |
| 181 continue; | |
| 182 when 'l': | |
| 183 if (x == hero.x - 1) | |
| 184 continue; | |
| 185 when 'y': | |
| 186 if ((x + y) - (hero.x + hero.y) >= 1) | |
| 187 continue; | |
| 188 when 'u': | |
| 189 if ((y - x) - (hero.y - hero.x) >= 1) | |
| 190 continue; | |
| 191 when 'n': | |
| 192 if ((x + y) - (hero.x + hero.y) <= -1) | |
| 193 continue; | |
| 194 when 'b': | |
| 195 if ((y - x) - (hero.y - hero.x) <= -1) | |
| 196 continue; | |
| 197 } | |
| 198 switch (ch) { | |
| 199 case DOOR: | |
| 200 if (x == hero.x || y == hero.y) | |
| 201 running = FALSE; | |
| 202 break; | |
| 203 case PASSAGE: | |
| 204 if (x == hero.x || y == hero.y) | |
| 205 passcount += 1; | |
| 206 break; | |
| 207 case FLOOR: | |
| 208 case '|': | |
| 209 case '-': | |
| 210 case ' ': | |
| 211 break; | |
| 212 default: | |
| 213 running = FALSE; | |
| 214 break; | |
| 215 } | |
| 216 } | |
| 217 } | |
| 218 } | |
| 219 } | |
| 220 if (door_stop && !firstmove && passcount > 1) | |
| 221 running = FALSE; | |
| 222 mvwaddch(cw, hero.y, hero.x, PLAYER); | |
| 223 wmove(cw, oldy, oldx); | |
| 224 player.t_oldpos = hero; | |
| 225 oldrp = rp; | |
| 226 } | |
| 227 | |
| 228 /* | |
| 229 * find_obj: | |
| 230 * find the unclaimed object at y, x | |
| 231 */ | |
| 232 struct linked_list * | |
| 233 find_obj(y, x) | |
| 234 int y, x; | |
| 235 { | |
| 236 reg struct linked_list *obj; | |
| 237 reg struct object *op; | |
| 238 | |
| 239 for (obj = lvl_obj; obj != NULL; obj = next(obj)) { | |
| 240 op = OBJPTR(obj); | |
| 241 if (op->o_pos.y == y && op->o_pos.x == x) | |
| 242 return obj; | |
| 243 } | |
| 244 return NULL; | |
| 245 } | |
| 246 | |
| 247 /* | |
| 248 * eat: | |
| 249 * Let the hero eat some food. | |
| 250 */ | |
| 251 eat() | |
| 252 { | |
| 253 reg struct linked_list *item; | |
| 254 reg struct object *obj; | |
| 255 reg int goodfood, cursed; | |
| 256 | |
| 257 if ((item = get_item("eat", FOOD)) == NULL) | |
| 258 return; | |
| 259 obj = OBJPTR(item); | |
| 260 if (obj->o_type != FOOD) { | |
| 261 msg("That's Inedible!"); | |
| 262 after = FALSE; | |
| 263 return; | |
| 264 } | |
| 265 cursed = 1; | |
| 266 if (o_on(obj, ISCURSED)) | |
| 267 cursed += 1; | |
| 268 else if (o_on(obj, ISBLESS)) | |
| 269 cursed -= 1; | |
| 270 if (obj->o_which == FRUITFOOD) { | |
| 271 msg("My, that was a yummy %s.", fruit); | |
| 272 goodfood = 100; | |
| 273 } | |
| 274 else { | |
| 275 if (rnd(100) > 80 || o_on(obj, ISCURSED)) { | |
| 276 msg("Yuk, this food tastes like ARA."); | |
| 277 goodfood = 300; | |
| 278 him->s_exp += 1; | |
| 279 check_level(); | |
| 280 } | |
| 281 else { | |
| 282 msg("Yum, that tasted good."); | |
| 283 goodfood = 200; | |
| 284 } | |
| 285 } | |
| 286 goodfood *= cursed; | |
| 287 if ((food_left += HUNGERTIME + rnd(400) - goodfood) > STOMACHSIZE) | |
| 288 food_left = STOMACHSIZE; | |
| 289 hungry_state = F_OKAY; | |
| 290 updpack(); /* update pack */ | |
| 291 if (obj == cur_weapon) | |
| 292 cur_weapon = NULL; | |
| 293 del_pack(item); /* get rid of the food */ | |
| 294 } | |
| 295 | |
| 296 /* | |
| 297 * aggravate: | |
| 298 * aggravate all the monsters on this level | |
| 299 */ | |
| 300 aggravate() | |
| 301 { | |
| 302 reg struct linked_list *mi; | |
| 303 | |
| 304 for (mi = mlist; mi != NULL; mi = next(mi)) | |
| 305 runto(&(THINGPTR(mi))->t_pos, &hero); | |
| 306 } | |
| 307 | |
| 308 /* | |
| 309 * vowelstr: | |
| 310 * If string starts with a vowel, return "n" for an "an" | |
| 311 */ | |
| 312 char * | |
| 313 vowelstr(str) | |
| 314 char *str; | |
| 315 { | |
| 316 switch (tolower(*str)) { | |
| 317 case 'a': | |
| 318 case 'e': | |
| 319 case 'i': | |
| 320 case 'o': | |
| 321 case 'u': | |
| 322 return "n"; | |
| 323 default: | |
| 324 return ""; | |
| 325 } | |
| 326 } | |
| 327 | |
| 328 /* | |
| 329 * is_current: | |
| 330 * See if the object is one of the currently used items | |
| 331 */ | |
| 332 is_current(obj) | |
| 333 struct object *obj; | |
| 334 { | |
| 335 if (obj == NULL) | |
| 336 return FALSE; | |
| 337 if (obj == cur_armor || obj == cur_weapon || obj == cur_ring[LEFT] | |
| 338 || obj == cur_ring[RIGHT]) { | |
| 339 msg("Already in use."); | |
| 340 return TRUE; | |
| 341 } | |
| 342 return FALSE; | |
| 343 } | |
| 344 | |
| 345 /* | |
| 346 * get_dir: | |
| 347 * Set up the direction coordinates | |
| 348 */ | |
| 349 get_dir() | |
| 350 { | |
| 351 reg char *prompt; | |
| 352 reg bool gotit; | |
| 353 | |
| 354 prompt = "Direction: "; | |
| 355 do { | |
| 356 gotit = TRUE; | |
| 357 switch (readchar()) { | |
| 358 case 'h': case'H': delta.y = 0; delta.x = -1; | |
| 359 when 'j': case'J': delta.y = 1; delta.x = 0; | |
| 360 when 'k': case'K': delta.y = -1; delta.x = 0; | |
| 361 when 'l': case'L': delta.y = 0; delta.x = 1; | |
| 362 when 'y': case'Y': delta.y = -1; delta.x = -1; | |
| 363 when 'u': case'U': delta.y = -1; delta.x = 1; | |
| 364 when 'b': case'B': delta.y = 1; delta.x = -1; | |
| 365 when 'n': case'N': delta.y = 1; delta.x = 1; | |
| 366 when ESCAPE: return FALSE; | |
| 367 otherwise: | |
| 368 mpos = 0; | |
| 369 msg(prompt); | |
| 370 gotit = FALSE; | |
| 371 } | |
| 372 } until (gotit); | |
| 373 if (pl_on(ISHUH) && rnd(100) > 80) { | |
| 374 do { | |
| 375 delta.y = rnd(3) - 1; | |
| 376 delta.x = rnd(3) - 1; | |
| 377 } while (delta.y == 0 && delta.x == 0); | |
| 378 } | |
| 379 mpos = 0; | |
| 380 return TRUE; | |
| 381 } | |
| 382 | |
| 383 /* | |
| 384 * initfood: | |
| 385 * Set up stuff for a food-type object | |
| 386 */ | |
| 387 initfood(what) | |
