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