xref: /dragonfly/games/hack/hack.do_wear.c (revision 0de61e28)
1 /*	$NetBSD: hack.do_wear.c,v 1.7 2009/08/12 07:28:40 dholland Exp $	*/
2 
3 /*
4  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5  * Amsterdam
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are
10  * met:
11  *
12  * - Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * - Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in the
17  * documentation and/or other materials provided with the distribution.
18  *
19  * - Neither the name of the Stichting Centrum voor Wiskunde en
20  * Informatica, nor the names of its contributors may be used to endorse or
21  * promote products derived from this software without specific prior
22  * written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  */
36 
37 /*
38  * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39  * All rights reserved.
40  *
41  * Redistribution and use in source and binary forms, with or without
42  * modification, are permitted provided that the following conditions
43  * are met:
44  * 1. Redistributions of source code must retain the above copyright
45  *    notice, this list of conditions and the following disclaimer.
46  * 2. Redistributions in binary form must reproduce the above copyright
47  *    notice, this list of conditions and the following disclaimer in the
48  *    documentation and/or other materials provided with the distribution.
49  * 3. The name of the author may not be used to endorse or promote products
50  *    derived from this software without specific prior written permission.
51  *
52  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
55  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62  */
63 
64 #include "hack.h"
65 #include "extern.h"
66 
67 static int dorr(struct obj *);
68 static int cursed(struct obj *);
69 
70 static void
71 off_msg(struct obj *otmp)
72 {
73 	pline("You were wearing %s.", doname(otmp));
74 }
75 
76 int
77 doremarm(void)
78 {
79 	struct obj     *otmp;
80 	if (!uarm && !uarmh && !uarms && !uarmg) {
81 		pline("Not wearing any armor.");
82 		return (0);
83 	}
84 	otmp = (!uarmh && !uarms && !uarmg) ? uarm :
85 		(!uarms && !uarm && !uarmg) ? uarmh :
86 		(!uarmh && !uarm && !uarmg) ? uarms :
87 		(!uarmh && !uarm && !uarms) ? uarmg :
88 		getobj("[", "take off");
89 	if (!otmp)
90 		return (0);
91 	if (!(otmp->owornmask & (W_ARMOR - W_ARM2))) {
92 		pline("You can't take that off.");
93 		return (0);
94 	}
95 	if (otmp == uarmg && uwep && uwep->cursed) {	/* myers@uwmacc */
96 		pline("You seem not able to take off the gloves while holding your weapon.");
97 		return (0);
98 	}
99 	(void) armoroff(otmp);
100 	return (1);
101 }
102 
103 int
104 doremring(void)
105 {
106 	if (!uleft && !uright) {
107 		pline("Not wearing any ring.");
108 		return (0);
109 	}
110 	if (!uleft)
111 		return (dorr(uright));
112 	if (!uright)
113 		return (dorr(uleft));
114 	if (uleft && uright)
115 		while (1) {
116 			char            answer;
117 
118 			pline("What ring, Right or Left? [ rl?]");
119 			if (strchr(quitchars, (answer = readchar())))
120 				return (0);
121 			switch (answer) {
122 			case 'l':
123 			case 'L':
124 				return (dorr(uleft));
125 			case 'r':
126 			case 'R':
127 				return (dorr(uright));
128 			case '?':
129 				(void) doprring();
130 				/* might look at morc here %% */
131 			}
132 		}
133 	/* NOTREACHED */
134 	return (0);
135 }
136 
137 static int
138 dorr(struct obj *otmp)
139 {
140 	if (cursed(otmp))
141 		return (0);
142 	ringoff(otmp);
143 	off_msg(otmp);
144 	return (1);
145 }
146 
147 static int
148 cursed(struct obj *otmp)
149 {
150 	if (otmp->cursed) {
151 		pline("You can't. It appears to be cursed.");
152 		return (1);
153 	}
154 	return (0);
155 }
156 
157 int
158 armoroff(struct obj *otmp)
159 {
160 	int             delay = -objects[otmp->otyp].oc_delay;
161 	if (cursed(otmp))
162 		return (0);
163 	setworn((struct obj *) 0, otmp->owornmask & W_ARMOR);
164 	if (delay) {
165 		nomul(delay);
166 		switch (otmp->otyp) {
167 		case HELMET:
168 			nomovemsg = "You finished taking off your helmet.";
169 			break;
170 		case PAIR_OF_GLOVES:
171 			nomovemsg = "You finished taking off your gloves";
172 			break;
173 		default:
174 			nomovemsg = "You finished taking off your suit.";
175 		}
176 	} else {
177 		off_msg(otmp);
178 	}
179 	return (1);
180 }
181 
182 int
183 doweararm(void)
184 {
185 	struct obj     *otmp;
186 	int             delay;
187 	int             err = 0;
188 	long            mask = 0;
189 
190 	otmp = getobj("[", "wear");
191 	if (!otmp)
192 		return (0);
193 	if (otmp->owornmask & W_ARMOR) {
194 		pline("You are already wearing that!");
195 		return (0);
196 	}
197 	if (otmp->otyp == HELMET) {
198 		if (uarmh) {
199 			pline("You are already wearing a helmet.");
200 			err++;
201 		} else
202 			mask = W_ARMH;
203 	} else if (otmp->otyp == SHIELD) {
204 		if (uarms)
205 			pline("You are already wearing a shield."), err++;
206 		if (uwep && uwep->otyp == TWO_HANDED_SWORD)
207 			pline("You cannot wear a shield and wield a two-handed sword."), err++;
208 		if (!err)
209 			mask = W_ARMS;
210 	} else if (otmp->otyp == PAIR_OF_GLOVES) {
211 		if (uarmg) {
212 			pline("You are already wearing gloves.");
213 			err++;
214 		} else if (uwep && uwep->cursed) {
215 			pline("You cannot wear gloves over your weapon.");
216 			err++;
217 		} else
218 			mask = W_ARMG;
219 	} else {
220 		if (uarm) {
221 			if (otmp->otyp != ELVEN_CLOAK || uarm2) {
222 				pline("You are already wearing some armor.");
223 				err++;
224 			}
225 		}
226 		if (!err)
227 			mask = W_ARM;
228 	}
229 	if (otmp == uwep && uwep->cursed) {
230 		if (!err++)
231 			pline("%s is welded to your hand.", Doname(uwep));
232 	}
233 	if (err)
234 		return (0);
235 	setworn(otmp, mask);
236 	if (otmp == uwep)
237 		setuwep((struct obj *) 0);
238 	delay = -objects[otmp->otyp].oc_delay;
239 	if (delay) {
240 		nomul(delay);
241 		nomovemsg = "You finished your dressing manoeuvre.";
242 	}
243 	otmp->known = 1;
244 	return (1);
245 }
246 
247 int
248 dowearring(void)
249 {
250 	struct obj     *otmp;
251 	long            mask = 0;
252 	long            oldprop;
253 
254 	if (uleft && uright) {
255 		pline("There are no more ring-fingers to fill.");
256 		return (0);
257 	}
258 	otmp = getobj("=", "wear");
259 	if (!otmp)
260 		return (0);
261 	if (otmp->owornmask & W_RING) {
262 		pline("You are already wearing that!");
263 		return (0);
264 	}
265 	if (otmp == uleft || otmp == uright) {
266 		pline("You are already wearing that.");
267 		return (0);
268 	}
269 	if (otmp == uwep && uwep->cursed) {
270 		pline("%s is welded to your hand.", Doname(uwep));
271 		return (0);
272 	}
273 	if (uleft)
274 		mask = RIGHT_RING;
275 	else if (uright)
276 		mask = LEFT_RING;
277 	else
278 		do {
279 			char            answer;
280 
281 			pline("What ring-finger, Right or Left? ");
282 			if (strchr(quitchars, (answer = readchar())))
283 				return (0);
284 			switch (answer) {
285 			case 'l':
286 			case 'L':
287 				mask = LEFT_RING;
288 				break;
289 			case 'r':
290 			case 'R':
291 				mask = RIGHT_RING;
292 				break;
293 			}
294 		} while (!mask);
295 	setworn(otmp, mask);
296 	if (otmp == uwep)
297 		setuwep((struct obj *) 0);
298 	oldprop = u.uprops[PROP(otmp->otyp)].p_flgs;
299 	u.uprops[PROP(otmp->otyp)].p_flgs |= mask;
300 	switch (otmp->otyp) {
301 	case RIN_LEVITATION:
302 		if (!oldprop)
303 			float_up();
304 		break;
305 	case RIN_PROTECTION_FROM_SHAPE_CHANGERS:
306 		rescham();
307 		break;
308 	case RIN_GAIN_STRENGTH:
309 		u.ustr += otmp->spe;
310 		u.ustrmax += otmp->spe;
311 		if (u.ustr > 118)
312 			u.ustr = 118;
313 		if (u.ustrmax > 118)
314 			u.ustrmax = 118;
315 		flags.botl = 1;
316 		break;
317 	case RIN_INCREASE_DAMAGE:
318 		u.udaminc += otmp->spe;
319 		break;
320 	}
321 	prinv(otmp);
322 	return (1);
323 }
324 
325 void
326 ringoff(struct obj *obj)
327 {
328 	long            mask;
329 	mask = obj->owornmask & W_RING;
330 	setworn((struct obj *) 0, obj->owornmask);
331 	if (!(u.uprops[PROP(obj->otyp)].p_flgs & mask))
332 		impossible("Strange... I didnt know you had that ring.");
333 	u.uprops[PROP(obj->otyp)].p_flgs &= ~mask;
334 	switch (obj->otyp) {
335 	case RIN_FIRE_RESISTANCE:
336 		/* Bad luck if the player is in hell... --jgm */
337 		if (!Fire_resistance && dlevel >= 30) {
338 			pline("The flames of Hell burn you to a crisp.");
339 			killer = "stupidity in hell";
340 			done("burned");
341 		}
342 		break;
343 	case RIN_LEVITATION:
344 		if (!Levitation) {	/* no longer floating */
345 			float_down();
346 		}
347 		break;
348 	case RIN_GAIN_STRENGTH:
349 		u.ustr -= obj->spe;
350 		u.ustrmax -= obj->spe;
351 		if (u.ustr > 118)
352 			u.ustr = 118;
353 		if (u.ustrmax > 118)
354 			u.ustrmax = 118;
355 		flags.botl = 1;
356 		break;
357 	case RIN_INCREASE_DAMAGE:
358 		u.udaminc -= obj->spe;
359 		break;
360 	}
361 }
362 
363 void
364 find_ac(void)
365 {
366 	int             uac = 10;
367 	if (uarm)
368 		uac -= ARM_BONUS(uarm);
369 	if (uarm2)
370 		uac -= ARM_BONUS(uarm2);
371 	if (uarmh)
372 		uac -= ARM_BONUS(uarmh);
373 	if (uarms)
374 		uac -= ARM_BONUS(uarms);
375 	if (uarmg)
376 		uac -= ARM_BONUS(uarmg);
377 	if (uleft && uleft->otyp == RIN_PROTECTION)
378 		uac -= uleft->spe;
379 	if (uright && uright->otyp == RIN_PROTECTION)
380 		uac -= uright->spe;
381 	if (uac != u.uac) {
382 		u.uac = uac;
383 		flags.botl = 1;
384 	}
385 }
386 
387 void
388 glibr(void)
389 {
390 	struct obj     *otmp;
391 	int             xfl = 0;
392 	if (!uarmg)
393 		if (uleft || uright) {
394 			/* Note: at present also cursed rings fall off */
395 			pline("Your %s off your fingers.",
396 			   (uleft && uright) ? "rings slip" : "ring slips");
397 			xfl++;
398 			if ((otmp = uleft) != Null(obj)) {
399 				ringoff(uleft);
400 				dropx(otmp);
401 			}
402 			if ((otmp = uright) != Null(obj)) {
403 				ringoff(uright);
404 				dropx(otmp);
405 			}
406 		}
407 	if ((otmp = uwep) != Null(obj)) {
408 		/* Note: at present also cursed weapons fall */
409 		setuwep((struct obj *) 0);
410 		dropx(otmp);
411 		pline("Your weapon %sslips from your hands.",
412 		      xfl ? "also " : "");
413 	}
414 }
415 
416 struct obj     *
417 some_armor(void)
418 {
419 	struct obj     *otmph = uarm;
420 	if (uarmh && (!otmph || !rn2(4)))
421 		otmph = uarmh;
422 	if (uarmg && (!otmph || !rn2(4)))
423 		otmph = uarmg;
424 	if (uarms && (!otmph || !rn2(4)))
425 		otmph = uarms;
426 	return (otmph);
427 }
428 
429 void
430 corrode_armor(void)
431 {
432 	struct obj     *otmph = some_armor();
433 	if (otmph) {
434 		if (otmph->rustfree ||
435 		    otmph->otyp == ELVEN_CLOAK ||
436 		    otmph->otyp == LEATHER_ARMOR ||
437 		    otmph->otyp == STUDDED_LEATHER_ARMOR) {
438 			pline("Your %s not affected!",
439 			      aobjnam(otmph, "are"));
440 			return;
441 		}
442 		pline("Your %s!", aobjnam(otmph, "corrode"));
443 		otmph->spe--;
444 	}
445 }
446