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