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