Merge branch 'vendor/OPENSSH'
[games.git] / games / hack / hack.do_wear.c
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 }