hack.do_wear.c revision 1.6
1/*	$OpenBSD: hack.do_wear.c,v 1.6 2003/05/19 06:30:56 pjanzen 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#ifndef lint
65static const char rcsid[] = "$OpenBSD: hack.do_wear.c,v 1.6 2003/05/19 06:30:56 pjanzen Exp $";
66#endif /* not lint */
67
68#include <stdio.h>
69#include <stdlib.h>
70#include "hack.h"
71extern char *nomovemsg;
72extern char quitchars[];
73
74static void off_msg(struct obj *);
75static int  dorr(struct obj *);
76static int  cursed(struct obj *);
77
78static void
79off_msg(struct obj *otmp)
80{
81	pline("You were wearing %s.", doname(otmp));
82}
83
84int
85doremarm()
86{
87	struct obj *otmp;
88	if(!uarm && !uarmh && !uarms && !uarmg) {
89		pline("Not wearing any armor.");
90		return(0);
91	}
92	otmp = (!uarmh && !uarms && !uarmg) ? uarm :
93		(!uarms && !uarm && !uarmg) ? uarmh :
94		(!uarmh && !uarm && !uarmg) ? uarms :
95		(!uarmh && !uarm && !uarms) ? uarmg :
96		getobj("[", "take off");
97	if(!otmp) return(0);
98	if(!(otmp->owornmask & (W_ARMOR - W_ARM2))) {
99		pline("You can't take that off.");
100		return(0);
101	}
102	if( otmp == uarmg && uwep && uwep->cursed ) {	/* myers@uwmacc */
103 pline("You seem not able to take off the gloves while holding your weapon.");
104		return(0);
105	}
106	(void) armoroff(otmp);
107	return(1);
108}
109
110int
111doremring()
112{
113	if(!uleft && !uright){
114		pline("Not wearing any ring.");
115		return(0);
116	}
117	if(!uleft)
118		return(dorr(uright));
119	if(!uright)
120		return(dorr(uleft));
121	if(uleft && uright) while(1) {
122		char answer;
123
124		pline("What ring, Right or Left? [ rl?]");
125		if(strchr(quitchars, (answer = readchar())))
126			return(0);
127		switch(answer) {
128		case 'l':
129		case 'L':
130			return(dorr(uleft));
131		case 'r':
132		case 'R':
133			return(dorr(uright));
134		case '?':
135			(void) doprring();
136			/* might look at morc here %% */
137		}
138	}
139	/* NOTREACHED */
140	return(0);
141}
142
143static int
144dorr(struct obj *otmp)
145{
146	if(cursed(otmp)) return(0);
147	ringoff(otmp);
148	off_msg(otmp);
149	return(1);
150}
151
152static int
153cursed(struct obj *otmp)
154{
155	if(otmp->cursed){
156		pline("You can't. It appears to be cursed.");
157		return(1);
158	}
159	return(0);
160}
161
162int
163armoroff(struct obj *otmp)
164{
165	int delay = -objects[otmp->otyp].oc_delay;
166
167	if(cursed(otmp)) return(0);
168	setworn((struct obj *) 0, otmp->owornmask & W_ARMOR);
169	if(delay) {
170		nomul(delay);
171		switch(otmp->otyp) {
172		case HELMET:
173			nomovemsg = "You finished taking off your helmet.";
174			break;
175		case PAIR_OF_GLOVES:
176			nomovemsg = "You finished taking off your gloves";
177			break;
178		default:
179			nomovemsg = "You finished taking off your suit.";
180		}
181	} else {
182		off_msg(otmp);
183	}
184	return(1);
185}
186
187int
188doweararm()
189{
190	struct obj *otmp;
191	int delay;
192	int err = 0;
193	long mask = 0;
194
195	otmp = getobj("[", "wear");
196	if(!otmp) return(0);
197	if(otmp->owornmask & W_ARMOR) {
198		pline("You are already wearing that!");
199		return(0);
200	}
201	if(otmp->otyp == HELMET){
202		if(uarmh) {
203			pline("You are already wearing a helmet.");
204			err++;
205		} else
206			mask = W_ARMH;
207	} else if(otmp->otyp == SHIELD){
208		if(uarms) pline("You are already wearing a shield."), err++;
209		if(uwep && uwep->otyp == TWO_HANDED_SWORD)
210	pline("You cannot wear a shield and wield a two-handed sword."), err++;
211		if(!err) mask = W_ARMS;
212	} else if(otmp->otyp == PAIR_OF_GLOVES) {
213		if(uarmg) {
214			pline("You are already wearing gloves.");
215			err++;
216		} else
217		if(uwep && uwep->cursed) {
218			pline("You cannot wear gloves over your weapon.");
219			err++;
220		} else
221			mask = W_ARMG;
222	} else {
223		if(uarm) {
224			if(otmp->otyp != ELVEN_CLOAK || uarm2) {
225				pline("You are already wearing some armor.");
226				err++;
227			}
228		}
229		if(!err) mask = W_ARM;
230	}
231	if(otmp == uwep && uwep->cursed) {
232		if(!err++)
233			pline("%s is welded to your hand.", Doname(uwep));
234	}
235	if(err) return(0);
236	setworn(otmp, mask);
237	if(otmp == uwep)
238		setuwep((struct obj *) 0);
239	delay = -objects[otmp->otyp].oc_delay;
240	if(delay){
241		nomul(delay);
242		nomovemsg = "You finished your dressing manoeuvre.";
243	}
244	otmp->known = 1;
245	return(1);
246}
247
248int
249dowearring()
250{
251	struct obj *otmp;
252	long mask = 0;
253	long oldprop;
254
255	if(uleft && uright){
256		pline("There are no more ring-fingers to fill.");
257		return(0);
258	}
259	otmp = getobj("=", "wear");
260	if(!otmp) 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) mask = RIGHT_RING;
274	else if(uright) mask = LEFT_RING;
275	else do {
276		char answer;
277
278 		pline("What ring-finger, Right or Left? ");
279		if(strchr(quitchars, (answer = readchar())))
280			return(0);
281		switch(answer){
282		case 'l':
283		case 'L':
284			mask = LEFT_RING;
285			break;
286		case 'r':
287		case 'R':
288			mask = RIGHT_RING;
289			break;
290		}
291	} while(!mask);
292	setworn(otmp, mask);
293	if(otmp == uwep)
294		setuwep((struct obj *) 0);
295	oldprop = u.uprops[PROP(otmp->otyp)].p_flgs;
296	u.uprops[PROP(otmp->otyp)].p_flgs |= mask;
297	switch(otmp->otyp){
298	case RIN_LEVITATION:
299		if(!oldprop) float_up();
300		break;
301	case RIN_PROTECTION_FROM_SHAPE_CHANGERS:
302		rescham();
303		break;
304	case RIN_GAIN_STRENGTH:
305		u.ustr += otmp->spe;
306		u.ustrmax += otmp->spe;
307		if(u.ustr > 118) u.ustr = 118;
308		if(u.ustrmax > 118) u.ustrmax = 118;
309		flags.botl = 1;
310		break;
311	case RIN_INCREASE_DAMAGE:
312		u.udaminc += otmp->spe;
313		break;
314	}
315	prinv(otmp);
316	return(1);
317}
318
319void
320ringoff(struct obj *obj)
321{
322	long mask;
323
324	mask = obj->owornmask & W_RING;
325	setworn((struct obj *) 0, obj->owornmask);
326	if(!(u.uprops[PROP(obj->otyp)].p_flgs & mask))
327		impossible("Strange... I didnt know you had that ring.");
328	u.uprops[PROP(obj->otyp)].p_flgs &= ~mask;
329	switch(obj->otyp) {
330	case RIN_FIRE_RESISTANCE:
331		/* Bad luck if the player is in hell... --jgm */
332		if (!Fire_resistance && dlevel >= 30) {
333			pline("The flames of Hell burn you to a crisp.");
334			killer = "stupidity in hell";
335			done("burned");
336		}
337		break;
338	case RIN_LEVITATION:
339		if(!Levitation) {	/* no longer floating */
340			float_down();
341		}
342		break;
343	case RIN_GAIN_STRENGTH:
344		u.ustr -= obj->spe;
345		u.ustrmax -= obj->spe;
346		if(u.ustr > 118) u.ustr = 118;
347		if(u.ustrmax > 118) u.ustrmax = 118;
348		flags.botl = 1;
349		break;
350	case RIN_INCREASE_DAMAGE:
351		u.udaminc -= obj->spe;
352		break;
353	}
354}
355
356void
357find_ac()
358{
359	int uac = 10;
360
361	if(uarm) uac -= ARM_BONUS(uarm);
362	if(uarm2) uac -= ARM_BONUS(uarm2);
363	if(uarmh) uac -= ARM_BONUS(uarmh);
364	if(uarms) uac -= ARM_BONUS(uarms);
365	if(uarmg) uac -= ARM_BONUS(uarmg);
366	if(uleft && uleft->otyp == RIN_PROTECTION) uac -= uleft->spe;
367	if(uright && uright->otyp == RIN_PROTECTION) uac -= uright->spe;
368	if(uac != u.uac){
369		u.uac = uac;
370		flags.botl = 1;
371	}
372}
373
374void
375glibr()
376{
377	struct obj *otmp;
378	int xfl = 0;
379
380	if(!uarmg) if(uleft || uright) {
381		/* Note: at present also cursed rings fall off */
382		pline("Your %s off your fingers.",
383			(uleft && uright) ? "rings slip" : "ring slips");
384		xfl++;
385		if((otmp = uleft) != Null(obj)){
386			ringoff(uleft);
387			dropx(otmp);
388		}
389		if((otmp = uright) != Null(obj)){
390			ringoff(uright);
391			dropx(otmp);
392		}
393	}
394	if((otmp = uwep) != Null(obj)){
395		/* Note: at present also cursed weapons fall */
396		setuwep((struct obj *) 0);
397		dropx(otmp);
398		pline("Your weapon %sslips from your hands.",
399			xfl ? "also " : "");
400	}
401}
402
403struct obj *
404some_armor()
405{
406	struct obj *otmph = uarm;
407
408	if(uarmh && (!otmph || !rn2(4))) otmph = uarmh;
409	if(uarmg && (!otmph || !rn2(4))) otmph = uarmg;
410	if(uarms && (!otmph || !rn2(4))) otmph = uarms;
411	return(otmph);
412}
413
414void
415corrode_armor()
416{
417	struct obj *otmph = some_armor();
418
419	if(otmph){
420		if(otmph->rustfree ||
421		   otmph->otyp == ELVEN_CLOAK ||
422		   otmph->otyp == LEATHER_ARMOR ||
423		   otmph->otyp == STUDDED_LEATHER_ARMOR) {
424			pline("Your %s not affected!",
425				aobjnam(otmph, "are"));
426			return;
427		}
428		pline("Your %s!", aobjnam(otmph, "corrode"));
429		otmph->spe--;
430	}
431}
432