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