xref: /original-bsd/games/rogue/ring.c (revision 0a83ae40)
1 /*
2  * ring.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[] = "@(#)ring.c	5.1 (Berkeley) 11/25/87";
15 #endif /* not lint */
16 
17 #include "rogue.h"
18 
19 char *left_or_right = "left or right hand?";
20 char *no_ring = "there's no ring on that hand";
21 short stealthy;
22 short r_rings;
23 short add_strength;
24 short e_rings;
25 short regeneration;
26 short ring_exp;
27 short auto_search;
28 boolean r_teleport;
29 boolean r_see_invisible;
30 boolean sustain_strength;
31 boolean maintain_armor;
32 
33 extern char *curse_message;
34 extern boolean wizard;
35 
36 put_on_ring()
37 {
38 	short ch;
39 	char desc[DCOLS];
40 	object *ring;
41 
42 	if (r_rings == 2) {
43 		message("wearing two rings already", 0);
44 		return;
45 	}
46 	if ((ch = pack_letter("put on what?", RING)) == CANCEL) {
47 		return;
48 	}
49 	if (!(ring = get_letter_object(ch))) {
50 		message("no such item.", 0);
51 		return;
52 	}
53 	if (!(ring->what_is & RING)) {
54 		message("that's not a ring", 0);
55 		return;
56 	}
57 	if (ring->in_use_flags & (ON_LEFT_HAND | ON_RIGHT_HAND)) {
58 		message("that ring is already being worn", 0);
59 		return;
60 	}
61 	if (r_rings == 1) {
62 		ch = (rogue.left_ring ? 'r' : 'l');
63 	} else {
64 		message(left_or_right, 0);
65 		do {
66 			ch = rgetchar();
67 		} while ((ch != CANCEL) && (ch != 'l') && (ch != 'r') && (ch != '\n') &&
68 			 	(ch != '\r'));
69 	}
70 	if ((ch != 'l') && (ch != 'r')) {
71 		check_message();
72 		return;
73 	}
74 	if (((ch == 'l') && rogue.left_ring)||((ch == 'r') && rogue.right_ring)) {
75 		check_message();
76 		message("there's already a ring on that hand", 0);
77 		return;
78 	}
79 	if (ch == 'l') {
80 		do_put_on(ring, 1);
81 	} else {
82 		do_put_on(ring, 0);
83 	}
84 	ring_stats(1);
85 	check_message();
86 	get_desc(ring, desc);
87 	message(desc, 0);
88 	(void) reg_move();
89 }
90 
91 /*
92  * Do not call ring_stats() from within do_put_on().  It will cause
93  * serious problems when do_put_on() is called from read_pack() in restore().
94  */
95 
96 do_put_on(ring, on_left)
97 object *ring;
98 boolean on_left;
99 {
100 	if (on_left) {
101 		ring->in_use_flags |= ON_LEFT_HAND;
102 		rogue.left_ring = ring;
103 	} else {
104 		ring->in_use_flags |= ON_RIGHT_HAND;
105 		rogue.right_ring = ring;
106 	}
107 }
108 
109 remove_ring()
110 {
111 	boolean left = 0, right = 0;
112 	short ch;
113 	char buf[DCOLS];
114 	object *ring;
115 
116 	if (r_rings == 0) {
117 		inv_rings();
118 	} else if (rogue.left_ring && !rogue.right_ring) {
119 		left = 1;
120 	} else if (!rogue.left_ring && rogue.right_ring) {
121 		right = 1;
122 	} else {
123 		message(left_or_right, 0);
124 		do {
125 			ch = rgetchar();
126 		} while ((ch != CANCEL) && (ch != 'l') && (ch != 'r') &&
127 			(ch != '\n') && (ch != '\r'));
128 		left = (ch == 'l');
129 		right = (ch == 'r');
130 		check_message();
131 	}
132 	if (left || right) {
133 		if (left) {
134 			if (rogue.left_ring) {
135 				ring = rogue.left_ring;
136 			} else {
137 				message(no_ring, 0);
138 			}
139 		} else {
140 			if (rogue.right_ring) {
141 				ring = rogue.right_ring;
142 			} else {
143 				message(no_ring, 0);
144 			}
145 		}
146 		if (ring->is_cursed) {
147 			message(curse_message, 0);
148 		} else {
149 			un_put_on(ring);
150 			(void) strcpy(buf, "removed ");
151 			get_desc(ring, buf + 8);
152 			message(buf, 0);
153 			(void) reg_move();
154 		}
155 	}
156 }
157 
158 un_put_on(ring)
159 object *ring;
160 {
161 	if (ring && (ring->in_use_flags & ON_LEFT_HAND)) {
162 		ring->in_use_flags &= (~ON_LEFT_HAND);
163 		rogue.left_ring = 0;
164 	} else if (ring && (ring->in_use_flags & ON_RIGHT_HAND)) {
165 		ring->in_use_flags &= (~ON_RIGHT_HAND);
166 		rogue.right_ring = 0;
167 	}
168 	ring_stats(1);
169 }
170 
171 gr_ring(ring, assign_wk)
172 object *ring;
173 boolean assign_wk;
174 {
175 	ring->what_is = RING;
176 	if (assign_wk) {
177 		ring->which_kind = get_rand(0, (RINGS - 1));
178 	}
179 	ring->class = 0;
180 
181 	switch(ring->which_kind) {
182 	/*
183 	case STEALTH:
184 		break;
185 	case SLOW_DIGEST:
186 		break;
187 	case REGENERATION:
188 		break;
189 	case R_SEE_INVISIBLE:
190 		break;
191 	case SUSTAIN_STRENGTH:
192 		break;
193 	case R_MAINTAIN_ARMOR:
194 		break;
195 	case SEARCHING:
196 		break;
197 	*/
198 	case R_TELEPORT:
199 		ring->is_cursed = 1;
200 		break;
201 	case ADD_STRENGTH:
202 	case DEXTERITY:
203 		while ((ring->class = (get_rand(0, 4) - 2)) == 0) ;
204 		ring->is_cursed = (ring->class < 0);
205 		break;
206 	case ADORNMENT:
207 		ring->is_cursed = coin_toss();
208 		break;
209 	}
210 }
211 
212 inv_rings()
213 {
214 	char buf[DCOLS];
215 
216 	if (r_rings == 0) {
217 		message("not wearing any rings", 0);
218 	} else {
219 		if (rogue.left_ring) {
220 			get_desc(rogue.left_ring, buf);
221 			message(buf, 0);
222 		}
223 		if (rogue.right_ring) {
224 			get_desc(rogue.right_ring, buf);
225 			message(buf, 0);
226 		}
227 	}
228 	if (wizard) {
229 		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",
230 			stealthy, r_rings, e_rings, r_teleport, sustain_strength,
231 			add_strength, regeneration, ring_exp, r_see_invisible,
232 			maintain_armor, auto_search);
233 		message(buf, 0);
234 	}
235 }
236 
237 ring_stats(pr)
238 boolean pr;
239 {
240 	short i;
241 	object *ring;
242 
243 	stealthy = 0;
244 	r_rings = 0;
245 	e_rings = 0;
246 	r_teleport = 0;
247 	sustain_strength = 0;
248 	add_strength = 0;
249 	regeneration = 0;
250 	ring_exp = 0;
251 	r_see_invisible = 0;
252 	maintain_armor = 0;
253 	auto_search = 0;
254 
255 	for (i = 0; i < 2; i++) {
256 		if (!(ring = ((i == 0) ? rogue.left_ring : rogue.right_ring))) {
257 			continue;
258 		}
259 		r_rings++;
260 		e_rings++;
261 		switch(ring->which_kind) {
262 		case STEALTH:
263 			stealthy++;
264 			break;
265 		case R_TELEPORT:
266 			r_teleport = 1;
267 			break;
268 		case REGENERATION:
269 			regeneration++;
270 			break;
271 		case SLOW_DIGEST:
272 			e_rings -= 2;
273 			break;
274 		case ADD_STRENGTH:
275 			add_strength += ring->class;
276 			break;
277 		case SUSTAIN_STRENGTH:
278 			sustain_strength = 1;
279 			break;
280 		case DEXTERITY:
281 			ring_exp += ring->class;
282 			break;
283 		case ADORNMENT:
284 			break;
285 		case R_SEE_INVISIBLE:
286 			r_see_invisible = 1;
287 			break;
288 		case MAINTAIN_ARMOR:
289 			maintain_armor = 1;
290 			break;
291 		case SEARCHING:
292 			auto_search += 2;
293 			break;
294 		}
295 	}
296 	if (pr) {
297 		print_stats(STAT_STRENGTH);
298 		relight();
299 	}
300 }
301