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