Home | History | Annotate | Line # | Download | only in rogue
ring.c revision 1.6.22.1
      1  1.6.22.1     matt /*	$NetBSD: 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.1     matt __RCSID("$NetBSD: 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.5  hubertf const char *left_or_right = "left or right hand?";
     59       1.5  hubertf const char *no_ring = "there's no ring on that hand";
     60       1.1      cgd short stealthy;
     61       1.1      cgd short r_rings;
     62       1.1      cgd short add_strength;
     63       1.1      cgd short e_rings;
     64       1.1      cgd short regeneration;
     65       1.1      cgd short ring_exp;
     66       1.1      cgd short auto_search;
     67       1.1      cgd boolean r_teleport;
     68       1.1      cgd boolean r_see_invisible;
     69       1.1      cgd boolean sustain_strength;
     70       1.1      cgd boolean maintain_armor;
     71       1.1      cgd 
     72       1.4    lukem void
     73       1.1      cgd put_on_ring()
     74       1.1      cgd {
     75       1.1      cgd 	short ch;
     76       1.1      cgd 	char desc[DCOLS];
     77       1.1      cgd 	object *ring;
     78       1.1      cgd 
     79       1.1      cgd 	if (r_rings == 2) {
     80  1.6.22.1     matt 		messagef(0, "wearing two rings already");
     81       1.1      cgd 		return;
     82       1.1      cgd 	}
     83       1.1      cgd 	if ((ch = pack_letter("put on what?", RING)) == CANCEL) {
     84       1.1      cgd 		return;
     85       1.1      cgd 	}
     86       1.1      cgd 	if (!(ring = get_letter_object(ch))) {
     87  1.6.22.1     matt 		messagef(0, "no such item.");
     88       1.1      cgd 		return;
     89       1.1      cgd 	}
     90       1.1      cgd 	if (!(ring->what_is & RING)) {
     91  1.6.22.1     matt 		messagef(0, "that's not a ring");
     92       1.1      cgd 		return;
     93       1.1      cgd 	}
     94       1.1      cgd 	if (ring->in_use_flags & (ON_LEFT_HAND | ON_RIGHT_HAND)) {
     95  1.6.22.1     matt 		messagef(0, "that ring is already being worn");
     96       1.1      cgd 		return;
     97       1.1      cgd 	}
     98       1.1      cgd 	if (r_rings == 1) {
     99       1.1      cgd 		ch = (rogue.left_ring ? 'r' : 'l');
    100       1.1      cgd 	} else {
    101  1.6.22.1     matt 		messagef(0, "%s", left_or_right);
    102       1.1      cgd 		do {
    103       1.1      cgd 			ch = rgetchar();
    104       1.1      cgd 		} while ((ch != CANCEL) && (ch != 'l') && (ch != 'r') && (ch != '\n') &&
    105       1.1      cgd 			 	(ch != '\r'));
    106       1.1      cgd 	}
    107       1.1      cgd 	if ((ch != 'l') && (ch != 'r')) {
    108       1.1      cgd 		check_message();
    109       1.1      cgd 		return;
    110       1.1      cgd 	}
    111       1.1      cgd 	if (((ch == 'l') && rogue.left_ring)||((ch == 'r') && rogue.right_ring)) {
    112       1.1      cgd 		check_message();
    113  1.6.22.1     matt 		messagef(0, "there's already a ring on that hand");
    114       1.1      cgd 		return;
    115       1.1      cgd 	}
    116       1.1      cgd 	if (ch == 'l') {
    117       1.1      cgd 		do_put_on(ring, 1);
    118       1.1      cgd 	} else {
    119       1.1      cgd 		do_put_on(ring, 0);
    120       1.1      cgd 	}
    121       1.1      cgd 	ring_stats(1);
    122       1.1      cgd 	check_message();
    123  1.6.22.1     matt 	get_desc(ring, desc, sizeof(desc));
    124  1.6.22.1     matt 	messagef(0, "%s", desc);
    125       1.1      cgd 	(void) reg_move();
    126       1.1      cgd }
    127       1.1      cgd 
    128       1.1      cgd /*
    129       1.1      cgd  * Do not call ring_stats() from within do_put_on().  It will cause
    130       1.1      cgd  * serious problems when do_put_on() is called from read_pack() in restore().
    131       1.1      cgd  */
    132       1.1      cgd 
    133       1.4    lukem void
    134       1.1      cgd do_put_on(ring, on_left)
    135       1.4    lukem 	object *ring;
    136       1.4    lukem 	boolean on_left;
    137       1.1      cgd {
    138       1.1      cgd 	if (on_left) {
    139       1.1      cgd 		ring->in_use_flags |= ON_LEFT_HAND;
    140       1.1      cgd 		rogue.left_ring = ring;
    141       1.1      cgd 	} else {
    142       1.1      cgd 		ring->in_use_flags |= ON_RIGHT_HAND;
    143       1.1      cgd 		rogue.right_ring = ring;
    144       1.1      cgd 	}
    145       1.1      cgd }
    146       1.1      cgd 
    147       1.4    lukem void
    148       1.1      cgd remove_ring()
    149       1.1      cgd {
    150       1.1      cgd 	boolean left = 0, right = 0;
    151       1.1      cgd 	short ch;
    152       1.1      cgd 	char buf[DCOLS];
    153       1.1      cgd 	object *ring;
    154       1.1      cgd 
    155       1.4    lukem 	ring = NULL;
    156       1.1      cgd 	if (r_rings == 0) {
    157       1.1      cgd 		inv_rings();
    158       1.1      cgd 	} else if (rogue.left_ring && !rogue.right_ring) {
    159       1.1      cgd 		left = 1;
    160       1.1      cgd 	} else if (!rogue.left_ring && rogue.right_ring) {
    161       1.1      cgd 		right = 1;
    162       1.1      cgd 	} else {
    163  1.6.22.1     matt 		messagef(0, "%s", left_or_right);
    164       1.1      cgd 		do {
    165       1.1      cgd 			ch = rgetchar();
    166       1.1      cgd 		} while ((ch != CANCEL) && (ch != 'l') && (ch != 'r') &&
    167       1.1      cgd 			(ch != '\n') && (ch != '\r'));
    168       1.1      cgd 		left = (ch == 'l');
    169       1.1      cgd 		right = (ch == 'r');
    170       1.1      cgd 		check_message();
    171       1.1      cgd 	}
    172       1.1      cgd 	if (left || right) {
    173       1.1      cgd 		if (left) {
    174       1.1      cgd 			if (rogue.left_ring) {
    175       1.1      cgd 				ring = rogue.left_ring;
    176       1.1      cgd 			} else {
    177  1.6.22.1     matt 				messagef(0, "%s", no_ring);
    178       1.1      cgd 			}
    179       1.1      cgd 		} else {
    180       1.1      cgd 			if (rogue.right_ring) {
    181       1.1      cgd 				ring = rogue.right_ring;
    182       1.1      cgd 			} else {
    183  1.6.22.1     matt 				messagef(0, "%s", no_ring);
    184       1.1      cgd 			}
    185       1.1      cgd 		}
    186       1.1      cgd 		if (ring->is_cursed) {
    187  1.6.22.1     matt 			messagef(0, "%s", curse_message);
    188       1.1      cgd 		} else {
    189       1.1      cgd 			un_put_on(ring);
    190  1.6.22.1     matt 			get_desc(ring, buf, sizeof(buf));
    191  1.6.22.1     matt 			messagef(0, "removed %s", buf);
    192       1.1      cgd 			(void) reg_move();
    193       1.1      cgd 		}
    194       1.1      cgd 	}
    195       1.1      cgd }
    196       1.1      cgd 
    197       1.4    lukem void
    198       1.1      cgd un_put_on(ring)
    199       1.4    lukem 	object *ring;
    200       1.1      cgd {
    201       1.1      cgd 	if (ring && (ring->in_use_flags & ON_LEFT_HAND)) {
    202       1.1      cgd 		ring->in_use_flags &= (~ON_LEFT_HAND);
    203       1.1      cgd 		rogue.left_ring = 0;
    204       1.1      cgd 	} else if (ring && (ring->in_use_flags & ON_RIGHT_HAND)) {
    205       1.1      cgd 		ring->in_use_flags &= (~ON_RIGHT_HAND);
    206       1.1      cgd 		rogue.right_ring = 0;
    207       1.1      cgd 	}
    208       1.1      cgd 	ring_stats(1);
    209       1.1      cgd }
    210       1.1      cgd 
    211       1.4    lukem void
    212       1.1      cgd gr_ring(ring, assign_wk)
    213       1.4    lukem 	object *ring;
    214       1.4    lukem 	boolean assign_wk;
    215       1.1      cgd {
    216       1.1      cgd 	ring->what_is = RING;
    217       1.1      cgd 	if (assign_wk) {
    218       1.1      cgd 		ring->which_kind = get_rand(0, (RINGS - 1));
    219       1.1      cgd 	}
    220       1.1      cgd 	ring->class = 0;
    221       1.1      cgd 
    222       1.1      cgd 	switch(ring->which_kind) {
    223       1.1      cgd 	/*
    224       1.1      cgd 	case STEALTH:
    225       1.1      cgd 		break;
    226       1.1      cgd 	case SLOW_DIGEST:
    227       1.1      cgd 		break;
    228       1.1      cgd 	case REGENERATION:
    229       1.1      cgd 		break;
    230       1.1      cgd 	case R_SEE_INVISIBLE:
    231       1.1      cgd 		break;
    232       1.1      cgd 	case SUSTAIN_STRENGTH:
    233       1.1      cgd 		break;
    234       1.1      cgd 	case R_MAINTAIN_ARMOR:
    235       1.1      cgd 		break;
    236       1.1      cgd 	case SEARCHING:
    237       1.1      cgd 		break;
    238       1.1      cgd 	*/
    239       1.1      cgd 	case R_TELEPORT:
    240       1.1      cgd 		ring->is_cursed = 1;
    241       1.1      cgd 		break;
    242       1.1      cgd 	case ADD_STRENGTH:
    243       1.1      cgd 	case DEXTERITY:
    244       1.1      cgd 		while ((ring->class = (get_rand(0, 4) - 2)) == 0) ;
    245       1.1      cgd 		ring->is_cursed = (ring->class < 0);
    246       1.1      cgd 		break;
    247       1.1      cgd 	case ADORNMENT:
    248       1.1      cgd 		ring->is_cursed = coin_toss();
    249       1.1      cgd 		break;
    250       1.1      cgd 	}
    251       1.1      cgd }
    252       1.1      cgd 
    253       1.4    lukem void
    254       1.1      cgd inv_rings()
    255       1.1      cgd {
    256       1.1      cgd 	char buf[DCOLS];
    257       1.1      cgd 
    258       1.1      cgd 	if (r_rings == 0) {
    259  1.6.22.1     matt 		messagef(0, "not wearing any rings");
    260       1.1      cgd 	} else {
    261       1.1      cgd 		if (rogue.left_ring) {
    262  1.6.22.1     matt 			get_desc(rogue.left_ring, buf, sizeof(buf));
    263  1.6.22.1     matt 			messagef(0, "%s", buf);
    264       1.1      cgd 		}
    265       1.1      cgd 		if (rogue.right_ring) {
    266  1.6.22.1     matt 			get_desc(rogue.right_ring, buf, sizeof(buf));
    267  1.6.22.1     matt 			messagef(0, "%s", buf);
    268       1.1      cgd 		}
    269       1.1      cgd 	}
    270       1.1      cgd 	if (wizard) {
    271  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",
    272       1.1      cgd 			stealthy, r_rings, e_rings, r_teleport, sustain_strength,
    273       1.1      cgd 			add_strength, regeneration, ring_exp, r_see_invisible,
    274       1.1      cgd 			maintain_armor, auto_search);
    275       1.1      cgd 	}
    276       1.1      cgd }
    277       1.1      cgd 
    278       1.4    lukem void
    279       1.1      cgd ring_stats(pr)
    280       1.4    lukem 	boolean pr;
    281       1.1      cgd {
    282       1.1      cgd 	short i;
    283       1.1      cgd 	object *ring;
    284       1.1      cgd 
    285       1.1      cgd 	stealthy = 0;
    286       1.1      cgd 	r_rings = 0;
    287       1.1      cgd 	e_rings = 0;
    288       1.1      cgd 	r_teleport = 0;
    289       1.1      cgd 	sustain_strength = 0;
    290       1.1      cgd 	add_strength = 0;
    291       1.1      cgd 	regeneration = 0;
    292       1.1      cgd 	ring_exp = 0;
    293       1.1      cgd 	r_see_invisible = 0;
    294       1.1      cgd 	maintain_armor = 0;
    295       1.1      cgd 	auto_search = 0;
    296       1.1      cgd 
    297       1.1      cgd 	for (i = 0; i < 2; i++) {
    298       1.1      cgd 		if (!(ring = ((i == 0) ? rogue.left_ring : rogue.right_ring))) {
    299       1.1      cgd 			continue;
    300       1.1      cgd 		}
    301       1.1      cgd 		r_rings++;
    302       1.1      cgd 		e_rings++;
    303       1.1      cgd 		switch(ring->which_kind) {
    304       1.1      cgd 		case STEALTH:
    305       1.1      cgd 			stealthy++;
    306       1.1      cgd 			break;
    307       1.1      cgd 		case R_TELEPORT:
    308       1.1      cgd 			r_teleport = 1;
    309       1.1      cgd 			break;
    310       1.1      cgd 		case REGENERATION:
    311       1.1      cgd 			regeneration++;
    312       1.1      cgd 			break;
    313       1.1      cgd 		case SLOW_DIGEST:
    314       1.1      cgd 			e_rings -= 2;
    315       1.1      cgd 			break;
    316       1.1      cgd 		case ADD_STRENGTH:
    317       1.1      cgd 			add_strength += ring->class;
    318       1.1      cgd 			break;
    319       1.1      cgd 		case SUSTAIN_STRENGTH:
    320       1.1      cgd 			sustain_strength = 1;
    321       1.1      cgd 			break;
    322       1.1      cgd 		case DEXTERITY:
    323       1.1      cgd 			ring_exp += ring->class;
    324       1.1      cgd 			break;
    325       1.1      cgd 		case ADORNMENT:
    326       1.1      cgd 			break;
    327       1.1      cgd 		case R_SEE_INVISIBLE:
    328       1.1      cgd 			r_see_invisible = 1;
    329       1.1      cgd 			break;
    330       1.1      cgd 		case MAINTAIN_ARMOR:
    331       1.1      cgd 			maintain_armor = 1;
    332       1.1      cgd 			break;
    333       1.1      cgd 		case SEARCHING:
    334       1.1      cgd 			auto_search += 2;
    335       1.1      cgd 			break;
    336       1.1      cgd 		}
    337       1.1      cgd 	}
    338       1.1      cgd 	if (pr) {
    339       1.1      cgd 		print_stats(STAT_STRENGTH);
    340       1.1      cgd 		relight();
    341       1.1      cgd 	}
    342       1.1      cgd }
    343