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