1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2: /* hack.apply.c - version 1.0.3 */ 3: 4: #include "hack.h" 5: #include "def.edog.h" 6: #include "def.mkroom.h" 7: extern struct monst *bchit(); 8: extern struct obj *addinv(); 9: extern struct trap *maketrap(); 10: extern int (*occupation)(); 11: extern char *occtxt; 12: extern char quitchars[]; 13: extern char pl_character[]; 14: 15: doapply() { 16: register struct obj *obj; 17: register int res = 1; 18: 19: obj = getobj("(", "use or apply"); 20: if(!obj) return(0); 21: 22: switch(obj->otyp){ 23: case EXPENSIVE_CAMERA: 24: use_camera(obj); break; 25: case ICE_BOX: 26: use_ice_box(obj); break; 27: case PICK_AXE: 28: res = use_pick_axe(obj); 29: break; 30: 31: case MAGIC_WHISTLE: 32: if(pl_character[0] == 'W' || u.ulevel > 9) { 33: use_magic_whistle(obj); 34: break; 35: } 36: /* fall into next case */ 37: case WHISTLE: 38: use_whistle(obj); 39: break; 40: 41: case CAN_OPENER: 42: if(!carrying(TIN)) { 43: pline("You have no can to open."); 44: goto xit; 45: } 46: pline("You cannot open a tin without eating its contents."); 47: pline("In order to eat, use the 'e' command."); 48: if(obj != uwep) 49: pline("Opening the tin will be much easier if you wield the can-opener."); 50: goto xit; 51: 52: default: 53: pline("Sorry, I don't know how to use that."); 54: xit: 55: nomul(0); 56: return(0); 57: } 58: nomul(0); 59: return(res); 60: } 61: 62: /* ARGSUSED */ 63: static 64: use_camera(obj) /* register */ struct obj *obj; { 65: register struct monst *mtmp; 66: if(!getdir(1)){ /* ask: in what direction? */ 67: flags.move = multi = 0; 68: return; 69: } 70: if(u.uswallow) { 71: pline("You take a picture of %s's stomach.", monnam(u.ustuck)); 72: return; 73: } 74: if(u.dz) { 75: pline("You take a picture of the %s.", 76: (u.dz > 0) ? "floor" : "ceiling"); 77: return; 78: } 79: if(mtmp = bchit(u.dx, u.dy, COLNO, '!')) { 80: if(mtmp->msleep){ 81: mtmp->msleep = 0; 82: pline("The flash awakens %s.", monnam(mtmp)); /* a3 */ 83: } else 84: if(mtmp->data->mlet != 'y') 85: if(mtmp->mcansee || mtmp->mblinded){ 86: register int tmp = dist(mtmp->mx,mtmp->my); 87: register int tmp2; 88: if(cansee(mtmp->mx,mtmp->my)) 89: pline("%s is blinded by the flash!", Monnam(mtmp)); 90: setmangry(mtmp); 91: if(tmp < 9 && !mtmp->isshk && rn2(4)) { 92: mtmp->mflee = 1; 93: if(rn2(4)) mtmp->mfleetim = rnd(100); 94: } 95: if(tmp < 3) mtmp->mcansee = mtmp->mblinded = 0; 96: else { 97: tmp2 = mtmp->mblinded; 98: tmp2 += rnd(1 + 50/tmp); 99: if(tmp2 > 127) tmp2 = 127; 100: mtmp->mblinded = tmp2; 101: mtmp->mcansee = 0; 102: } 103: } 104: } 105: } 106: 107: static 108: struct obj *current_ice_box; /* a local variable of use_ice_box, to be 109: used by its local procedures in/ck_ice_box */ 110: static 111: in_ice_box(obj) register struct obj *obj; { 112: if(obj == current_ice_box || 113: (Punished && (obj == uball || obj == uchain))){ 114: pline("You must be kidding."); 115: return(0); 116: } 117: if(obj->owornmask & (W_ARMOR | W_RING)) { 118: pline("You cannot refrigerate something you are wearing."); 119: return(0); 120: } 121: if(obj->owt + current_ice_box->owt > 70) { 122: pline("It won't fit."); 123: return(1); /* be careful! */ 124: } 125: if(obj == uwep) { 126: if(uwep->cursed) { 127: pline("Your weapon is welded to your hand!"); 128: return(0); 129: } 130: setuwep((struct obj *) 0); 131: } 132: current_ice_box->owt += obj->owt; 133: freeinv(obj); 134: obj->o_cnt_id = current_ice_box->o_id; 135: obj->nobj = fcobj; 136: fcobj = obj; 137: obj->age = moves - obj->age; /* actual age */ 138: return(1); 139: } 140: 141: /* 142: KLUDGE -- pointer to static function passed around 143: -- not allowed in overlay scheme 144: static 145: */ 146: ck_ice_box(obj) register struct obj *obj; { 147: return(obj->o_cnt_id == current_ice_box->o_id); 148: } 149: 150: /* 151: KLUDGE -- pointer to static function passed around 152: -- not allowed in overlay scheme 153: static 154: */ 155: out_ice_box(obj) register struct obj *obj; { 156: register struct obj *otmp; 157: if(obj == fcobj) fcobj = fcobj->nobj; 158: else { 159: for(otmp = fcobj; otmp->nobj != obj; otmp = otmp->nobj) 160: if(!otmp->nobj) panic("out_ice_box"); 161: otmp->nobj = obj->nobj; 162: } 163: current_ice_box->owt -= obj->owt; 164: obj->age = moves - obj->age; /* simulated point of time */ 165: (void) addinv(obj); 166: } 167: 168: static 169: use_ice_box(obj) register struct obj *obj; { 170: register int cnt = 0; 171: register struct obj *otmp; 172: current_ice_box = obj; /* for use by in/out_ice_box */ 173: for(otmp = fcobj; otmp; otmp = otmp->nobj) 174: if(otmp->o_cnt_id == obj->o_id) 175: cnt++; 176: if(!cnt) pline("Your ice-box is empty."); 177: else { 178: pline("Do you want to take something out of the ice-box? [yn] "); 179: if(readchar() == 'y') 180: if(askchain(fcobj, (char *) 0, 0, out_ice_box, ck_ice_box, 0)) 181: return; 182: pline("That was all. Do you wish to put something in? [yn] "); 183: if(readchar() != 'y') return; 184: } 185: /* call getobj: 0: allow cnt; #: allow all types; %: expect food */ 186: otmp = getobj("0#%", "put in"); 187: if(!otmp || !in_ice_box(otmp)) 188: flags.move = multi = 0; 189: } 190: 191: static 192: struct monst * 193: bchit(ddx,ddy,range,sym) register int ddx,ddy,range; char sym; { 194: register struct monst *mtmp = (struct monst *) 0; 195: register int bchx = u.ux, bchy = u.uy; 196: 197: if(sym) Tmp_at(-1, sym); /* open call */ 198: while(range--) { 199: bchx += ddx; 200: bchy += ddy; 201: if(mtmp = m_at(bchx,bchy)) 202: break; 203: if(!ZAP_POS(levl[bchx][bchy].typ)) { 204: bchx -= ddx; 205: bchy -= ddy; 206: break; 207: } 208: if(sym) Tmp_at(bchx, bchy); 209: } 210: if(sym) Tmp_at(-1, -1); 211: return(mtmp); 212: } 213: 214: /* ARGSUSED */ 215: static 216: use_whistle(obj) struct obj *obj; { 217: register struct monst *mtmp = fmon; 218: pline("You produce a high whistling sound."); 219: while(mtmp) { 220: if(dist(mtmp->mx,mtmp->my) < u.ulevel*20) { 221: if(mtmp->msleep) 222: mtmp->msleep = 0; 223: if(mtmp->mtame) 224: EDOG(mtmp)->whistletime = moves; 225: } 226: mtmp = mtmp->nmon; 227: } 228: } 229: 230: /* ARGSUSED */ 231: static 232: use_magic_whistle(obj) struct obj *obj; { 233: register struct monst *mtmp = fmon; 234: pline("You produce a strange whistling sound."); 235: while(mtmp) { 236: if(mtmp->mtame) mnexto(mtmp); 237: mtmp = mtmp->nmon; 238: } 239: } 240: 241: static int dig_effort; /* effort expended on current pos */ 242: static uchar dig_level; 243: static coord dig_pos; 244: static boolean dig_down; 245: 246: /* 247: KLUDGE -- pointer to static function passed around 248: -- not allowed in overlay scheme 249: static 250: */ 251: dig() { 252: register struct rm *lev; 253: register dpx = dig_pos.x, dpy = dig_pos.y; 254: 255: /* perhaps a nymph stole his pick-axe while he was busy digging */ 256: /* or perhaps he teleported away */ 257: if(u.uswallow || !uwep || uwep->otyp != PICK_AXE || 258: dig_level != dlevel || 259: ((dig_down && (dpx != u.ux || dpy != u.uy)) || 260: (!dig_down && dist(dpx,dpy) > 2))) 261: return(0); 262: 263: dig_effort += 10 + abon() + uwep->spe + rn2(5); 264: if(dig_down) { 265: if(!xdnstair) { 266: pline("The floor here seems too hard to dig in."); 267: return(0); 268: } 269: if(dig_effort > 250) { 270: dighole(); 271: return(0); /* done with digging */ 272: } 273: if(dig_effort > 50) { 274: register struct trap *ttmp = t_at(dpx,dpy); 275: 276: if(!ttmp) { 277: ttmp = maketrap(dpx,dpy,PIT); 278: ttmp->tseen = 1; 279: pline("You have dug a pit."); 280: u.utrap = rn1(4,2); 281: u.utraptype = TT_PIT; 282: return(0); 283: } 284: } 285: } else 286: if(dig_effort > 100) { 287: register char *digtxt; 288: register struct obj *obj; 289: 290: lev = &levl[dpx][dpy]; 291: if(obj = sobj_at(ENORMOUS_ROCK, dpx, dpy)) { 292: fracture_rock(obj); 293: digtxt = "The rock falls apart."; 294: } else if(!lev->typ || lev->typ == SCORR) { 295: lev->typ = CORR; 296: digtxt = "You succeeded in cutting away some rock."; 297: } else if(lev->typ == HWALL || lev->typ == VWALL 298: || lev->typ == SDOOR) { 299: lev->typ = xdnstair ? DOOR : ROOM; 300: digtxt = "You just made an opening in the wall."; 301: } else 302: digtxt = "Now what exactly was it that you were digging in?"; 303: mnewsym(dpx, dpy); 304: prl(dpx, dpy); 305: pline(digtxt); /* after mnewsym & prl */ 306: return(0); 307: } else { 308: if(IS_WALL(levl[dpx][dpy].typ)) { 309: register int rno = inroom(dpx,dpy); 310: 311: if(rno >= 0 && rooms[rno].rtype >= 8) { 312: pline("This wall seems too hard to dig into."); 313: return(0); 314: } 315: } 316: pline("You hit the rock with all your might."); 317: } 318: return(1); 319: } 320: 321: /* When will hole be finished? Very rough indication used by shopkeeper. */ 322: holetime() { 323: return( (occupation == dig) ? (250 - dig_effort)/20 : -1); 324: } 325: 326: dighole() 327: { 328: register struct trap *ttmp = t_at(u.ux, u.uy); 329: 330: if(!xdnstair) { 331: pline("The floor here seems too hard to dig in."); 332: } else { 333: if(ttmp) 334: ttmp->ttyp = TRAPDOOR; 335: else 336: ttmp = maketrap(u.ux, u.uy, TRAPDOOR); 337: ttmp->tseen = 1; 338: pline("You've made a hole in the floor."); 339: if(!u.ustuck) { 340: if(inshop()) 341: shopdig(1); 342: pline("You fall through ..."); 343: if(u.utraptype == TT_PIT) { 344: u.utrap = 0; 345: u.utraptype = 0; 346: } 347: goto_level(dlevel+1, FALSE); 348: } 349: } 350: } 351: 352: static 353: use_pick_axe(obj) 354: struct obj *obj; 355: { 356: char dirsyms[12]; 357: extern char sdir[]; 358: register char *dsp = dirsyms, *sdp = sdir; 359: register struct monst *mtmp; 360: register struct rm *lev; 361: register int rx, ry, res = 0; 362: 363: if(obj != uwep) { 364: if(uwep && uwep->cursed) { 365: /* Andreas Bormann - ihnp4!decvax!mcvax!unido!ab */ 366: pline("Since your weapon is welded to your hand,"); 367: pline("you cannot use that pick-axe."); 368: return(0); 369: } 370: pline("You now wield %s.", doname(obj)); 371: setuwep(obj); 372: res = 1; 373: } 374: while(*sdp) { 375: (void) movecmd(*sdp); /* sets u.dx and u.dy and u.dz */ 376: rx = u.ux + u.dx; 377: ry = u.uy + u.dy; 378: if(u.dz > 0 || (u.dz == 0 && isok(rx, ry) && 379: (IS_ROCK(levl[rx][ry].typ) 380: || sobj_at(ENORMOUS_ROCK, rx, ry)))) 381: *dsp++ = *sdp; 382: sdp++; 383: } 384: *dsp = 0; 385: pline("In what direction do you want to dig? [%s] ", dirsyms); 386: if(!getdir(0)) /* no txt */ 387: return(res); 388: if(u.uswallow && attack(u.ustuck)) /* return(1) */; 389: else 390: if(u.dz < 0) 391: pline("You cannot reach the ceiling."); 392: else 393: if(u.dz == 0) { 394: if(Confusion) 395: confdir(); 396: rx = u.ux + u.dx; 397: ry = u.uy + u.dy; 398: if((mtmp = m_at(rx, ry)) && attack(mtmp)) 399: return(1); 400: if(!isok(rx, ry)) { 401: pline("Clash!"); 402: return(1); 403: } 404: lev = &levl[rx][ry]; 405: if(lev->typ == DOOR) 406: pline("Your %s against the door.", 407: aobjnam(obj, "clang")); 408: else if(!IS_ROCK(lev->typ) 409: && !sobj_at(ENORMOUS_ROCK, rx, ry)) { 410: /* ACCESSIBLE or POOL */ 411: pline("You swing your %s through thin air.", 412: aobjnam(obj, (char *) 0)); 413: } else { 414: if(dig_pos.x != rx || dig_pos.y != ry 415: || dig_level != dlevel || dig_down) { 416: dig_down = FALSE; 417: dig_pos.x = rx; 418: dig_pos.y = ry; 419: dig_level = dlevel; 420: dig_effort = 0; 421: pline("You start digging."); 422: } else 423: pline("You continue digging."); 424: occupation = dig; 425: occtxt = "digging"; 426: } 427: } else if(Levitation) { 428: pline("You cannot reach the floor."); 429: } else { 430: if(dig_pos.x != u.ux || dig_pos.y != u.uy 431: || dig_level != dlevel || !dig_down) { 432: dig_down = TRUE; 433: dig_pos.x = u.ux; 434: dig_pos.y = u.uy; 435: dig_level = dlevel; 436: dig_effort = 0; 437: pline("You start digging in the floor."); 438: if(inshop()) 439: shopdig(0); 440: } else 441: pline("You continue digging in the floor."); 442: occupation = dig; 443: occtxt = "digging"; 444: } 445: return(1); 446: }