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 static 142 ck_ice_box(obj) register struct obj *obj; { 143 return(obj->o_cnt_id == current_ice_box->o_id); 144 } 145 146 static 147 out_ice_box(obj) register struct obj *obj; { 148 register struct obj *otmp; 149 if(obj == fcobj) fcobj = fcobj->nobj; 150 else { 151 for(otmp = fcobj; otmp->nobj != obj; otmp = otmp->nobj) 152 if(!otmp->nobj) panic("out_ice_box"); 153 otmp->nobj = obj->nobj; 154 } 155 current_ice_box->owt -= obj->owt; 156 obj->age = moves - obj->age; /* simulated point of time */ 157 (void) addinv(obj); 158 } 159 160 static 161 use_ice_box(obj) register struct obj *obj; { 162 register int cnt = 0; 163 register struct obj *otmp; 164 current_ice_box = obj; /* for use by in/out_ice_box */ 165 for(otmp = fcobj; otmp; otmp = otmp->nobj) 166 if(otmp->o_cnt_id == obj->o_id) 167 cnt++; 168 if(!cnt) pline("Your ice-box is empty."); 169 else { 170 pline("Do you want to take something out of the ice-box? [yn] "); 171 if(readchar() == 'y') 172 if(askchain(fcobj, (char *) 0, 0, out_ice_box, ck_ice_box, 0)) 173 return; 174 pline("That was all. Do you wish to put something in? [yn] "); 175 if(readchar() != 'y') return; 176 } 177 /* call getobj: 0: allow cnt; #: allow all types; %: expect food */ 178 otmp = getobj("0#%", "put in"); 179 if(!otmp || !in_ice_box(otmp)) 180 flags.move = multi = 0; 181 } 182 183 static 184 struct monst * 185 bchit(ddx,ddy,range,sym) register int ddx,ddy,range; char sym; { 186 register struct monst *mtmp = (struct monst *) 0; 187 register int bchx = u.ux, bchy = u.uy; 188 189 if(sym) Tmp_at(-1, sym); /* open call */ 190 while(range--) { 191 bchx += ddx; 192 bchy += ddy; 193 if(mtmp = m_at(bchx,bchy)) 194 break; 195 if(!ZAP_POS(levl[bchx][bchy].typ)) { 196 bchx -= ddx; 197 bchy -= ddy; 198 break; 199 } 200 if(sym) Tmp_at(bchx, bchy); 201 } 202 if(sym) Tmp_at(-1, -1); 203 return(mtmp); 204 } 205 206 /* ARGSUSED */ 207 static 208 use_whistle(obj) struct obj *obj; { 209 register struct monst *mtmp = fmon; 210 pline("You produce a high whistling sound."); 211 while(mtmp) { 212 if(dist(mtmp->mx,mtmp->my) < u.ulevel*20) { 213 if(mtmp->msleep) 214 mtmp->msleep = 0; 215 if(mtmp->mtame) 216 EDOG(mtmp)->whistletime = moves; 217 } 218 mtmp = mtmp->nmon; 219 } 220 } 221 222 /* ARGSUSED */ 223 static 224 use_magic_whistle(obj) struct obj *obj; { 225 register struct monst *mtmp = fmon; 226 pline("You produce a strange whistling sound."); 227 while(mtmp) { 228 if(mtmp->mtame) mnexto(mtmp); 229 mtmp = mtmp->nmon; 230 } 231 } 232 233 static int dig_effort; /* effort expended on current pos */ 234 static uchar dig_level; 235 static coord dig_pos; 236 static boolean dig_down; 237 238 static 239 dig() { 240 register struct rm *lev; 241 register dpx = dig_pos.x, dpy = dig_pos.y; 242 243 /* perhaps a nymph stole his pick-axe while he was busy digging */ 244 /* or perhaps he teleported away */ 245 if(u.uswallow || !uwep || uwep->otyp != PICK_AXE || 246 dig_level != dlevel || 247 ((dig_down && (dpx != u.ux || dpy != u.uy)) || 248 (!dig_down && dist(dpx,dpy) > 2))) 249 return(0); 250 251 dig_effort += 10 + abon() + uwep->spe + rn2(5); 252 if(dig_down) { 253 if(!xdnstair) { 254 pline("The floor here seems too hard to dig in."); 255 return(0); 256 } 257 if(dig_effort > 250) { 258 dighole(); 259 return(0); /* done with digging */ 260 } 261 if(dig_effort > 50) { 262 register struct trap *ttmp = t_at(dpx,dpy); 263 264 if(!ttmp) { 265 ttmp = maketrap(dpx,dpy,PIT); 266 ttmp->tseen = 1; 267 pline("You have dug a pit."); 268 u.utrap = rn1(4,2); 269 u.utraptype = TT_PIT; 270 return(0); 271 } 272 } 273 } else 274 if(dig_effort > 100) { 275 register char *digtxt; 276 register struct obj *obj; 277 278 lev = &levl[dpx][dpy]; 279 if(obj = sobj_at(ENORMOUS_ROCK, dpx, dpy)) { 280 fracture_rock(obj); 281 digtxt = "The rock falls apart."; 282 } else if(!lev->typ || lev->typ == SCORR) { 283 lev->typ = CORR; 284 digtxt = "You succeeded in cutting away some rock."; 285 } else if(lev->typ == HWALL || lev->typ == VWALL 286 || lev->typ == SDOOR) { 287 lev->typ = xdnstair ? DOOR : ROOM; 288 digtxt = "You just made an opening in the wall."; 289 } else 290 digtxt = "Now what exactly was it that you were digging in?"; 291 mnewsym(dpx, dpy); 292 prl(dpx, dpy); 293 pline(digtxt); /* after mnewsym & prl */ 294 return(0); 295 } else { 296 if(IS_WALL(levl[dpx][dpy].typ)) { 297 register int rno = inroom(dpx,dpy); 298 299 if(rno >= 0 && rooms[rno].rtype >= 8) { 300 pline("This wall seems too hard to dig into."); 301 return(0); 302 } 303 } 304 pline("You hit the rock with all your might."); 305 } 306 return(1); 307 } 308 309 /* When will hole be finished? Very rough indication used by shopkeeper. */ 310 holetime() { 311 return( (occupation == dig) ? (250 - dig_effort)/20 : -1); 312 } 313 314 dighole() 315 { 316 register struct trap *ttmp = t_at(u.ux, u.uy); 317 318 if(!xdnstair) { 319 pline("The floor here seems too hard to dig in."); 320 } else { 321 if(ttmp) 322 ttmp->ttyp = TRAPDOOR; 323 else 324 ttmp = maketrap(u.ux, u.uy, TRAPDOOR); 325 ttmp->tseen = 1; 326 pline("You've made a hole in the floor."); 327 if(!u.ustuck) { 328 if(inshop()) 329 shopdig(1); 330 pline("You fall through ..."); 331 if(u.utraptype == TT_PIT) { 332 u.utrap = 0; 333 u.utraptype = 0; 334 } 335 goto_level(dlevel+1, FALSE); 336 } 337 } 338 } 339 340 static 341 use_pick_axe(obj) 342 struct obj *obj; 343 { 344 char dirsyms[12]; 345 extern char sdir[]; 346 register char *dsp = dirsyms, *sdp = sdir; 347 register struct monst *mtmp; 348 register struct rm *lev; 349 register int rx, ry, res = 0; 350 351 if(obj != uwep) { 352 if(uwep && uwep->cursed) { 353 /* Andreas Bormann - ihnp4!decvax!mcvax!unido!ab */ 354 pline("Since your weapon is welded to your hand,"); 355 pline("you cannot use that pick-axe."); 356 return(0); 357 } 358 pline("You now wield %s.", doname(obj)); 359 setuwep(obj); 360 res = 1; 361 } 362 while(*sdp) { 363 (void) movecmd(*sdp); /* sets u.dx and u.dy and u.dz */ 364 rx = u.ux + u.dx; 365 ry = u.uy + u.dy; 366 if(u.dz > 0 || (u.dz == 0 && isok(rx, ry) && 367 (IS_ROCK(levl[rx][ry].typ) 368 || sobj_at(ENORMOUS_ROCK, rx, ry)))) 369 *dsp++ = *sdp; 370 sdp++; 371 } 372 *dsp = 0; 373 pline("In what direction do you want to dig? [%s] ", dirsyms); 374 if(!getdir(0)) /* no txt */ 375 return(res); 376 if(u.uswallow && attack(u.ustuck)) /* return(1) */; 377 else 378 if(u.dz < 0) 379 pline("You cannot reach the ceiling."); 380 else 381 if(u.dz == 0) { 382 if(Confusion) 383 confdir(); 384 rx = u.ux + u.dx; 385 ry = u.uy + u.dy; 386 if((mtmp = m_at(rx, ry)) && attack(mtmp)) 387 return(1); 388 if(!isok(rx, ry)) { 389 pline("Clash!"); 390 return(1); 391 } 392 lev = &levl[rx][ry]; 393 if(lev->typ == DOOR) 394 pline("Your %s against the door.", 395 aobjnam(obj, "clang")); 396 else if(!IS_ROCK(lev->typ) 397 && !sobj_at(ENORMOUS_ROCK, rx, ry)) { 398 /* ACCESSIBLE or POOL */ 399 pline("You swing your %s through thin air.", 400 aobjnam(obj, (char *) 0)); 401 } else { 402 if(dig_pos.x != rx || dig_pos.y != ry 403 || dig_level != dlevel || dig_down) { 404 dig_down = FALSE; 405 dig_pos.x = rx; 406 dig_pos.y = ry; 407 dig_level = dlevel; 408 dig_effort = 0; 409 pline("You start digging."); 410 } else 411 pline("You continue digging."); 412 occupation = dig; 413 occtxt = "digging"; 414 } 415 } else if(Levitation) { 416 pline("You cannot reach the floor."); 417 } else { 418 if(dig_pos.x != u.ux || dig_pos.y != u.uy 419 || dig_level != dlevel || !dig_down) { 420 dig_down = TRUE; 421 dig_pos.x = u.ux; 422 dig_pos.y = u.uy; 423 dig_level = dlevel; 424 dig_effort = 0; 425 pline("You start digging in the floor."); 426 if(inshop()) 427 shopdig(0); 428 } else 429 pline("You continue digging in the floor."); 430 occupation = dig; 431 occtxt = "digging"; 432 } 433 return(1); 434 } 435