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