kernel - Fix excessive call stack depth on stuck interrupt
[dragonfly.git] / games / hack / hack.do_wear.c
blobc7f78028e18a1b1f0086e4fbe31f0af7a1ab05a1
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 $ */
6 #include "hack.h"
7 extern char quitchars[];
9 static void off_msg(struct obj *);
10 static int dorr(struct obj *);
11 static bool cursed(struct obj *);
13 static void
14 off_msg(struct obj *otmp)
16 pline("You were wearing %s.", doname(otmp));
19 int
20 doremarm(void)
22 struct obj *otmp;
24 if (!uarm && !uarmh && !uarms && !uarmg) {
25 pline("Not wearing any armor.");
26 return (0);
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);
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);
43 armoroff(otmp);
44 return (1);
47 int
48 doremring(void)
50 if (!uleft && !uright) {
51 pline("Not wearing any ring.");
52 return (0);
54 if (!uleft)
55 return (dorr(uright));
56 if (!uright)
57 return (dorr(uleft));
58 if (uleft && uright)
59 for (;;) {
60 char answer;
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 %% */
77 /* NOTREACHED */
78 return (0);
81 static int
82 dorr(struct obj *otmp)
84 if (cursed(otmp))
85 return (0);
86 ringoff(otmp);
87 off_msg(otmp);
88 return (1);
91 static bool
92 cursed(struct obj *otmp)
94 if (otmp->cursed) {
95 pline("You can't. It appears to be cursed.");
96 return (1);
98 return (0);
101 bool
102 armoroff(struct obj *otmp)
104 int delay = -objects[otmp->otyp].oc_delay;
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.";
121 } else
122 off_msg(otmp);
123 return (1);
127 doweararm(void)
129 struct obj *otmp;
130 int delay;
131 int err = 0;
132 long mask = 0;
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);
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++;
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++;
172 if (!err)
173 mask = W_ARM;
175 if (otmp == uwep && uwep->cursed) {
176 if (!err++)
177 pline("%s is welded to your hand.", Doname(uwep));
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.";
189 otmp->known = 1;
190 return (1);
194 dowearring(void)
196 struct obj *otmp;
197 long mask = 0;
198 long oldprop;
200 if (uleft && uright) {
201 pline("There are no more ring-fingers to fill.");
202 return (0);
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);
211 if (otmp == uleft || otmp == uright) {
212 pline("You are already wearing that.");
213 return (0);
215 if (otmp == uwep && uwep->cursed) {
216 pline("%s is welded to your hand.", Doname(uwep));
217 return (0);
219 if (uleft)
220 mask = RIGHT_RING;
221 else if (uright)
222 mask = LEFT_RING;
223 else
224 do {
225 char answer;
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;
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;
267 prinv(otmp);
268 return (1);
271 void
272 ringoff(struct obj *obj)
274 long mask;
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");
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;
309 void
310 find_ac(void)
312 int uac = 10;
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;
334 void
335 glibr(void)
337 struct obj *otmp;
338 int xfl = 0;
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);
350 if ((otmp = uright) != NULL) {
351 ringoff(uright);
352 dropx(otmp);
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 " : "");
364 struct obj *
365 some_armor(void)
367 struct obj *otmph = uarm;
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);
378 void
379 corrode_armor(void)
381 struct obj *otmph = some_armor();
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;
392 pline("Your %s!", aobjnam(otmph, "corrode"));
393 otmph->spe--;