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