1 /* 2 * Copyright (c) 1988 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Timothy C. Stoehr. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)use.c 5.3 (Berkeley) 06/01/90"; 13 #endif /* not lint */ 14 15 /* 16 * use.c 17 * 18 * This source herein may be modified and/or distributed by anybody who 19 * so desires, with the following restrictions: 20 * 1.) No portion of this notice shall be removed. 21 * 2.) Credit shall not be taken for the creation of this source. 22 * 3.) This code is not to be traded, sold, or used for personal 23 * gain or profit. 24 * 25 */ 26 27 #include "rogue.h" 28 29 short halluc = 0; 30 short blind = 0; 31 short confused = 0; 32 short levitate = 0; 33 short haste_self = 0; 34 boolean see_invisible = 0; 35 short extra_hp = 0; 36 boolean detect_monster = 0; 37 boolean con_mon = 0; 38 char *strange_feeling = "you have a strange feeling for a moment, then it passes"; 39 40 extern short bear_trap; 41 extern char hunger_str[]; 42 extern short cur_room; 43 extern long level_points[]; 44 extern boolean being_held; 45 extern char *fruit, *you_can_move_again; 46 extern boolean sustain_strength; 47 48 quaff() 49 { 50 short ch; 51 char buf[80]; 52 object *obj; 53 54 ch = pack_letter("quaff what?", POTION); 55 56 if (ch == CANCEL) { 57 return; 58 } 59 if (!(obj = get_letter_object(ch))) { 60 message("no such item.", 0); 61 return; 62 } 63 if (obj->what_is != POTION) { 64 message("you can't drink that", 0); 65 return; 66 } 67 switch(obj->which_kind) { 68 case INCREASE_STRENGTH: 69 message("you feel stronger now, what bulging muscles!", 70 0); 71 rogue.str_current++; 72 if (rogue.str_current > rogue.str_max) { 73 rogue.str_max = rogue.str_current; 74 } 75 break; 76 case RESTORE_STRENGTH: 77 rogue.str_current = rogue.str_max; 78 message("this tastes great, you feel warm all over", 0); 79 break; 80 case HEALING: 81 message("you begin to feel better", 0); 82 potion_heal(0); 83 break; 84 case EXTRA_HEALING: 85 message("you begin to feel much better", 0); 86 potion_heal(1); 87 break; 88 case POISON: 89 if (!sustain_strength) { 90 rogue.str_current -= get_rand(1, 3); 91 if (rogue.str_current < 1) { 92 rogue.str_current = 1; 93 } 94 } 95 message("you feel very sick now", 0); 96 if (halluc) { 97 unhallucinate(); 98 } 99 break; 100 case RAISE_LEVEL: 101 rogue.exp_points = level_points[rogue.exp - 1]; 102 message("you suddenly feel much more skillful", 0); 103 add_exp(1, 1); 104 break; 105 case BLINDNESS: 106 go_blind(); 107 break; 108 case HALLUCINATION: 109 message("oh wow, everything seems so cosmic", 0); 110 halluc += get_rand(500, 800); 111 break; 112 case DETECT_MONSTER: 113 show_monsters(); 114 if (!(level_monsters.next_monster)) { 115 message(strange_feeling, 0); 116 } 117 break; 118 case DETECT_OBJECTS: 119 if (level_objects.next_object) { 120 if (!blind) { 121 show_objects(); 122 } 123 } else { 124 message(strange_feeling, 0); 125 } 126 break; 127 case CONFUSION: 128 message((halluc ? "what a trippy feeling" : 129 "you feel confused"), 0); 130 cnfs(); 131 break; 132 case LEVITATION: 133 message("you start to float in the air", 0); 134 levitate += get_rand(15, 30); 135 being_held = bear_trap = 0; 136 break; 137 case HASTE_SELF: 138 message("you feel yourself moving much faster", 0); 139 haste_self += get_rand(11, 21); 140 if (!(haste_self % 2)) { 141 haste_self++; 142 } 143 break; 144 case SEE_INVISIBLE: 145 sprintf(buf, "hmm, this potion tastes like %sjuice", fruit); 146 message(buf, 0); 147 if (blind) { 148 unblind(); 149 } 150 see_invisible = 1; 151 relight(); 152 break; 153 } 154 print_stats((STAT_STRENGTH | STAT_HP)); 155 if (id_potions[obj->which_kind].id_status != CALLED) { 156 id_potions[obj->which_kind].id_status = IDENTIFIED; 157 } 158 vanish(obj, 1, &rogue.pack); 159 } 160 161 read_scroll() 162 { 163 short ch; 164 object *obj; 165 char msg[DCOLS]; 166 167 ch = pack_letter("read what?", SCROL); 168 169 if (ch == CANCEL) { 170 return; 171 } 172 if (!(obj = get_letter_object(ch))) { 173 message("no such item.", 0); 174 return; 175 } 176 if (obj->what_is != SCROL) { 177 message("you can't read that", 0); 178 return; 179 } 180 switch(obj->which_kind) { 181 case SCARE_MONSTER: 182 message("you hear a maniacal laughter in the distance", 183 0); 184 break; 185 case HOLD_MONSTER: 186 hold_monster(); 187 break; 188 case ENCH_WEAPON: 189 if (rogue.weapon) { 190 if (rogue.weapon->what_is == WEAPON) { 191 sprintf(msg, "your %sglow%s %sfor a moment", 192 name_of(rogue.weapon), 193 ((rogue.weapon->quantity <= 1) ? "s" : ""), 194 get_ench_color()); 195 message(msg, 0); 196 if (coin_toss()) { 197 rogue.weapon->hit_enchant++; 198 } else { 199 rogue.weapon->d_enchant++; 200 } 201 } 202 rogue.weapon->is_cursed = 0; 203 } else { 204 message("your hands tingle", 0); 205 } 206 break; 207 case ENCH_ARMOR: 208 if (rogue.armor) { 209 sprintf(msg, "your armor glows %sfor a moment", 210 get_ench_color()); 211 message(msg, 0); 212 rogue.armor->d_enchant++; 213 rogue.armor->is_cursed = 0; 214 print_stats(STAT_ARMOR); 215 } else { 216 message("your skin crawls", 0); 217 } 218 break; 219 case IDENTIFY: 220 message("this is a scroll of identify", 0); 221 obj->identified = 1; 222 id_scrolls[obj->which_kind].id_status = IDENTIFIED; 223 idntfy(); 224 break; 225 case TELEPORT: 226 tele(); 227 break; 228 case SLEEP: 229 message("you fall asleep", 0); 230 take_a_nap(); 231 break; 232 case PROTECT_ARMOR: 233 if (rogue.armor) { 234 message( "your armor is covered by a shimmering gold shield",0); 235 rogue.armor->is_protected = 1; 236 rogue.armor->is_cursed = 0; 237 } else { 238 message("your acne seems to have disappeared", 0); 239 } 240 break; 241 case REMOVE_CURSE: 242 message((!halluc) ? 243 "you feel as though someone is watching over you" : 244 "you feel in touch with the universal oneness", 0); 245 uncurse_all(); 246 break; 247 case CREATE_MONSTER: 248 create_monster(); 249 break; 250 case AGGRAVATE_MONSTER: 251 aggravate(); 252 break; 253 case MAGIC_MAPPING: 254 message("this scroll seems to have a map on it", 0); 255 draw_magic_map(); 256 break; 257 case CON_MON: 258 con_mon = 1; 259 sprintf(msg, "your hands glow %sfor a moment", get_ench_color()); 260 message(msg, 0); 261 break; 262 } 263 if (id_scrolls[obj->which_kind].id_status != CALLED) { 264 id_scrolls[obj->which_kind].id_status = IDENTIFIED; 265 } 266 vanish(obj, (obj->which_kind != SLEEP), &rogue.pack); 267 } 268 269 /* vanish() does NOT handle a quiver of weapons with more than one 270 * arrow (or whatever) in the quiver. It will only decrement the count. 271 */ 272 273 vanish(obj, rm, pack) 274 object *obj; 275 short rm; 276 object *pack; 277 { 278 if (obj->quantity > 1) { 279 obj->quantity--; 280 } else { 281 if (obj->in_use_flags & BEING_WIELDED) { 282 unwield(obj); 283 } else if (obj->in_use_flags & BEING_WORN) { 284 unwear(obj); 285 } else if (obj->in_use_flags & ON_EITHER_HAND) { 286 un_put_on(obj); 287 } 288 take_from_pack(obj, pack); 289 free_object(obj); 290 } 291 if (rm) { 292 (void) reg_move(); 293 } 294 } 295 296 potion_heal(extra) 297 { 298 float ratio; 299 short add; 300 301 rogue.hp_current += rogue.exp; 302 303 ratio = ((float)rogue.hp_current) / rogue.hp_max; 304 305 if (ratio >= 1.00) { 306 rogue.hp_max += (extra ? 2 : 1); 307 extra_hp += (extra ? 2 : 1); 308 rogue.hp_current = rogue.hp_max; 309 } else if (ratio >= 0.90) { 310 rogue.hp_max += (extra ? 1 : 0); 311 extra_hp += (extra ? 1 : 0); 312 rogue.hp_current = rogue.hp_max; 313 } else { 314 if (ratio < 0.33) { 315 ratio = 0.33; 316 } 317 if (extra) { 318 ratio += ratio; 319 } 320 add = (short)(ratio * ((float)rogue.hp_max - rogue.hp_current)); 321 rogue.hp_current += add; 322 if (rogue.hp_current > rogue.hp_max) { 323 rogue.hp_current = rogue.hp_max; 324 } 325 } 326 if (blind) { 327 unblind(); 328 } 329 if (confused && extra) { 330 unconfuse(); 331 } else if (confused) { 332 confused = (confused / 2) + 1; 333 } 334 if (halluc && extra) { 335 unhallucinate(); 336 } else if (halluc) { 337 halluc = (halluc / 2) + 1; 338 } 339 } 340 341 idntfy() 342 { 343 short ch; 344 object *obj; 345 struct id *id_table; 346 char desc[DCOLS]; 347 AGAIN: 348 ch = pack_letter("what would you like to identify?", ALL_OBJECTS); 349 350 if (ch == CANCEL) { 351 return; 352 } 353 if (!(obj = get_letter_object(ch))) { 354 message("no such item, try again", 0); 355 message("", 0); 356 check_message(); 357 goto AGAIN; 358 } 359 obj->identified = 1; 360 if (obj->what_is & (SCROL | POTION | WEAPON | ARMOR | WAND | RING)) { 361 id_table = get_id_table(obj); 362 id_table[obj->which_kind].id_status = IDENTIFIED; 363 } 364 get_desc(obj, desc); 365 message(desc, 0); 366 } 367 368 eat() 369 { 370 short ch; 371 short moves; 372 object *obj; 373 char buf[70]; 374 375 ch = pack_letter("eat what?", FOOD); 376 377 if (ch == CANCEL) { 378 return; 379 } 380 if (!(obj = get_letter_object(ch))) { 381 message("no such item.", 0); 382 return; 383 } 384 if (obj->what_is != FOOD) { 385 message("you can't eat that", 0); 386 return; 387 } 388 if ((obj->which_kind == FRUIT) || rand_percent(60)) { 389 moves = get_rand(950, 1150); 390 if (obj->which_kind == RATION) { 391 message("yum, that tasted good", 0); 392 } else { 393 sprintf(buf, "my, that was a yummy %s", fruit); 394 message(buf, 0); 395 } 396 } else { 397 moves = get_rand(750, 950); 398 message("yuk, that food tasted awful", 0); 399 add_exp(2, 1); 400 } 401 rogue.moves_left /= 3; 402 rogue.moves_left += moves; 403 hunger_str[0] = 0; 404 print_stats(STAT_HUNGER); 405 406 vanish(obj, 1, &rogue.pack); 407 } 408 409 hold_monster() 410 { 411 short i, j; 412 short mcount = 0; 413 object *monster; 414 short row, col; 415 416 for (i = -2; i <= 2; i++) { 417 for (j = -2; j <= 2; j++) { 418 row = rogue.row + i; 419 col = rogue.col + j; 420 if ((row < MIN_ROW) || (row > (DROWS-2)) || (col < 0) || 421 (col > (DCOLS-1))) { 422 continue; 423 } 424 if (dungeon[row][col] & MONSTER) { 425 monster = object_at(&level_monsters, row, col); 426 monster->m_flags |= ASLEEP; 427 monster->m_flags &= (~WAKENS); 428 mcount++; 429 } 430 } 431 } 432 if (mcount == 0) { 433 message("you feel a strange sense of loss", 0); 434 } else if (mcount == 1) { 435 message("the monster freezes", 0); 436 } else { 437 message("the monsters around you freeze", 0); 438 } 439 } 440 441 tele() 442 { 443 mvaddch(rogue.row, rogue.col, get_dungeon_char(rogue.row, rogue.col)); 444 445 if (cur_room >= 0) { 446 darken_room(cur_room); 447 } 448 put_player(get_room_number(rogue.row, rogue.col)); 449 being_held = 0; 450 bear_trap = 0; 451 } 452 453 hallucinate() 454 { 455 object *obj, *monster; 456 short ch; 457 458 if (blind) return; 459 460 obj = level_objects.next_object; 461 462 while (obj) { 463 ch = mvinch(obj->row, obj->col); 464 if (((ch < 'A') || (ch > 'Z')) && 465 ((obj->row != rogue.row) || (obj->col != rogue.col))) 466 if ((ch != ' ') && (ch != '.') && (ch != '#') && (ch != '+')) { 467 addch(gr_obj_char()); 468 } 469 obj = obj->next_object; 470 } 471 monster = level_monsters.next_monster; 472 473 while (monster) { 474 ch = mvinch(monster->row, monster->col); 475 if ((ch >= 'A') && (ch <= 'Z')) { 476 addch(get_rand('A', 'Z')); 477 } 478 monster = monster->next_monster; 479 } 480 } 481 482 unhallucinate() 483 { 484 halluc = 0; 485 relight(); 486 message("everything looks SO boring now", 1); 487 } 488 489 unblind() 490 { 491 blind = 0; 492 message("the veil of darkness lifts", 1); 493 relight(); 494 if (halluc) { 495 hallucinate(); 496 } 497 if (detect_monster) { 498 show_monsters(); 499 } 500 } 501 502 relight() 503 { 504 if (cur_room == PASSAGE) { 505 light_passage(rogue.row, rogue.col); 506 } else { 507 light_up_room(cur_room); 508 } 509 mvaddch(rogue.row, rogue.col, rogue.fchar); 510 } 511 512 take_a_nap() 513 { 514 short i; 515 516 i = get_rand(2, 5); 517 md_sleep(1); 518 519 while (i--) { 520 mv_mons(); 521 } 522 md_sleep(1); 523 message(you_can_move_again, 0); 524 } 525 526 go_blind() 527 { 528 short i, j; 529 530 if (!blind) { 531 message("a cloak of darkness falls around you", 0); 532 } 533 blind += get_rand(500, 800); 534 535 if (detect_monster) { 536 object *monster; 537 538 monster = level_monsters.next_monster; 539 540 while (monster) { 541 mvaddch(monster->row, monster->col, monster->trail_char); 542 monster = monster->next_monster; 543 } 544 } 545 if (cur_room >= 0) { 546 for (i = rooms[cur_room].top_row + 1; 547 i < rooms[cur_room].bottom_row; i++) { 548 for (j = rooms[cur_room].left_col + 1; 549 j < rooms[cur_room].right_col; j++) { 550 mvaddch(i, j, ' '); 551 } 552 } 553 } 554 mvaddch(rogue.row, rogue.col, rogue.fchar); 555 } 556 557 char * 558 get_ench_color() 559 { 560 if (halluc) { 561 return(id_potions[get_rand(0, POTIONS-1)].title); 562 } else if (con_mon) { 563 return("red "); 564 } 565 return("blue "); 566 } 567 568 cnfs() 569 { 570 confused += get_rand(12, 22); 571 } 572 573 unconfuse() 574 { 575 char msg[80]; 576 577 confused = 0; 578 sprintf(msg, "you feel less %s now", (halluc ? "trippy" : "confused")); 579 message(msg, 1); 580 } 581 582 uncurse_all() 583 { 584 object *obj; 585 586 obj = rogue.pack.next_object; 587 588 while (obj) { 589 obj->is_cursed = 0; 590 obj = obj->next_object; 591 } 592 } 593