132689Sbostic /* 236704Sbostic * Copyright (c) 1988 The Regents of the University of California. 336704Sbostic * All rights reserved. 436704Sbostic * 536704Sbostic * This code is derived from software contributed to Berkeley by 636704Sbostic * Timothy C. Stoehr. 736704Sbostic * 8*42601Sbostic * %sccs.include.redist.c% 936704Sbostic */ 1036704Sbostic 1136704Sbostic #ifndef lint 12*42601Sbostic static char sccsid[] = "@(#)ring.c 5.3 (Berkeley) 06/01/90"; 1336704Sbostic #endif /* not lint */ 1436704Sbostic 1536704Sbostic /* 1632689Sbostic * ring.c 1732689Sbostic * 1832689Sbostic * This source herein may be modified and/or distributed by anybody who 1932689Sbostic * so desires, with the following restrictions: 2032689Sbostic * 1.) No portion of this notice shall be removed. 2132689Sbostic * 2.) Credit shall not be taken for the creation of this source. 2232689Sbostic * 3.) This code is not to be traded, sold, or used for personal 2332689Sbostic * gain or profit. 2432689Sbostic * 2532689Sbostic */ 2632689Sbostic 2732689Sbostic #include "rogue.h" 2832689Sbostic 2932689Sbostic char *left_or_right = "left or right hand?"; 3032689Sbostic char *no_ring = "there's no ring on that hand"; 3132689Sbostic short stealthy; 3232689Sbostic short r_rings; 3332689Sbostic short add_strength; 3432689Sbostic short e_rings; 3532689Sbostic short regeneration; 3632689Sbostic short ring_exp; 3732689Sbostic short auto_search; 3832689Sbostic boolean r_teleport; 3932689Sbostic boolean r_see_invisible; 4032689Sbostic boolean sustain_strength; 4132689Sbostic boolean maintain_armor; 4232689Sbostic 4332689Sbostic extern char *curse_message; 4432689Sbostic extern boolean wizard; 4532689Sbostic 4632689Sbostic put_on_ring() 4732689Sbostic { 4832689Sbostic short ch; 4932689Sbostic char desc[DCOLS]; 5032689Sbostic object *ring; 5132689Sbostic 5232689Sbostic if (r_rings == 2) { 5332689Sbostic message("wearing two rings already", 0); 5432689Sbostic return; 5532689Sbostic } 5632689Sbostic if ((ch = pack_letter("put on what?", RING)) == CANCEL) { 5732689Sbostic return; 5832689Sbostic } 5932689Sbostic if (!(ring = get_letter_object(ch))) { 6032689Sbostic message("no such item.", 0); 6132689Sbostic return; 6232689Sbostic } 6332689Sbostic if (!(ring->what_is & RING)) { 6432689Sbostic message("that's not a ring", 0); 6532689Sbostic return; 6632689Sbostic } 6732689Sbostic if (ring->in_use_flags & (ON_LEFT_HAND | ON_RIGHT_HAND)) { 6832689Sbostic message("that ring is already being worn", 0); 6932689Sbostic return; 7032689Sbostic } 7132689Sbostic if (r_rings == 1) { 7232689Sbostic ch = (rogue.left_ring ? 'r' : 'l'); 7332689Sbostic } else { 7432689Sbostic message(left_or_right, 0); 7532689Sbostic do { 7632689Sbostic ch = rgetchar(); 7732689Sbostic } while ((ch != CANCEL) && (ch != 'l') && (ch != 'r') && (ch != '\n') && 7832689Sbostic (ch != '\r')); 7932689Sbostic } 8032689Sbostic if ((ch != 'l') && (ch != 'r')) { 8132689Sbostic check_message(); 8232689Sbostic return; 8332689Sbostic } 8432689Sbostic if (((ch == 'l') && rogue.left_ring)||((ch == 'r') && rogue.right_ring)) { 8532689Sbostic check_message(); 8632689Sbostic message("there's already a ring on that hand", 0); 8732689Sbostic return; 8832689Sbostic } 8932689Sbostic if (ch == 'l') { 9032689Sbostic do_put_on(ring, 1); 9132689Sbostic } else { 9232689Sbostic do_put_on(ring, 0); 9332689Sbostic } 9432689Sbostic ring_stats(1); 9532689Sbostic check_message(); 9632689Sbostic get_desc(ring, desc); 9732689Sbostic message(desc, 0); 9832689Sbostic (void) reg_move(); 9932689Sbostic } 10032689Sbostic 10132689Sbostic /* 10232689Sbostic * Do not call ring_stats() from within do_put_on(). It will cause 10332689Sbostic * serious problems when do_put_on() is called from read_pack() in restore(). 10432689Sbostic */ 10532689Sbostic 10632689Sbostic do_put_on(ring, on_left) 10732689Sbostic object *ring; 10832689Sbostic boolean on_left; 10932689Sbostic { 11032689Sbostic if (on_left) { 11132689Sbostic ring->in_use_flags |= ON_LEFT_HAND; 11232689Sbostic rogue.left_ring = ring; 11332689Sbostic } else { 11432689Sbostic ring->in_use_flags |= ON_RIGHT_HAND; 11532689Sbostic rogue.right_ring = ring; 11632689Sbostic } 11732689Sbostic } 11832689Sbostic 11932689Sbostic remove_ring() 12032689Sbostic { 12132689Sbostic boolean left = 0, right = 0; 12232689Sbostic short ch; 12332689Sbostic char buf[DCOLS]; 12432689Sbostic object *ring; 12532689Sbostic 12632689Sbostic if (r_rings == 0) { 12732689Sbostic inv_rings(); 12832689Sbostic } else if (rogue.left_ring && !rogue.right_ring) { 12932689Sbostic left = 1; 13032689Sbostic } else if (!rogue.left_ring && rogue.right_ring) { 13132689Sbostic right = 1; 13232689Sbostic } else { 13332689Sbostic message(left_or_right, 0); 13432689Sbostic do { 13532689Sbostic ch = rgetchar(); 13632689Sbostic } while ((ch != CANCEL) && (ch != 'l') && (ch != 'r') && 13732689Sbostic (ch != '\n') && (ch != '\r')); 13832689Sbostic left = (ch == 'l'); 13932689Sbostic right = (ch == 'r'); 14032689Sbostic check_message(); 14132689Sbostic } 14232689Sbostic if (left || right) { 14332689Sbostic if (left) { 14432689Sbostic if (rogue.left_ring) { 14532689Sbostic ring = rogue.left_ring; 14632689Sbostic } else { 14732689Sbostic message(no_ring, 0); 14832689Sbostic } 14932689Sbostic } else { 15032689Sbostic if (rogue.right_ring) { 15132689Sbostic ring = rogue.right_ring; 15232689Sbostic } else { 15332689Sbostic message(no_ring, 0); 15432689Sbostic } 15532689Sbostic } 15632689Sbostic if (ring->is_cursed) { 15732689Sbostic message(curse_message, 0); 15832689Sbostic } else { 15932689Sbostic un_put_on(ring); 16032689Sbostic (void) strcpy(buf, "removed "); 16132689Sbostic get_desc(ring, buf + 8); 16232689Sbostic message(buf, 0); 16332689Sbostic (void) reg_move(); 16432689Sbostic } 16532689Sbostic } 16632689Sbostic } 16732689Sbostic 16832689Sbostic un_put_on(ring) 16932689Sbostic object *ring; 17032689Sbostic { 17132689Sbostic if (ring && (ring->in_use_flags & ON_LEFT_HAND)) { 17232689Sbostic ring->in_use_flags &= (~ON_LEFT_HAND); 17332689Sbostic rogue.left_ring = 0; 17432689Sbostic } else if (ring && (ring->in_use_flags & ON_RIGHT_HAND)) { 17532689Sbostic ring->in_use_flags &= (~ON_RIGHT_HAND); 17632689Sbostic rogue.right_ring = 0; 17732689Sbostic } 17832689Sbostic ring_stats(1); 17932689Sbostic } 18032689Sbostic 18132689Sbostic gr_ring(ring, assign_wk) 18232689Sbostic object *ring; 18332689Sbostic boolean assign_wk; 18432689Sbostic { 18532689Sbostic ring->what_is = RING; 18632689Sbostic if (assign_wk) { 18732689Sbostic ring->which_kind = get_rand(0, (RINGS - 1)); 18832689Sbostic } 18932689Sbostic ring->class = 0; 19032689Sbostic 19132689Sbostic switch(ring->which_kind) { 19232689Sbostic /* 19332689Sbostic case STEALTH: 19432689Sbostic break; 19532689Sbostic case SLOW_DIGEST: 19632689Sbostic break; 19732689Sbostic case REGENERATION: 19832689Sbostic break; 19932689Sbostic case R_SEE_INVISIBLE: 20032689Sbostic break; 20132689Sbostic case SUSTAIN_STRENGTH: 20232689Sbostic break; 20332689Sbostic case R_MAINTAIN_ARMOR: 20432689Sbostic break; 20532689Sbostic case SEARCHING: 20632689Sbostic break; 20732689Sbostic */ 20832689Sbostic case R_TELEPORT: 20932689Sbostic ring->is_cursed = 1; 21032689Sbostic break; 21132689Sbostic case ADD_STRENGTH: 21232689Sbostic case DEXTERITY: 21332689Sbostic while ((ring->class = (get_rand(0, 4) - 2)) == 0) ; 21432689Sbostic ring->is_cursed = (ring->class < 0); 21532689Sbostic break; 21632689Sbostic case ADORNMENT: 21732689Sbostic ring->is_cursed = coin_toss(); 21832689Sbostic break; 21932689Sbostic } 22032689Sbostic } 22132689Sbostic 22232689Sbostic inv_rings() 22332689Sbostic { 22432689Sbostic char buf[DCOLS]; 22532689Sbostic 22632689Sbostic if (r_rings == 0) { 22732689Sbostic message("not wearing any rings", 0); 22832689Sbostic } else { 22932689Sbostic if (rogue.left_ring) { 23032689Sbostic get_desc(rogue.left_ring, buf); 23132689Sbostic message(buf, 0); 23232689Sbostic } 23332689Sbostic if (rogue.right_ring) { 23432689Sbostic get_desc(rogue.right_ring, buf); 23532689Sbostic message(buf, 0); 23632689Sbostic } 23732689Sbostic } 23832689Sbostic if (wizard) { 23932689Sbostic sprintf(buf, "ste %d, r_r %d, e_r %d, r_t %d, s_s %d, a_s %d, reg %d, r_e %d, s_i %d, m_a %d, aus %d", 24032689Sbostic stealthy, r_rings, e_rings, r_teleport, sustain_strength, 24132689Sbostic add_strength, regeneration, ring_exp, r_see_invisible, 24232689Sbostic maintain_armor, auto_search); 24332689Sbostic message(buf, 0); 24432689Sbostic } 24532689Sbostic } 24632689Sbostic 24732689Sbostic ring_stats(pr) 24832689Sbostic boolean pr; 24932689Sbostic { 25032689Sbostic short i; 25132689Sbostic object *ring; 25232689Sbostic 25332689Sbostic stealthy = 0; 25432689Sbostic r_rings = 0; 25532689Sbostic e_rings = 0; 25632689Sbostic r_teleport = 0; 25732689Sbostic sustain_strength = 0; 25832689Sbostic add_strength = 0; 25932689Sbostic regeneration = 0; 26032689Sbostic ring_exp = 0; 26132689Sbostic r_see_invisible = 0; 26232689Sbostic maintain_armor = 0; 26332689Sbostic auto_search = 0; 26432689Sbostic 26532689Sbostic for (i = 0; i < 2; i++) { 26632689Sbostic if (!(ring = ((i == 0) ? rogue.left_ring : rogue.right_ring))) { 26732689Sbostic continue; 26832689Sbostic } 26932689Sbostic r_rings++; 27032689Sbostic e_rings++; 27132689Sbostic switch(ring->which_kind) { 27232689Sbostic case STEALTH: 27332689Sbostic stealthy++; 27432689Sbostic break; 27532689Sbostic case R_TELEPORT: 27632689Sbostic r_teleport = 1; 27732689Sbostic break; 27832689Sbostic case REGENERATION: 27932689Sbostic regeneration++; 28032689Sbostic break; 28132689Sbostic case SLOW_DIGEST: 28232689Sbostic e_rings -= 2; 28332689Sbostic break; 28432689Sbostic case ADD_STRENGTH: 28532689Sbostic add_strength += ring->class; 28632689Sbostic break; 28732689Sbostic case SUSTAIN_STRENGTH: 28832689Sbostic sustain_strength = 1; 28932689Sbostic break; 29032689Sbostic case DEXTERITY: 29132689Sbostic ring_exp += ring->class; 29232689Sbostic break; 29332689Sbostic case ADORNMENT: 29432689Sbostic break; 29532689Sbostic case R_SEE_INVISIBLE: 29632689Sbostic r_see_invisible = 1; 29732689Sbostic break; 29832689Sbostic case MAINTAIN_ARMOR: 29932689Sbostic maintain_armor = 1; 30032689Sbostic break; 30132689Sbostic case SEARCHING: 30232689Sbostic auto_search += 2; 30332689Sbostic break; 30432689Sbostic } 30532689Sbostic } 30632689Sbostic if (pr) { 30732689Sbostic print_stats(STAT_STRENGTH); 30832689Sbostic relight(); 30932689Sbostic } 31032689Sbostic } 311