ring.c revision 1.6.22.2       1  1.6.22.2   matt /*	ring.c,v 1.6.22.1 2008/01/09 01:30:58 matt Exp	*/
      2       1.3    cgd 
      3       1.1    cgd /*
      4       1.3    cgd  * Copyright (c) 1988, 1993
      5       1.3    cgd  *	The Regents of the University of California.  All rights reserved.
      6       1.1    cgd  *
      7       1.1    cgd  * This code is derived from software contributed to Berkeley by
      8       1.1    cgd  * Timothy C. Stoehr.
      9       1.1    cgd  *
     10       1.1    cgd  * Redistribution and use in source and binary forms, with or without
     11       1.1    cgd  * modification, are permitted provided that the following conditions
     12       1.1    cgd  * are met:
     13       1.1    cgd  * 1. Redistributions of source code must retain the above copyright
     14       1.1    cgd  *    notice, this list of conditions and the following disclaimer.
     15       1.1    cgd  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.1    cgd  *    notice, this list of conditions and the following disclaimer in the
     17       1.1    cgd  *    documentation and/or other materials provided with the distribution.
     18       1.6    agc  * 3. Neither the name of the University nor the names of its contributors
     19       1.1    cgd  *    may be used to endorse or promote products derived from this software
     20       1.1    cgd  *    without specific prior written permission.
     21       1.1    cgd  *
     22       1.1    cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23       1.1    cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24       1.1    cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25       1.1    cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26       1.1    cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27       1.1    cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28       1.1    cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29       1.1    cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30       1.1    cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31       1.1    cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32       1.1    cgd  * SUCH DAMAGE.
     33       1.1    cgd  */
     34       1.1    cgd 
     35       1.4  lukem #include <sys/cdefs.h>
     36       1.1    cgd #ifndef lint
     37       1.3    cgd #if 0
     38       1.3    cgd static char sccsid[] = "@(#)ring.c	8.1 (Berkeley) 5/31/93";
     39       1.3    cgd #else
     40  1.6.22.2   matt __RCSID("ring.c,v 1.6.22.1 2008/01/09 01:30:58 matt Exp");
     41       1.3    cgd #endif
     42       1.1    cgd #endif /* not lint */
     43       1.1    cgd 
     44       1.1    cgd /*
     45       1.1    cgd  * ring.c
     46       1.1    cgd  *
     47       1.1    cgd  * This source herein may be modified and/or distributed by anybody who
     48       1.1    cgd  * so desires, with the following restrictions:
     49       1.1    cgd  *    1.)  No portion of this notice shall be removed.
     50       1.1    cgd  *    2.)  Credit shall not be taken for the creation of this source.
     51       1.1    cgd  *    3.)  This code is not to be traded, sold, or used for personal
     52       1.1    cgd  *         gain or profit.
     53       1.1    cgd  *
     54       1.1    cgd  */
     55       1.1    cgd 
     56       1.1    cgd #include "rogue.h"
     57       1.1    cgd 
     58  1.6.22.2   matt static const char left_or_right[] = "left or right hand?";
     59  1.6.22.2   matt static const char no_ring[] = "there's no ring on that hand";
     60  1.6.22.2   matt 
     61       1.1    cgd short stealthy;
     62       1.1    cgd short r_rings;
     63       1.1    cgd short add_strength;
     64       1.1    cgd short e_rings;
     65       1.1    cgd short regeneration;
     66       1.1    cgd short ring_exp;
     67       1.1    cgd short auto_search;
     68       1.1    cgd boolean r_teleport;
     69       1.1    cgd boolean r_see_invisible;
     70       1.1    cgd boolean sustain_strength;
     71       1.1    cgd boolean maintain_armor;
     72       1.1    cgd 
     73       1.4  lukem void
     74  1.6.22.2   matt put_on_ring(void)
     75       1.1    cgd {
     76       1.1    cgd 	short ch;
     77       1.1    cgd 	char desc[DCOLS];
     78       1.1    cgd 	object *ring;
     79       1.1    cgd 
     80       1.1    cgd 	if (r_rings == 2) {
     81  1.6.22.1   matt 		messagef(0, "wearing two rings already");
     82       1.1    cgd 		return;
     83       1.1    cgd 	}
     84       1.1    cgd 	if ((ch = pack_letter("put on what?", RING)) == CANCEL) {
     85       1.1    cgd 		return;
     86       1.1    cgd 	}
     87       1.1    cgd 	if (!(ring = get_letter_object(ch))) {
     88  1.6.22.1   matt 		messagef(0, "no such item.");
     89       1.1    cgd 		return;
     90       1.1    cgd 	}
     91       1.1    cgd 	if (!(ring->what_is & RING)) {
     92  1.6.22.1   matt 		messagef(0, "that's not a ring");
     93       1.1    cgd 		return;
     94       1.1    cgd 	}
     95       1.1    cgd 	if (ring->in_use_flags & (ON_LEFT_HAND | ON_RIGHT_HAND)) {
     96  1.6.22.1   matt 		messagef(0, "that ring is already being worn");
     97       1.1    cgd 		return;
     98       1.1    cgd 	}
     99       1.1    cgd 	if (r_rings == 1) {
    100       1.1    cgd 		ch = (rogue.left_ring ? 'r' : 'l');
    101       1.1    cgd 	} else {
    102  1.6.22.1   matt 		messagef(0, "%s", left_or_right);
    103       1.1    cgd 		do {
    104       1.1    cgd 			ch = rgetchar();
    105       1.1    cgd 		} while ((ch != CANCEL) && (ch != 'l') && (ch != 'r') && (ch != '\n') &&
    106       1.1    cgd 			 	(ch != '\r'));
    107       1.1    cgd 	}
    108       1.1    cgd 	if ((ch != 'l') && (ch != 'r')) {
    109       1.1    cgd 		check_message();
    110       1.1    cgd 		return;
    111       1.1    cgd 	}
    112       1.1    cgd 	if (((ch == 'l') && rogue.left_ring)||((ch == 'r') && rogue.right_ring)) {
    113       1.1    cgd 		check_message();
    114  1.6.22.1   matt 		messagef(0, "there's already a ring on that hand");
    115       1.1    cgd 		return;
    116       1.1    cgd 	}
    117       1.1    cgd 	if (ch == 'l') {
    118       1.1    cgd 		do_put_on(ring, 1);
    119       1.1    cgd 	} else {
    120       1.1    cgd 		do_put_on(ring, 0);
    121       1.1    cgd 	}
    122       1.1    cgd 	ring_stats(1);
    123       1.1    cgd 	check_message();
    124  1.6.22.1   matt 	get_desc(ring, desc, sizeof(desc));
    125  1.6.22.1   matt 	messagef(0, "%s", desc);
    126  1.6.22.2   matt 	(void)reg_move();
    127       1.1    cgd }
    128       1.1    cgd 
    129       1.1    cgd /*
    130       1.1    cgd  * Do not call ring_stats() from within do_put_on().  It will cause
    131       1.1    cgd  * serious problems when do_put_on() is called from read_pack() in restore().
    132       1.1    cgd  */
    133       1.1    cgd 
    134       1.4  lukem void
    135  1.6.22.2   matt do_put_on(object *ring, boolean on_left)
    136       1.1    cgd {
    137       1.1    cgd 	if (on_left) {
    138       1.1    cgd 		ring->in_use_flags |= ON_LEFT_HAND;
    139       1.1    cgd 		rogue.left_ring = ring;
    140       1.1    cgd 	} else {
    141       1.1    cgd 		ring->in_use_flags |= ON_RIGHT_HAND;
    142       1.1    cgd 		rogue.right_ring = ring;
    143       1.1    cgd 	}
    144       1.1    cgd }
    145       1.1    cgd 
    146       1.4  lukem void
    147  1.6.22.2   matt remove_ring(void)
    148       1.1    cgd {
    149       1.1    cgd 	boolean left = 0, right = 0;
    150       1.1    cgd 	short ch;
    151       1.1    cgd 	char buf[DCOLS];
    152       1.1    cgd 	object *ring;
    153       1.1    cgd 
    154       1.4  lukem 	ring = NULL;
    155       1.1    cgd 	if (r_rings == 0) {
    156       1.1    cgd 		inv_rings();
    157       1.1    cgd 	} else if (rogue.left_ring && !rogue.right_ring) {
    158       1.1    cgd 		left = 1;
    159       1.1    cgd 	} else if (!rogue.left_ring && rogue.right_ring) {
    160       1.1    cgd 		right = 1;
    161       1.1    cgd 	} else {
    162  1.6.22.1   matt 		messagef(0, "%s", left_or_right);
    163       1.1    cgd 		do {
    164       1.1    cgd 			ch = rgetchar();
    165       1.1    cgd 		} while ((ch != CANCEL) && (ch != 'l') && (ch != 'r') &&
    166       1.1    cgd 			(ch != '\n') && (ch != '\r'));
    167       1.1    cgd 		left = (ch == 'l');
    168       1.1    cgd 		right = (ch == 'r');
    169       1.1    cgd 		check_message();
    170       1.1    cgd 	}
    171       1.1    cgd 	if (left || right) {
    172       1.1    cgd 		if (left) {
    173       1.1    cgd 			if (rogue.left_ring) {
    174       1.1    cgd 				ring = rogue.left_ring;
    175       1.1    cgd 			} else {
    176  1.6.22.1   matt 				messagef(0, "%s", no_ring);
    177       1.1    cgd 			}
    178       1.1    cgd 		} else {
    179       1.1    cgd 			if (rogue.right_ring) {
    180       1.1    cgd 				ring = rogue.right_ring;
    181       1.1    cgd 			} else {
    182  1.6.22.1   matt 				messagef(0, "%s", no_ring);
    183       1.1    cgd 			}
    184       1.1    cgd 		}
    185       1.1    cgd 		if (ring->is_cursed) {
    186  1.6.22.1   matt 			messagef(0, "%s", curse_message);
    187       1.1    cgd 		} else {
    188       1.1    cgd 			un_put_on(ring);
    189  1.6.22.1   matt 			get_desc(ring, buf, sizeof(buf));
    190  1.6.22.1   matt 			messagef(0, "removed %s", buf);
    191  1.6.22.2   matt 			(void)reg_move();
    192       1.1    cgd 		}
    193       1.1    cgd 	}
    194       1.1    cgd }
    195       1.1    cgd 
    196       1.4  lukem void
    197  1.6.22.2   matt un_put_on(object *ring)
    198       1.1    cgd {
    199       1.1    cgd 	if (ring && (ring->in_use_flags & ON_LEFT_HAND)) {
    200       1.1    cgd 		ring->in_use_flags &= (~ON_LEFT_HAND);
    201  1.6.22.2   matt 		rogue.left_ring = NULL;
    202       1.1    cgd 	} else if (ring && (ring->in_use_flags & ON_RIGHT_HAND)) {
    203       1.1    cgd 		ring->in_use_flags &= (~ON_RIGHT_HAND);
    204  1.6.22.2   matt 		rogue.right_ring = NULL;
    205       1.1    cgd 	}
    206       1.1    cgd 	ring_stats(1);
    207       1.1    cgd }
    208       1.1    cgd 
    209       1.4  lukem void
    210  1.6.22.2   matt gr_ring(object *ring, boolean assign_wk)
    211       1.1    cgd {
    212       1.1    cgd 	ring->what_is = RING;
    213       1.1    cgd 	if (assign_wk) {
    214       1.1    cgd 		ring->which_kind = get_rand(0, (RINGS - 1));
    215       1.1    cgd 	}
    216       1.1    cgd 	ring->class = 0;
    217       1.1    cgd 
    218       1.1    cgd 	switch(ring->which_kind) {
    219       1.1    cgd 	/*
    220       1.1    cgd 	case STEALTH:
    221       1.1    cgd 		break;
    222       1.1    cgd 	case SLOW_DIGEST:
    223       1.1    cgd 		break;
    224       1.1    cgd 	case REGENERATION:
    225       1.1    cgd 		break;
    226       1.1    cgd 	case R_SEE_INVISIBLE:
    227       1.1    cgd 		break;
    228       1.1    cgd 	case SUSTAIN_STRENGTH:
    229       1.1    cgd 		break;
    230       1.1    cgd 	case R_MAINTAIN_ARMOR:
    231       1.1    cgd 		break;
    232       1.1    cgd 	case SEARCHING:
    233       1.1    cgd 		break;
    234       1.1    cgd 	*/
    235       1.1    cgd 	case R_TELEPORT:
    236       1.1    cgd 		ring->is_cursed = 1;
    237       1.1    cgd 		break;
    238       1.1    cgd 	case ADD_STRENGTH:
    239       1.1    cgd 	case DEXTERITY:
    240  1.6.22.2   matt 		while ((ring->class = (get_rand(0, 4) - 2)) == 0)
    241  1.6.22.2   matt 			;
    242       1.1    cgd 		ring->is_cursed = (ring->class < 0);
    243       1.1    cgd 		break;
    244       1.1    cgd 	case ADORNMENT:
    245       1.1    cgd 		ring->is_cursed = coin_toss();
    246       1.1    cgd 		break;
    247       1.1    cgd 	}
    248       1.1    cgd }
    249       1.1    cgd 
    250       1.4  lukem void
    251  1.6.22.2   matt inv_rings(void)
    252       1.1    cgd {
    253       1.1    cgd 	char buf[DCOLS];
    254       1.1    cgd 
    255       1.1    cgd 	if (r_rings == 0) {
    256  1.6.22.1   matt 		messagef(0, "not wearing any rings");
    257       1.1    cgd 	} else {
    258       1.1    cgd 		if (rogue.left_ring) {
    259  1.6.22.1   matt 			get_desc(rogue.left_ring, buf, sizeof(buf));
    260  1.6.22.1   matt 			messagef(0, "%s", buf);
    261       1.1    cgd 		}
    262       1.1    cgd 		if (rogue.right_ring) {
    263  1.6.22.1   matt 			get_desc(rogue.right_ring, buf, sizeof(buf));
    264  1.6.22.1   matt 			messagef(0, "%s", buf);
    265       1.1    cgd 		}
    266       1.1    cgd 	}
    267       1.1    cgd 	if (wizard) {
    268  1.6.22.1   matt 		messagef(0, "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",
    269       1.1    cgd 			stealthy, r_rings, e_rings, r_teleport, sustain_strength,
    270       1.1    cgd 			add_strength, regeneration, ring_exp, r_see_invisible,
    271       1.1    cgd 			maintain_armor, auto_search);
    272       1.1    cgd 	}
    273       1.1    cgd }
    274       1.1    cgd 
    275       1.4  lukem void
    276  1.6.22.2   matt ring_stats(boolean pr)
    277       1.1    cgd {
    278       1.1    cgd 	short i;
    279       1.1    cgd 	object *ring;
    280       1.1    cgd 
    281       1.1    cgd 	stealthy = 0;
    282       1.1    cgd 	r_rings = 0;
    283       1.1    cgd 	e_rings = 0;
    284       1.1    cgd 	r_teleport = 0;
    285       1.1    cgd 	sustain_strength = 0;
    286       1.1    cgd 	add_strength = 0;
    287       1.1    cgd 	regeneration = 0;
    288       1.1    cgd 	ring_exp = 0;
    289       1.1    cgd 	r_see_invisible = 0;
    290       1.1    cgd 	maintain_armor = 0;
    291       1.1    cgd 	auto_search = 0;
    292       1.1    cgd 
    293       1.1    cgd 	for (i = 0; i < 2; i++) {
    294       1.1    cgd 		if (!(ring = ((i == 0) ? rogue.left_ring : rogue.right_ring))) {
    295       1.1    cgd 			continue;
    296       1.1    cgd 		}
    297       1.1    cgd 		r_rings++;
    298       1.1    cgd 		e_rings++;
    299       1.1    cgd 		switch(ring->which_kind) {
    300       1.1    cgd 		case STEALTH:
    301       1.1    cgd 			stealthy++;
    302       1.1    cgd 			break;
    303       1.1    cgd 		case R_TELEPORT:
    304       1.1    cgd 			r_teleport = 1;
    305       1.1    cgd 			break;
    306       1.1    cgd 		case REGENERATION:
    307       1.1    cgd 			regeneration++;
    308       1.1    cgd 			break;
    309       1.1    cgd 		case SLOW_DIGEST:
    310       1.1    cgd 			e_rings -= 2;
    311       1.1    cgd 			break;
    312       1.1    cgd 		case ADD_STRENGTH:
    313       1.1    cgd 			add_strength += ring->class;
    314       1.1    cgd 			break;
    315       1.1    cgd 		case SUSTAIN_STRENGTH:
    316       1.1    cgd 			sustain_strength = 1;
    317       1.1    cgd 			break;
    318       1.1    cgd 		case DEXTERITY:
    319       1.1    cgd 			ring_exp += ring->class;
    320       1.1    cgd 			break;
    321       1.1    cgd 		case ADORNMENT:
    322       1.1    cgd 			break;
    323       1.1    cgd 		case R_SEE_INVISIBLE:
    324       1.1    cgd 			r_see_invisible = 1;
    325       1.1    cgd 			break;
    326       1.1    cgd 		case MAINTAIN_ARMOR:
    327       1.1    cgd 			maintain_armor = 1;
    328       1.1    cgd 			break;
    329       1.1    cgd 		case SEARCHING:
    330       1.1    cgd 			auto_search += 2;
    331       1.1    cgd 			break;
    332       1.1    cgd 		}
    333       1.1    cgd 	}
    334       1.1    cgd 	if (pr) {
    335       1.1    cgd 		print_stats(STAT_STRENGTH);
    336       1.1    cgd 		relight();
    337       1.1    cgd 	}
    338       1.1    cgd }
    339