1/* SCCS Id: @(#)muse.c 3.4 2002/12/23 */ 2/* Copyright (C) 1990 by Ken Arromdee */ 3/* NetHack may be freely redistributed. See license for details. */ 4 5/* 6 * Monster item usage routines. 7 */ 8 9#include "hack.h" 10#include "edog.h" 11 12extern const int monstr[]; 13 14boolean m_using = FALSE; 15 16/* Let monsters use magic items. Arbitrary assumptions: Monsters only use 17 * scrolls when they can see, monsters know when wands have 0 charges, monsters 18 * cannot recognize if items are cursed are not, monsters which are confused 19 * don't know not to read scrolls, etc.... 20 */ 21 22STATIC_DCL struct permonst *FDECL(muse_newcham_mon, (struct monst *)); 23STATIC_DCL int FDECL(precheck, (struct monst *,struct obj *)); 24STATIC_DCL void FDECL(mzapmsg, (struct monst *,struct obj *,BOOLEAN_P)); 25STATIC_DCL void FDECL(mreadmsg, (struct monst *,struct obj *)); 26STATIC_DCL void FDECL(mquaffmsg, (struct monst *,struct obj *)); 27STATIC_PTR int FDECL(mbhitm, (struct monst *,struct obj *)); 28STATIC_DCL void FDECL(mbhit, 29 (struct monst *,int,int FDECL((*),(MONST_P,OBJ_P)), 30 int FDECL((*),(OBJ_P,OBJ_P)),struct obj *)); 31STATIC_DCL void FDECL(you_aggravate, (struct monst *)); 32STATIC_DCL void FDECL(mon_consume_unstone, (struct monst *,struct obj *, 33 BOOLEAN_P,BOOLEAN_P)); 34 35static struct musable { 36 struct obj *offensive; 37 struct obj *defensive; 38 struct obj *misc; 39 int has_offense, has_defense, has_misc; 40 /* =0, no capability; otherwise, different numbers. 41 * If it's an object, the object is also set (it's 0 otherwise). 42 */ 43} m; 44static int trapx, trapy; 45static boolean zap_oseen; 46 /* for wands which use mbhitm and are zapped at players. We usually 47 * want an oseen local to the function, but this is impossible since the 48 * function mbhitm has to be compatible with the normal zap routines, 49 * and those routines don't remember who zapped the wand. 50 */ 51 52/* Any preliminary checks which may result in the monster being unable to use 53 * the item. Returns 0 if nothing happened, 2 if the monster can't do anything 54 * (i.e. it teleported) and 1 if it's dead. 55 */ 56STATIC_OVL int 57precheck(mon, obj) 58struct monst *mon; 59struct obj *obj; 60{ 61 boolean vis; 62 63 if (!obj) return 0; 64 vis = cansee(mon->mx, mon->my); 65 66 if (obj->oclass == POTION_CLASS) { 67 coord cc; 68 static const char *empty = "The potion turns out to be empty."; 69 const char *potion_descr; 70 struct monst *mtmp; 71#define POTION_OCCUPANT_CHANCE(n) (13 + 2*(n)) /* also in potion.c */ 72 73 potion_descr = OBJ_DESCR(objects[obj->otyp]); 74 if (potion_descr && !strcmp(potion_descr, "milky")) { 75 if ( flags.ghost_count < MAXMONNO && 76 !rn2(POTION_OCCUPANT_CHANCE(flags.ghost_count))) { 77 if (!enexto(&cc, mon->mx, mon->my, &mons[PM_GHOST])) return 0; 78 mquaffmsg(mon, obj); 79 m_useup(mon, obj); 80 mtmp = makemon(&mons[PM_GHOST], cc.x, cc.y, NO_MM_FLAGS); 81 if (!mtmp) { 82 if (vis) pline(empty); 83 } else { 84 if (vis) { 85 pline("As %s opens the bottle, an enormous %s emerges!", 86 mon_nam(mon), 87 Hallucination ? rndmonnam() : (const char *)"ghost"); 88 pline("%s is frightened to death, and unable to move.", 89 Monnam(mon)); 90 } 91 mon->mcanmove = 0; 92 mon->mfrozen = 3; 93 } 94 return 2; 95 } 96 } 97 if (potion_descr && !strcmp(potion_descr, "smoky") && 98 flags.djinni_count < MAXMONNO && 99 !rn2(POTION_OCCUPANT_CHANCE(flags.djinni_count))) { 100 if (!enexto(&cc, mon->mx, mon->my, &mons[PM_DJINNI])) return 0; 101 mquaffmsg(mon, obj); 102 m_useup(mon, obj); 103 mtmp = makemon(&mons[PM_DJINNI], cc.x, cc.y, NO_MM_FLAGS); 104 if (!mtmp) { 105 if (vis) pline(empty); 106 } else { 107 if (vis) 108 pline("In a cloud of smoke, %s emerges!", 109 a_monnam(mtmp)); 110 pline("%s speaks.", vis ? Monnam(mtmp) : Something); 111 /* I suspect few players will be upset that monsters */ 112 /* can't wish for wands of death here.... */ 113 if (rn2(2)) { 114 verbalize("You freed me!"); 115 mtmp->mpeaceful = 1; 116 set_malign(mtmp); 117 } else { 118 verbalize("It is about time."); 119 if (vis) pline("%s vanishes.", Monnam(mtmp)); 120 mongone(mtmp); 121 } 122 } 123 return 2; 124 } 125 } 126 if (obj->oclass == WAND_CLASS && obj->cursed && !rn2(100)) { 127 int dam = d(obj->spe+2, 6); 128 129 if (flags.soundok) { 130 if (vis) pline("%s zaps %s, which suddenly explodes!", 131 Monnam(mon), an(xname(obj))); 132 else You_hear("a zap and an explosion in the distance."); 133 } 134 m_useup(mon, obj); 135 if (mon->mhp <= dam) { 136 monkilled(mon, "", AD_RBRE); 137 return 1; 138 } 139 else mon->mhp -= dam; 140 m.has_defense = m.has_offense = m.has_misc = 0; 141 /* Only one needed to be set to 0 but the others are harmless */ 142 } 143 return 0; 144} 145 146STATIC_OVL void 147mzapmsg(mtmp, otmp, self) 148struct monst *mtmp; 149struct obj *otmp; 150boolean self; 151{ 152 if (!canseemon(mtmp)) { 153 if (flags.soundok) 154 You_hear("a %s zap.", 155 (distu(mtmp->mx,mtmp->my) <= (BOLT_LIM+1)*(BOLT_LIM+1)) ? 156 "nearby" : "distant"); 157 } else if (self) 158 pline("%s zaps %sself with %s!", 159 Monnam(mtmp), mhim(mtmp), doname(otmp)); 160 else { 161 pline("%s zaps %s!", Monnam(mtmp), an(xname(otmp))); 162 stop_occupation(); 163 } 164} 165 166STATIC_OVL void 167mreadmsg(mtmp, otmp) 168struct monst *mtmp; 169struct obj *otmp; 170{ 171 boolean vismon = canseemon(mtmp); 172 char onambuf[BUFSZ]; 173 short saverole; 174 unsigned savebknown; 175 176 if (!vismon && !flags.soundok) 177 return; /* no feedback */ 178 179 otmp->dknown = 1; /* seeing or hearing it read reveals its label */ 180 /* shouldn't be able to hear curse/bless status of unseen scrolls; 181 for priest characters, bknown will always be set during naming */ 182 savebknown = otmp->bknown; 183 saverole = Role_switch; 184 if (!vismon) { 185 otmp->bknown = 0; 186 if (Role_if(PM_PRIEST)) Role_switch = 0; 187 } 188 Strcpy(onambuf, singular(otmp, doname)); 189 Role_switch = saverole; 190 otmp->bknown = savebknown; 191 192 if (vismon) 193 pline("%s reads %s!", Monnam(mtmp), onambuf); 194 else 195 You_hear("%s reading %s.", 196 x_monnam(mtmp, ARTICLE_A, (char *)0, 197 (SUPPRESS_IT|SUPPRESS_INVISIBLE|SUPPRESS_SADDLE), FALSE), 198 onambuf); 199 200 if (mtmp->mconf) 201 pline("Being confused, %s mispronounces the magic words...", 202 vismon ? mon_nam(mtmp) : mhe(mtmp)); 203} 204 205STATIC_OVL void 206mquaffmsg(mtmp, otmp) 207struct monst *mtmp; 208struct obj *otmp; 209{ 210 if (canseemon(mtmp)) { 211 otmp->dknown = 1; 212 pline("%s drinks %s!", Monnam(mtmp), singular(otmp, doname)); 213 } else 214 if (flags.soundok) 215 You_hear("a chugging sound."); 216} 217 218/* Defines for various types of stuff. The order in which monsters prefer 219 * to use them is determined by the order of the code logic, not the 220 * numerical order in which they are defined. 221 */ 222#define MUSE_SCR_TELEPORTATION 1 223#define MUSE_WAN_TELEPORTATION_SELF 2 224#define MUSE_POT_HEALING 3 225#define MUSE_POT_EXTRA_HEALING 4 226#define MUSE_WAN_DIGGING 5 227#define MUSE_TRAPDOOR 6 228#define MUSE_TELEPORT_TRAP 7 229#define MUSE_UPSTAIRS 8 230#define MUSE_DOWNSTAIRS 9 231#define MUSE_WAN_CREATE_MONSTER 10 232#define MUSE_SCR_CREATE_MONSTER 11 233#define MUSE_UP_LADDER 12 234#define MUSE_DN_LADDER 13 235#define MUSE_SSTAIRS 14 236#define MUSE_WAN_TELEPORTATION 15 237#define MUSE_BUGLE 16 238#define MUSE_UNICORN_HORN 17 239#define MUSE_POT_FULL_HEALING 18 240#define MUSE_LIZARD_CORPSE 19 241/* 242#define MUSE_INNATE_TPT 9999 243 * We cannot use this. Since monsters get unlimited teleportation, if they 244 * were allowed to teleport at will you could never catch them. Instead, 245 * assume they only teleport at random times, despite the inconsistency that if 246 * you polymorph into one you teleport at will. 247 */ 248 249/* Select a defensive item/action for a monster. Returns TRUE iff one is 250 * found. 251 */ 252boolean 253find_defensive(mtmp) 254struct monst *mtmp; 255{ 256 register struct obj *obj = 0; 257 struct trap *t; 258 int x=mtmp->mx, y=mtmp->my; 259 boolean stuck = (mtmp == u.ustuck); 260 boolean immobile = (mtmp->data->mmove == 0); 261 int fraction; 262 263 if (is_animal(mtmp->data) || mindless(mtmp->data)) 264 return FALSE; 265 if(dist2(x, y, mtmp->mux, mtmp->muy) > 25) 266 return FALSE; 267 if (u.uswallow && stuck) return FALSE; 268 269 m.defensive = (struct obj *)0; 270 m.has_defense = 0; 271 272 /* since unicorn horns don't get used up, the monster would look 273 * silly trying to use the same cursed horn round after round 274 */ 275 if (mtmp->mconf || mtmp->mstun || !mtmp->mcansee) { 276 if (!is_unicorn(mtmp->data) && !nohands(mtmp->data)) { 277 for(obj = mtmp->minvent; obj; obj = obj->nobj) 278 if (obj->otyp == UNICORN_HORN && !obj->cursed) 279 break; 280 } 281 if (obj || is_unicorn(mtmp->data)) { 282 m.defensive = obj; 283 m.has_defense = MUSE_UNICORN_HORN; 284 return TRUE; 285 } 286 } 287 288 if (mtmp->mconf) { 289 for(obj = mtmp->minvent; obj; obj = obj->nobj) { 290 if (obj->otyp == CORPSE && obj->corpsenm == PM_LIZARD) { 291 m.defensive = obj; 292 m.has_defense = MUSE_LIZARD_CORPSE; 293 return TRUE; 294 } 295 } 296 } 297 298 /* It so happens there are two unrelated cases when we might want to 299 * check specifically for healing alone. The first is when the monster 300 * is blind (healing cures blindness). The second is when the monster 301 * is peaceful; then we don't want to flee the player, and by 302 * coincidence healing is all there is that doesn't involve fleeing. 303 * These would be hard to combine because of the control flow. 304 * Pestilence won't use healing even when blind. 305 */ 306 if (!mtmp->mcansee && !nohands(mtmp->data) && 307 mtmp->data != &mons[PM_PESTILENCE]) { 308 if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) != 0) { 309 m.defensive = obj; 310 m.has_defense = MUSE_POT_FULL_HEALING; 311 return TRUE; 312 } 313 if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) { 314 m.defensive = obj; 315 m.has_defense = MUSE_POT_EXTRA_HEALING; 316 return TRUE; 317 } 318 if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) { 319 m.defensive = obj; 320 m.has_defense = MUSE_POT_HEALING; 321 return TRUE; 322 } 323 } 324 325 fraction = u.ulevel < 10 ? 5 : u.ulevel < 14 ? 4 : 3; 326 if(mtmp->mhp >= mtmp->mhpmax || 327 (mtmp->mhp >= 10 && mtmp->mhp*fraction >= mtmp->mhpmax)) 328 return FALSE; 329 330 if (mtmp->mpeaceful) { 331 if (!nohands(mtmp->data)) { 332 if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) != 0) { 333 m.defensive = obj; 334 m.has_defense = MUSE_POT_FULL_HEALING; 335 return TRUE; 336 } 337 if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) { 338 m.defensive = obj; 339 m.has_defense = MUSE_POT_EXTRA_HEALING; 340 return TRUE; 341 } 342 if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) { 343 m.defensive = obj; 344 m.has_defense = MUSE_POT_HEALING; 345 return TRUE; 346 } 347 } 348 return FALSE; 349 } 350 351 if (levl[x][y].typ == STAIRS && !stuck && !immobile) { 352 if (x == xdnstair && y == ydnstair && !is_floater(mtmp->data)) 353 m.has_defense = MUSE_DOWNSTAIRS; 354 if (x == xupstair && y == yupstair && ledger_no(&u.uz) != 1) 355 /* Unfair to let the monsters leave the dungeon with the Amulet */ 356 /* (or go to the endlevel since you also need it, to get there) */ 357 m.has_defense = MUSE_UPSTAIRS; 358 } else if (levl[x][y].typ == LADDER && !stuck && !immobile) { 359 if (x == xupladder && y == yupladder) 360 m.has_defense = MUSE_UP_LADDER; 361 if (x == xdnladder && y == ydnladder && !is_floater(mtmp->data)) 362 m.has_defense = MUSE_DN_LADDER; 363 } else if (sstairs.sx && sstairs.sx == x && sstairs.sy == y) { 364 m.has_defense = MUSE_SSTAIRS; 365 } else if (!stuck && !immobile) { 366 /* Note: trap doors take precedence over teleport traps. */ 367 int xx, yy; 368 369 for(xx = x-1; xx <= x+1; xx++) for(yy = y-1; yy <= y+1; yy++) 370 if (isok(xx,yy)) 371 if (xx != u.ux && yy != u.uy) 372 if (mtmp->data != &mons[PM_GRID_BUG] || xx == x || yy == y) 373 if ((xx==x && yy==y) || !level.monsters[xx][yy]) 374 if ((t = t_at(xx,yy)) != 0) 375 if ((verysmall(mtmp->data) || throws_rocks(mtmp->data) || 376 passes_walls(mtmp->data)) || !sobj_at(BOULDER, xx, yy)) 377 if (!onscary(xx,yy,mtmp)) { 378 if ((t->ttyp == TRAPDOOR || t->ttyp == HOLE) 379 && !is_floater(mtmp->data) 380 && !mtmp->isshk && !mtmp->isgd 381 && !mtmp->ispriest 382 && Can_fall_thru(&u.uz) 383 ) { 384 trapx = xx; 385 trapy = yy; 386 m.has_defense = MUSE_TRAPDOOR; 387 } else if (t->ttyp == TELEP_TRAP && m.has_defense != MUSE_TRAPDOOR) { 388 trapx = xx; 389 trapy = yy; 390 m.has_defense = MUSE_TELEPORT_TRAP; 391 } 392 } 393 } 394 395 if (nohands(mtmp->data)) /* can't use objects */ 396 goto botm; 397 398 if (is_mercenary(mtmp->data) && (obj = m_carrying(mtmp, BUGLE))) { 399 int xx, yy; 400 struct monst *mon; 401 402 /* Distance is arbitrary. What we really want to do is 403 * have the soldier play the bugle when it sees or 404 * remembers soldiers nearby... 405 */ 406 for(xx = x-3; xx <= x+3; xx++) for(yy = y-3; yy <= y+3; yy++) 407 if (isok(xx,yy)) 408 if ((mon = m_at(xx,yy)) && is_mercenary(mon->data) && 409 mon->data != &mons[PM_GUARD] && 410 (mon->msleeping || (!mon->mcanmove))) { 411 m.defensive = obj; 412 m.has_defense = MUSE_BUGLE; 413 } 414 } 415 416 /* use immediate physical escape prior to attempting magic */ 417 if (m.has_defense) /* stairs, trap door or tele-trap, bugle alert */ 418 goto botm; 419 420 /* kludge to cut down on trap destruction (particularly portals) */ 421 t = t_at(x,y); 422 if (t && (t->ttyp == PIT || t->ttyp == SPIKED_PIT || 423 t->ttyp == WEB || t->ttyp == BEAR_TRAP)) 424 t = 0; /* ok for monster to dig here */ 425 426#define nomore(x) if(m.has_defense==x) continue; 427 for (obj = mtmp->minvent; obj; obj = obj->nobj) { 428 /* don't always use the same selection pattern */ 429 if (m.has_defense && !rn2(3)) break; 430 431 /* nomore(MUSE_WAN_DIGGING); */ 432 if (m.has_defense == MUSE_WAN_DIGGING) break; 433 if (obj->otyp == WAN_DIGGING && obj->spe > 0 && !stuck && !t 434 && !mtmp->isshk && !mtmp->isgd && !mtmp->ispriest 435 && !is_floater(mtmp->data) 436 /* monsters digging in Sokoban can ruin things */ 437 && !In_sokoban(&u.uz) 438 /* digging wouldn't be effective; assume they know that */ 439 && !(levl[x][y].wall_info & W_NONDIGGABLE) 440 && !(Is_botlevel(&u.uz) || In_endgame(&u.uz)) 441 && !(is_ice(x,y) || is_pool(x,y) || is_lava(x,y)) 442 && !(mtmp->data == &mons[PM_VLAD_THE_IMPALER] 443 && In_V_tower(&u.uz))) { 444 m.defensive = obj; 445 m.has_defense = MUSE_WAN_DIGGING; 446 } 447 nomore(MUSE_WAN_TELEPORTATION_SELF); 448 nomore(MUSE_WAN_TELEPORTATION); 449 if(obj->otyp == WAN_TELEPORTATION && obj->spe > 0) { 450 /* use the TELEP_TRAP bit to determine if they know 451 * about noteleport on this level or not. Avoids 452 * ineffective re-use of teleportation. This does 453 * mean if the monster leaves the level, they'll know 454 * about teleport traps. 455 */ 456 if (!level.flags.noteleport || 457 !(mtmp->mtrapseen & (1 << (TELEP_TRAP-1)))) { 458 m.defensive = obj; 459 m.has_defense = (mon_has_amulet(mtmp)) 460 ? MUSE_WAN_TELEPORTATION 461 : MUSE_WAN_TELEPORTATION_SELF; 462 } 463 } 464 nomore(MUSE_SCR_TELEPORTATION); 465 if(obj->otyp == SCR_TELEPORTATION && mtmp->mcansee 466 && haseyes(mtmp->data) 467 && (!obj->cursed || 468 (!(mtmp->isshk && inhishop(mtmp)) 469 && !mtmp->isgd && !mtmp->ispriest))) { 470 /* see WAN_TELEPORTATION case above */ 471 if (!level.flags.noteleport || 472 !(mtmp->mtrapseen & (1 << (TELEP_TRAP-1)))) { 473 m.defensive = obj; 474 m.has_defense = MUSE_SCR_TELEPORTATION; 475 } 476 } 477 478 if (mtmp->data != &mons[PM_PESTILENCE]) { 479 nomore(MUSE_POT_FULL_HEALING); 480 if(obj->otyp == POT_FULL_HEALING) { 481 m.defensive = obj; 482 m.has_defense = MUSE_POT_FULL_HEALING; 483 } 484 nomore(MUSE_POT_EXTRA_HEALING); 485 if(obj->otyp == POT_EXTRA_HEALING) { 486 m.defensive = obj; 487 m.has_defense = MUSE_POT_EXTRA_HEALING; 488 } 489 nomore(MUSE_WAN_CREATE_MONSTER); 490 if(obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) { 491 m.defensive = obj; 492 m.has_defense = MUSE_WAN_CREATE_MONSTER; 493 } 494 nomore(MUSE_POT_HEALING); 495 if(obj->otyp == POT_HEALING) { 496 m.defensive = obj; 497 m.has_defense = MUSE_POT_HEALING; 498 } 499 } else { /* Pestilence */ 500 nomore(MUSE_POT_FULL_HEALING); 501 if (obj->otyp == POT_SICKNESS) { 502 m.defensive = obj; 503 m.has_defense = MUSE_POT_FULL_HEALING; 504 } 505 nomore(MUSE_WAN_CREATE_MONSTER); 506 if (obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) { 507 m.defensive = obj; 508 m.has_defense = MUSE_WAN_CREATE_MONSTER; 509 } 510 } 511 nomore(MUSE_SCR_CREATE_MONSTER); 512 if(obj->otyp == SCR_CREATE_MONSTER) { 513 m.defensive = obj; 514 m.has_defense = MUSE_SCR_CREATE_MONSTER; 515 } 516 } 517botm: return((boolean)(!!m.has_defense)); 518#undef nomore 519} 520 521/* Perform a defensive action for a monster. Must be called immediately 522 * after find_defensive(). Return values are 0: did something, 1: died, 523 * 2: did something and can't attack again (i.e. teleported). 524 */ 525int 526use_defensive(mtmp) 527struct monst *mtmp; 528{ 529 int i, fleetim, how = 0; 530 struct obj *otmp = m.defensive; 531 boolean vis, vismon, oseen; 532 const char *mcsa = "%s can see again."; 533 534 if ((i = precheck(mtmp, otmp)) != 0) return i; 535 vis = cansee(mtmp->mx, mtmp->my); 536 vismon = canseemon(mtmp); 537 oseen = otmp && vismon; 538 539 /* when using defensive choice to run away, we want monster to avoid 540 rushing right straight back; don't override if already scared */ 541 fleetim = !mtmp->mflee ? (33 - (30 * mtmp->mhp / mtmp->mhpmax)) : 0; 542#define m_flee(m) if (fleetim && !m->iswiz) \ 543 { monflee(m, fleetim, FALSE, FALSE); } 544 545 switch(m.has_defense) { 546 case MUSE_UNICORN_HORN: 547 if (vismon) { 548 if (otmp) 549 pline("%s uses a unicorn horn!", Monnam(mtmp)); 550 else 551 pline_The("tip of %s's horn glows!", mon_nam(mtmp)); 552 } 553 if (!mtmp->mcansee) { 554 mtmp->mcansee = 1; 555 mtmp->mblinded = 0; 556 if (vismon) pline(mcsa, Monnam(mtmp)); 557 } else if (mtmp->mconf || mtmp->mstun) { 558 mtmp->mconf = mtmp->mstun = 0; 559 if (vismon) 560 pline("%s seems steadier now.", Monnam(mtmp)); 561 } else impossible("No need for unicorn horn?"); 562 return 2; 563 case MUSE_BUGLE: 564 if (vismon) 565 pline("%s plays %s!", Monnam(mtmp), doname(otmp)); 566 else if (flags.soundok) 567 You_hear("a bugle playing reveille!"); 568 awaken_soldiers(); 569 return 2; 570 case MUSE_WAN_TELEPORTATION_SELF: 571 if ((mtmp->isshk && inhishop(mtmp)) 572 || mtmp->isgd || mtmp->ispriest) return 2; 573 m_flee(mtmp); 574 mzapmsg(mtmp, otmp, TRUE); 575 otmp->spe--; 576 how = WAN_TELEPORTATION; 577mon_tele: 578 if (tele_restrict(mtmp)) { /* mysterious force... */ 579 if (vismon && how) /* mentions 'teleport' */ 580 makeknown(how); 581 /* monster learns that teleportation isn't useful here */ 582 if (level.flags.noteleport) 583 mtmp->mtrapseen |= (1 << (TELEP_TRAP-1)); 584 return 2; 585 } 586 if (( 587#if 0 588 mon_has_amulet(mtmp) || 589#endif 590 On_W_tower_level(&u.uz)) && !rn2(3)) { 591 if (vismon) 592 pline("%s seems disoriented for a moment.", 593 Monnam(mtmp)); 594 return 2; 595 } 596 if (oseen && how) makeknown(how); 597 (void) rloc(mtmp, FALSE); 598 return 2; 599 case MUSE_WAN_TELEPORTATION: 600 zap_oseen = oseen; 601 mzapmsg(mtmp, otmp, FALSE); 602 otmp->spe--; 603 m_using = TRUE; 604 mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp); 605 /* monster learns that teleportation isn't useful here */ 606 if (level.flags.noteleport) 607 mtmp->mtrapseen |= (1 << (TELEP_TRAP-1)); 608 m_using = FALSE; 609 return 2; 610 case MUSE_SCR_TELEPORTATION: 611 { 612 int obj_is_cursed = otmp->cursed; 613 614 if (mtmp->isshk || mtmp->isgd || mtmp->ispriest) return 2; 615 m_flee(mtmp); 616 mreadmsg(mtmp, otmp); 617 m_useup(mtmp, otmp); /* otmp might be free'ed */ 618 how = SCR_TELEPORTATION; 619 if (obj_is_cursed || mtmp->mconf) { 620 int nlev; 621 d_level flev; 622 623 if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) { 624 if (vismon) 625 pline("%s seems very disoriented for a moment.", 626 Monnam(mtmp)); 627 return 2; 628 } 629 nlev = random_teleport_level(); 630 if (nlev == depth(&u.uz)) { 631 if (vismon) 632 pline("%s shudders for a moment.", 633 Monnam(mtmp)); 634 return 2; 635 } 636 get_level(&flev, nlev); 637 migrate_to_level(mtmp, ledger_no(&flev), MIGR_RANDOM, 638 (coord *)0); 639 if (oseen) makeknown(SCR_TELEPORTATION); 640 } else goto mon_tele; 641 return 2; 642 } 643 case MUSE_WAN_DIGGING: 644 { struct trap *ttmp; 645 646 m_flee(mtmp); 647 mzapmsg(mtmp, otmp, FALSE); 648 otmp->spe--; 649 if (oseen) makeknown(WAN_DIGGING); 650 if (IS_FURNITURE(levl[mtmp->mx][mtmp->my].typ) || 651 IS_DRAWBRIDGE(levl[mtmp->mx][mtmp->my].typ) || 652 (is_drawbridge_wall(mtmp->mx, mtmp->my) >= 0) || 653 (sstairs.sx && sstairs.sx == mtmp->mx && 654 sstairs.sy == mtmp->my)) { 655 pline_The("digging ray is ineffective."); 656 return 2; 657 } 658 if (!Can_dig_down(&u.uz)) { 659 if(canseemon(mtmp)) 660 pline_The("%s here is too hard to dig in.", 661 surface(mtmp->mx, mtmp->my)); 662 return 2; 663 } 664 ttmp = maketrap(mtmp->mx, mtmp->my, HOLE); 665 if (!ttmp) return 2; 666 seetrap(ttmp); 667 if (vis) { 668 pline("%s has made a hole in the %s.", Monnam(mtmp), 669 surface(mtmp->mx, mtmp->my)); 670 pline("%s %s through...", Monnam(mtmp), 671 is_flyer(mtmp->data) ? "dives" : "falls"); 672 } else if (flags.soundok) 673 You_hear("%s crash through the %s.", something, 674 surface(mtmp->mx, mtmp->my)); 675 /* we made sure that there is a level for mtmp to go to */ 676 migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 677 MIGR_RANDOM, (coord *)0); 678 return 2; 679 } 680 case MUSE_WAN_CREATE_MONSTER: 681 { coord cc; 682 /* pm: 0 => random, eel => aquatic, croc => amphibious */ 683 struct permonst *pm = !is_pool(mtmp->mx, mtmp->my) ? 0 : 684 &mons[u.uinwater ? PM_GIANT_EEL : PM_CROCODILE]; 685 struct monst *mon; 686 687 if (!enexto(&cc, mtmp->mx, mtmp->my, pm)) return 0; 688 mzapmsg(mtmp, otmp, FALSE); 689 otmp->spe--; 690 mon = makemon((struct permonst *)0, cc.x, cc.y, NO_MM_FLAGS); 691 if (mon && canspotmon(mon) && oseen) 692 makeknown(WAN_CREATE_MONSTER); 693 return 2; 694 } 695 case MUSE_SCR_CREATE_MONSTER: 696 { coord cc; 697 struct permonst *pm = 0, *fish = 0; 698 int cnt = 1; 699 struct monst *mon; 700 boolean known = FALSE; 701 702 if (!rn2(73)) cnt += rnd(4); 703 if (mtmp->mconf || otmp->cursed) cnt += 12; 704 if (mtmp->mconf) pm = fish = &mons[PM_ACID_BLOB]; 705 else if (is_pool(mtmp->mx, mtmp->my)) 706 fish = &mons[u.uinwater ? PM_GIANT_EEL : PM_CROCODILE]; 707 mreadmsg(mtmp, otmp); 708 while(cnt--) { 709 /* `fish' potentially gives bias towards water locations; 710 `pm' is what to actually create (0 => random) */ 711 if (!enexto(&cc, mtmp->mx, mtmp->my, fish)) break; 712 mon = makemon(pm, cc.x, cc.y, NO_MM_FLAGS); 713 if (mon && canspotmon(mon)) known = TRUE; 714 } 715 /* The only case where we don't use oseen. For wands, you 716 * have to be able to see the monster zap the wand to know 717 * what type it is. For teleport scrolls, you have to see 718 * the monster to know it teleported. 719 */ 720 if (known) 721 makeknown(SCR_CREATE_MONSTER); 722 else if (!objects[SCR_CREATE_MONSTER].oc_name_known 723 && !objects[SCR_CREATE_MONSTER].oc_uname) 724 docall(otmp); 725 m_useup(mtmp, otmp); 726 return 2; 727 } 728 case MUSE_TRAPDOOR: 729 /* trap doors on "bottom" levels of dungeons are rock-drop 730 * trap doors, not holes in the floor. We check here for 731 * safety. 732 */ 733 if (Is_botlevel(&u.uz)) return 0; 734 m_flee(mtmp); 735 if (vis) { 736 struct trap *t; 737 t = t_at(trapx,trapy); 738 pline("%s %s into a %s!", Monnam(mtmp), 739 makeplural(locomotion(mtmp->data, "jump")), 740 t->ttyp == TRAPDOOR ? "trap door" : "hole"); 741 if (levl[trapx][trapy].typ == SCORR) { 742 levl[trapx][trapy].typ = CORR; 743 unblock_point(trapx, trapy); 744 } 745 seetrap(t_at(trapx,trapy)); 746 } 747 748 /* don't use rloc_to() because worm tails must "move" */ 749 remove_monster(mtmp->mx, mtmp->my); 750 newsym(mtmp->mx, mtmp->my); /* update old location */ 751 place_monster(mtmp, trapx, trapy); 752 if (mtmp->wormno) worm_move(mtmp); 753 newsym(trapx, trapy); 754 755 migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 756 MIGR_RANDOM, (coord *)0); 757 return 2; 758 case MUSE_UPSTAIRS: 759 /* Monsters without amulets escape the dungeon and are 760 * gone for good when they leave up the up stairs. 761 * Monsters with amulets would reach the endlevel, 762 * which we cannot allow since that would leave the 763 * player stranded. 764 */ 765 if (ledger_no(&u.uz) == 1) { 766 if (mon_has_special(mtmp)) 767 return 0; 768 if (vismon) 769 pline("%s escapes the dungeon!", Monnam(mtmp)); 770 mongone(mtmp); 771 return 2; 772 } 773 m_flee(mtmp); 774 if (Inhell && mon_has_amulet(mtmp) && !rn2(4) && 775 (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz) - 3)) { 776 if (vismon) pline( 777 "As %s climbs the stairs, a mysterious force momentarily surrounds %s...", 778 mon_nam(mtmp), mhim(mtmp)); 779 /* simpler than for the player; this will usually be 780 the Wizard and he'll immediately go right to the 781 upstairs, so there's not much point in having any 782 chance for a random position on the current level */ 783 migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 784 MIGR_RANDOM, (coord *)0); 785 } else { 786 if (vismon) pline("%s escapes upstairs!", Monnam(mtmp)); 787 migrate_to_level(mtmp, ledger_no(&u.uz) - 1, 788 MIGR_STAIRS_DOWN, (coord *)0); 789 } 790 return 2; 791 case MUSE_DOWNSTAIRS: 792 m_flee(mtmp); 793 if (vismon) pline("%s escapes downstairs!", Monnam(mtmp)); 794 migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 795 MIGR_STAIRS_UP, (coord *)0); 796 return 2; 797 case MUSE_UP_LADDER: 798 m_flee(mtmp); 799 if (vismon) pline("%s escapes up the ladder!", Monnam(mtmp)); 800 migrate_to_level(mtmp, ledger_no(&u.uz) - 1, 801 MIGR_LADDER_DOWN, (coord *)0); 802 return 2; 803 case MUSE_DN_LADDER: 804 m_flee(mtmp); 805 if (vismon) pline("%s escapes down the ladder!", Monnam(mtmp)); 806 migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 807 MIGR_LADDER_UP, (coord *)0); 808 return 2; 809 case MUSE_SSTAIRS: 810 m_flee(mtmp); 811 /* the stairs leading up from the 1st level are */ 812 /* regular stairs, not sstairs. */ 813 if (sstairs.up) { 814 if (vismon) 815 pline("%s escapes upstairs!", Monnam(mtmp)); 816 if(Inhell) { 817 migrate_to_level(mtmp, ledger_no(&sstairs.tolev), 818 MIGR_RANDOM, (coord *)0); 819 return 2; 820 } 821 } else if (vismon) 822 pline("%s escapes downstairs!", Monnam(mtmp)); 823 migrate_to_level(mtmp, ledger_no(&sstairs.tolev), 824 MIGR_SSTAIRS, (coord *)0); 825 return 2; 826 case MUSE_TELEPORT_TRAP: 827 m_flee(mtmp); 828 if (vis) { 829 pline("%s %s onto a teleport trap!", Monnam(mtmp), 830 makeplural(locomotion(mtmp->data, "jump"))); 831 if (levl[trapx][trapy].typ == SCORR) { 832 levl[trapx][trapy].typ = CORR; 833 unblock_point(trapx, trapy); 834 } 835 seetrap(t_at(trapx,trapy)); 836 } 837 /* don't use rloc_to() because worm tails must "move" */ 838 remove_monster(mtmp->mx, mtmp->my); 839 newsym(mtmp->mx, mtmp->my); /* update old location */ 840 place_monster(mtmp, trapx, trapy); 841 if (mtmp->wormno) worm_move(mtmp); 842 newsym(trapx, trapy); 843 844 goto mon_tele; 845 case MUSE_POT_HEALING: 846 mquaffmsg(mtmp, otmp); 847 i = d(6 + 2 * bcsign(otmp), 4); 848 mtmp->mhp += i; 849 if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = ++mtmp->mhpmax; 850 if (!otmp->cursed && !mtmp->mcansee) { 851 mtmp->mcansee = 1; 852 mtmp->mblinded = 0; 853 if (vismon) pline(mcsa, Monnam(mtmp)); 854 } 855 if (vismon) pline("%s looks better.", Monnam(mtmp)); 856 if (oseen) makeknown(POT_HEALING); 857 m_useup(mtmp, otmp); 858 return 2; 859 case MUSE_POT_EXTRA_HEALING: 860 mquaffmsg(mtmp, otmp); 861 i = d(6 + 2 * bcsign(otmp), 8); 862 mtmp->mhp += i; 863 if (mtmp->mhp > mtmp->mhpmax) 864 mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 5 : 2)); 865 if (!mtmp->mcansee) { 866 mtmp->mcansee = 1; 867 mtmp->mblinded = 0; 868 if (vismon) pline(mcsa, Monnam(mtmp)); 869 } 870 if (vismon) pline("%s looks much better.", Monnam(mtmp)); 871 if (oseen) makeknown(POT_EXTRA_HEALING); 872 m_useup(mtmp, otmp); 873 return 2; 874 case MUSE_POT_FULL_HEALING: 875 mquaffmsg(mtmp, otmp); 876 if (otmp->otyp == POT_SICKNESS) unbless(otmp); /* Pestilence */ 877 mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 8 : 4)); 878 if (!mtmp->mcansee && otmp->otyp != POT_SICKNESS) { 879 mtmp->mcansee = 1; 880 mtmp->mblinded = 0; 881 if (vismon) pline(mcsa, Monnam(mtmp)); 882 } 883 if (vismon) pline("%s looks completely healed.", Monnam(mtmp)); 884 if (oseen) makeknown(otmp->otyp); 885 m_useup(mtmp, otmp); 886 return 2; 887 case MUSE_LIZARD_CORPSE: 888 /* not actually called for its unstoning effect */ 889 mon_consume_unstone(mtmp, otmp, FALSE, FALSE); 890 return 2; 891 case 0: return 0; /* i.e. an exploded wand */ 892 default: impossible("%s wanted to perform action %d?", Monnam(mtmp), 893 m.has_defense); 894 break; 895 } 896 return 0; 897#undef m_flee 898} 899 900int 901rnd_defensive_item(mtmp) 902struct monst *mtmp; 903{ 904 struct permonst *pm = mtmp->data; 905 int difficulty = monstr[(monsndx(pm))]; 906 int trycnt = 0; 907 908 if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data) 909 || pm->mlet == S_GHOST 910# ifdef KOPS 911 || pm->mlet == S_KOP 912# endif 913 ) return 0; 914 try_again: 915 switch (rn2(8 + (difficulty > 3) + (difficulty > 6) + 916 (difficulty > 8))) { 917 case 6: case 9: 918 if (level.flags.noteleport && ++trycnt < 2) 919 goto try_again; 920 if (!rn2(3)) return WAN_TELEPORTATION; 921 /* else FALLTHRU */ 922 case 0: case 1: 923 return SCR_TELEPORTATION; 924 case 8: case 10: 925 if (!rn2(3)) return WAN_CREATE_MONSTER; 926 /* else FALLTHRU */ 927 case 2: return SCR_CREATE_MONSTER; 928 case 3: return POT_HEALING; 929 case 4: return POT_EXTRA_HEALING; 930 case 5: return (mtmp->data != &mons[PM_PESTILENCE]) ? 931 POT_FULL_HEALING : POT_SICKNESS; 932 case 7: if (is_floater(pm) || mtmp->isshk || mtmp->isgd 933 || mtmp->ispriest 934 ) 935 return 0; 936 else 937 return WAN_DIGGING; 938 } 939 /*NOTREACHED*/ 940 return 0; 941} 942 943#define MUSE_WAN_DEATH 1 944#define MUSE_WAN_SLEEP 2 945#define MUSE_WAN_FIRE 3 946#define MUSE_WAN_COLD 4 947#define MUSE_WAN_LIGHTNING 5 948#define MUSE_WAN_MAGIC_MISSILE 6 949#define MUSE_WAN_STRIKING 7 950#define MUSE_SCR_FIRE 8 951#define MUSE_POT_PARALYSIS 9 952#define MUSE_POT_BLINDNESS 10 953#define MUSE_POT_CONFUSION 11 954#define MUSE_FROST_HORN 12 955#define MUSE_FIRE_HORN 13 956#define MUSE_POT_ACID 14 957/*#define MUSE_WAN_TELEPORTATION 15*/ 958#define MUSE_POT_SLEEPING 16 959#define MUSE_SCR_EARTH 17 960 961/* Select an offensive item/action for a monster. Returns TRUE iff one is 962 * found. 963 */ 964boolean 965find_offensive(mtmp) 966struct monst *mtmp; 967{ 968 register struct obj *obj; 969 boolean ranged_stuff = lined_up(mtmp); 970 boolean reflection_skip = (Reflecting && rn2(2)); 971 struct obj *helmet = which_armor(mtmp, W_ARMH); 972 973 m.offensive = (struct obj *)0; 974 m.has_offense = 0; 975 if (mtmp->mpeaceful || is_animal(mtmp->data) || 976 mindless(mtmp->data) || nohands(mtmp->data)) 977 return FALSE; 978 if (u.uswallow) return FALSE; 979 if (in_your_sanctuary(mtmp, 0, 0)) return FALSE; 980 if (dmgtype(mtmp->data, AD_HEAL) && !uwep 981#ifdef TOURIST 982 && !uarmu 983#endif 984 && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf) 985 return FALSE; 986 987 if (!ranged_stuff) return FALSE; 988#define nomore(x) if(m.has_offense==x) continue; 989 for(obj=mtmp->minvent; obj; obj=obj->nobj) { 990 /* nomore(MUSE_WAN_DEATH); */ 991 if (!reflection_skip) { 992 if(obj->otyp == WAN_DEATH && obj->spe > 0) { 993 m.offensive = obj; 994 m.has_offense = MUSE_WAN_DEATH; 995 } 996 nomore(MUSE_WAN_SLEEP); 997 if(obj->otyp == WAN_SLEEP && obj->spe > 0 && multi >= 0) { 998 m.offensive = obj; 999 m.has_offense = MUSE_WAN_SLEEP; 1000 } 1001 nomore(MUSE_WAN_FIRE); 1002 if(obj->otyp == WAN_FIRE && obj->spe > 0) { 1003 m.offensive = obj; 1004 m.has_offense = MUSE_WAN_FIRE; 1005 } 1006 nomore(MUSE_FIRE_HORN); 1007 if(obj->otyp == FIRE_HORN && obj->spe > 0) { 1008 m.offensive = obj; 1009 m.has_offense = MUSE_FIRE_HORN; 1010 } 1011 nomore(MUSE_WAN_COLD); 1012 if(obj->otyp == WAN_COLD && obj->spe > 0) { 1013 m.offensive = obj; 1014 m.has_offense = MUSE_WAN_COLD; 1015 } 1016 nomore(MUSE_FROST_HORN); 1017 if(obj->otyp == FROST_HORN && obj->spe > 0) { 1018 m.offensive = obj; 1019 m.has_offense = MUSE_FROST_HORN; 1020 } 1021 nomore(MUSE_WAN_LIGHTNING); 1022 if(obj->otyp == WAN_LIGHTNING && obj->spe > 0) { 1023 m.offensive = obj; 1024 m.has_offense = MUSE_WAN_LIGHTNING; 1025 } 1026 nomore(MUSE_WAN_MAGIC_MISSILE); 1027 if(obj->otyp == WAN_MAGIC_MISSILE && obj->spe > 0) { 1028 m.offensive = obj; 1029 m.has_offense = MUSE_WAN_MAGIC_MISSILE; 1030 } 1031 } 1032 nomore(MUSE_WAN_STRIKING); 1033 if(obj->otyp == WAN_STRIKING && obj->spe > 0) { 1034 m.offensive = obj; 1035 m.has_offense = MUSE_WAN_STRIKING; 1036 } 1037 nomore(MUSE_POT_PARALYSIS); 1038 if(obj->otyp == POT_PARALYSIS && multi >= 0) { 1039 m.offensive = obj; 1040 m.has_offense = MUSE_POT_PARALYSIS; 1041 } 1042 nomore(MUSE_POT_BLINDNESS); 1043 if(obj->otyp == POT_BLINDNESS && !attacktype(mtmp->data, AT_GAZE)) { 1044 m.offensive = obj; 1045 m.has_offense = MUSE_POT_BLINDNESS; 1046 } 1047 nomore(MUSE_POT_CONFUSION); 1048 if(obj->otyp == POT_CONFUSION) { 1049 m.offensive = obj; 1050 m.has_offense = MUSE_POT_CONFUSION; 1051 } 1052 nomore(MUSE_POT_SLEEPING); 1053 if(obj->otyp == POT_SLEEPING) { 1054 m.offensive = obj; 1055 m.has_offense = MUSE_POT_SLEEPING; 1056 } 1057 nomore(MUSE_POT_ACID); 1058 if(obj->otyp == POT_ACID) { 1059 m.offensive = obj; 1060 m.has_offense = MUSE_POT_ACID; 1061 } 1062 /* we can safely put this scroll here since the locations that 1063 * are in a 1 square radius are a subset of the locations that 1064 * are in wand range 1065 */ 1066 nomore(MUSE_SCR_EARTH); 1067 if (obj->otyp == SCR_EARTH 1068 && ((helmet && is_metallic(helmet)) || 1069 mtmp->mconf || amorphous(mtmp->data) || 1070 passes_walls(mtmp->data) || 1071 noncorporeal(mtmp->data) || 1072 unsolid(mtmp->data) || !rn2(10)) 1073 && dist2(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy) <= 2 1074 && mtmp->mcansee && haseyes(mtmp->data) 1075#ifdef REINCARNATION 1076 && !Is_rogue_level(&u.uz) 1077#endif 1078 && (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) { 1079 m.offensive = obj; 1080 m.has_offense = MUSE_SCR_EARTH; 1081 } 1082#if 0 1083 nomore(MUSE_SCR_FIRE); 1084 if (obj->otyp == SCR_FIRE && resists_fire(mtmp) 1085 && dist2(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy) <= 2 1086 && mtmp->mcansee && haseyes(mtmp->data)) { 1087 m.offensive = obj; 1088 m.has_offense = MUSE_SCR_FIRE; 1089 } 1090#endif 1091 } 1092 return((boolean)(!!m.has_offense)); 1093#undef nomore 1094} 1095 1096STATIC_PTR 1097int 1098mbhitm(mtmp, otmp) 1099register struct monst *mtmp; 1100register struct obj *otmp; 1101{ 1102 int tmp; 1103 1104 boolean reveal_invis = FALSE; 1105 if (mtmp != &youmonst) { 1106 mtmp->msleeping = 0; 1107 if (mtmp->m_ap_type) seemimic(mtmp); 1108 } 1109 switch(otmp->otyp) { 1110 case WAN_STRIKING: 1111 reveal_invis = TRUE; 1112 if (mtmp == &youmonst) { 1113 if (zap_oseen) makeknown(WAN_STRIKING); 1114 if (Antimagic) { 1115 shieldeff(u.ux, u.uy); 1116 pline("Boing!"); 1117 } else if (rnd(20) < 10 + u.uac) { 1118 pline_The("wand hits you!"); 1119 tmp = d(2,12); 1120 if(Half_spell_damage) tmp = (tmp+1) / 2; 1121 losehp(tmp, "wand", KILLED_BY_AN); 1122 } else pline_The("wand misses you."); 1123 stop_occupation(); 1124 nomul(0); 1125 } else if (resists_magm(mtmp)) { 1126 shieldeff(mtmp->mx, mtmp->my); 1127 pline("Boing!"); 1128 } else if (rnd(20) < 10+find_mac(mtmp)) { 1129 tmp = d(2,12); 1130 hit("wand", mtmp, exclam(tmp)); 1131 (void) resist(mtmp, otmp->oclass, tmp, TELL); 1132 if (cansee(mtmp->mx, mtmp->my) && zap_oseen) 1133 makeknown(WAN_STRIKING); 1134 } else { 1135 miss("wand", mtmp); 1136 if (cansee(mtmp->mx, mtmp->my) && zap_oseen) 1137 makeknown(WAN_STRIKING); 1138 } 1139 break; 1140 case WAN_TELEPORTATION: 1141 if (mtmp == &youmonst) { 1142 if (zap_oseen) makeknown(WAN_TELEPORTATION); 1143 tele(); 1144 } else { 1145 /* for consistency with zap.c, don't identify */ 1146 if (mtmp->ispriest && 1147 *in_rooms(mtmp->mx, mtmp->my, TEMPLE)) { 1148 if (cansee(mtmp->mx, mtmp->my)) 1149 pline("%s resists the magic!", Monnam(mtmp)); 1150 mtmp->msleeping = 0; 1151 if(mtmp->m_ap_type) seemimic(mtmp); 1152 } else if (!tele_restrict(mtmp)) 1153 (void) rloc(mtmp, FALSE); 1154 } 1155 break; 1156 case WAN_CANCELLATION: 1157 case SPE_CANCELLATION: 1158 (void) cancel_monst(mtmp, otmp, FALSE, TRUE, FALSE); 1159 break; 1160 } 1161 if (reveal_invis) { 1162 if (mtmp->mhp > 0 && cansee(bhitpos.x,bhitpos.y) 1163 && !canspotmon(mtmp)) 1164 map_invisible(bhitpos.x, bhitpos.y); 1165 } 1166 return 0; 1167} 1168 1169/* A modified bhit() for monsters. Based on bhit() in zap.c. Unlike 1170 * buzz(), bhit() doesn't take into account the possibility of a monster 1171 * zapping you, so we need a special function for it. (Unless someone wants 1172 * to merge the two functions...) 1173 */ 1174STATIC_OVL void 1175mbhit(mon,range,fhitm,fhito,obj) 1176struct monst *mon; /* monster shooting the wand */ 1177register int range; /* direction and range */ 1178int FDECL((*fhitm),(MONST_P,OBJ_P)); 1179int FDECL((*fhito),(OBJ_P,OBJ_P)); /* fns called when mon/obj hit */ 1180struct obj *obj; /* 2nd arg to fhitm/fhito */ 1181{ 1182 register struct monst *mtmp; 1183 register struct obj *otmp; 1184 register uchar typ; 1185 int ddx, ddy; 1186 1187 bhitpos.x = mon->mx; 1188 bhitpos.y = mon->my; 1189 ddx = sgn(mon->mux - mon->mx); 1190 ddy = sgn(mon->muy - mon->my); 1191 1192 while(range-- > 0) { 1193 int x,y; 1194 1195 bhitpos.x += ddx; 1196 bhitpos.y += ddy; 1197 x = bhitpos.x; y = bhitpos.y; 1198 1199 if (!isok(x,y)) { 1200 bhitpos.x -= ddx; 1201 bhitpos.y -= ddy; 1202 break; 1203 } 1204 if (find_drawbridge(&x,&y)) 1205 switch (obj->otyp) { 1206 case WAN_STRIKING: 1207 destroy_drawbridge(x,y); 1208 } 1209 if(bhitpos.x==u.ux && bhitpos.y==u.uy) { 1210 (*fhitm)(&youmonst, obj); 1211 range -= 3; 1212 } else if(MON_AT(bhitpos.x, bhitpos.y)){ 1213 mtmp = m_at(bhitpos.x,bhitpos.y); 1214 if (cansee(bhitpos.x,bhitpos.y) && !canspotmon(mtmp)) 1215 map_invisible(bhitpos.x, bhitpos.y); 1216 (*fhitm)(mtmp, obj); 1217 range -= 3; 1218 } 1219 /* modified by GAN to hit all objects */ 1220 if(fhito){ 1221 int hitanything = 0; 1222 register struct obj *next_obj; 1223 1224 for(otmp = level.objects[bhitpos.x][bhitpos.y]; 1225 otmp; otmp = next_obj) { 1226 /* Fix for polymorph bug, Tim Wright */ 1227 next_obj = otmp->nexthere; 1228 hitanything += (*fhito)(otmp, obj); 1229 } 1230 if(hitanything) range--; 1231 } 1232 typ = levl[bhitpos.x][bhitpos.y].typ; 1233 if(IS_DOOR(typ) || typ == SDOOR) { 1234 switch (obj->otyp) { 1235 /* note: monsters don't use opening or locking magic 1236 at present, but keep these as placeholders */ 1237 case WAN_OPENING: 1238 case WAN_LOCKING: 1239 case WAN_STRIKING: 1240 if (doorlock(obj, bhitpos.x, bhitpos.y)) { 1241 makeknown(obj->otyp); 1242 /* if a shop door gets broken, add it to 1243 the shk's fix list (no cost to player) */ 1244 if (levl[bhitpos.x][bhitpos.y].doormask == 1245 D_BROKEN && 1246 *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE)) 1247 add_damage(bhitpos.x, bhitpos.y, 0L); 1248 } 1249 break; 1250 } 1251 } 1252 if(!ZAP_POS(typ) || (IS_DOOR(typ) && 1253 (levl[bhitpos.x][bhitpos.y].doormask & (D_LOCKED | D_CLOSED))) 1254 ) { 1255 bhitpos.x -= ddx; 1256 bhitpos.y -= ddy; 1257 break; 1258 } 1259 } 1260} 1261 1262/* Perform an offensive action for a monster. Must be called immediately 1263 * after find_offensive(). Return values are same as use_defensive(). 1264 */ 1265int 1266use_offensive(mtmp) 1267struct monst *mtmp; 1268{ 1269 int i; 1270 struct obj *otmp = m.offensive; 1271 boolean oseen; 1272 1273 /* offensive potions are not drunk, they're thrown */ 1274 if (otmp->oclass != POTION_CLASS && (i = precheck(mtmp, otmp)) != 0) 1275 return i; 1276 oseen = otmp && canseemon(mtmp); 1277 1278 switch(m.has_offense) { 1279 case MUSE_WAN_DEATH: 1280 case MUSE_WAN_SLEEP: 1281 case MUSE_WAN_FIRE: 1282 case MUSE_WAN_COLD: 1283 case MUSE_WAN_LIGHTNING: 1284 case MUSE_WAN_MAGIC_MISSILE: 1285 mzapmsg(mtmp, otmp, FALSE); 1286 otmp->spe--; 1287 if (oseen) makeknown(otmp->otyp); 1288 m_using = TRUE; 1289 buzz((int)(-30 - (otmp->otyp - WAN_MAGIC_MISSILE)), 1290 (otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6, 1291 mtmp->mx, mtmp->my, 1292 sgn(mtmp->mux-mtmp->mx), sgn(mtmp->muy-mtmp->my)); 1293 m_using = FALSE; 1294 return (mtmp->mhp <= 0) ? 1 : 2; 1295 case MUSE_FIRE_HORN: 1296 case MUSE_FROST_HORN: 1297 if (oseen) { 1298 makeknown(otmp->otyp); 1299 pline("%s plays a %s!", Monnam(mtmp), xname(otmp)); 1300 } else 1301 You_hear("a horn being played."); 1302 otmp->spe--; 1303 m_using = TRUE; 1304 buzz(-30 - ((otmp->otyp==FROST_HORN) ? AD_COLD-1 : AD_FIRE-1), 1305 rn1(6,6), mtmp->mx, mtmp->my, 1306 sgn(mtmp->mux-mtmp->mx), sgn(mtmp->muy-mtmp->my)); 1307 m_using = FALSE; 1308 return (mtmp->mhp <= 0) ? 1 : 2; 1309 case MUSE_WAN_TELEPORTATION: 1310 case MUSE_WAN_STRIKING: 1311 zap_oseen = oseen; 1312 mzapmsg(mtmp, otmp, FALSE); 1313 otmp->spe--; 1314 m_using = TRUE; 1315 mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp); 1316 m_using = FALSE; 1317 return 2; 1318 case MUSE_SCR_EARTH: 1319 { 1320 /* TODO: handle steeds */ 1321 register int x, y; 1322 /* don't use monster fields after killing it */ 1323 boolean confused = (mtmp->mconf ? TRUE : FALSE); 1324 int mmx = mtmp->mx, mmy = mtmp->my; 1325 1326 mreadmsg(mtmp, otmp); 1327 /* Identify the scroll */ 1328 if (canspotmon(mtmp)) { 1329 pline_The("%s rumbles %s %s!", ceiling(mtmp->mx, mtmp->my), 1330 otmp->blessed ? "around" : "above", 1331 mon_nam(mtmp)); 1332 if (oseen) makeknown(otmp->otyp); 1333 } else if (cansee(mtmp->mx, mtmp->my)) { 1334 pline_The("%s rumbles in the middle of nowhere!", 1335 ceiling(mtmp->mx, mtmp->my)); 1336 if (mtmp->minvis) 1337 map_invisible(mtmp->mx, mtmp->my); 1338 if (oseen) makeknown(otmp->otyp); 1339 } 1340 1341 /* Loop through the surrounding squares */ 1342 for (x = mmx-1; x <= mmx+1; x++) { 1343 for (y = mmy-1; y <= mmy+1; y++) { 1344 /* Is this a suitable spot? */ 1345 if (isok(x, y) && !closed_door(x, y) && 1346 !IS_ROCK(levl[x][y].typ) && 1347 !IS_AIR(levl[x][y].typ) && 1348 (((x == mmx) && (y == mmy)) ? 1349 !otmp->blessed : !otmp->cursed) && 1350 (x != u.ux || y != u.uy)) { 1351 register struct obj *otmp2; 1352 register struct monst *mtmp2; 1353 1354 /* Make the object(s) */ 1355 otmp2 = mksobj(confused ? ROCK : BOULDER, 1356 FALSE, FALSE); 1357 if (!otmp2) continue; /* Shouldn't happen */ 1358 otmp2->quan = confused ? rn1(5,2) : 1; 1359 otmp2->owt = weight(otmp2); 1360 1361 /* Find the monster here (might be same as mtmp) */ 1362 mtmp2 = m_at(x, y); 1363 if (mtmp2 && !amorphous(mtmp2->data) && 1364 !passes_walls(mtmp2->data) && 1365 !noncorporeal(mtmp2->data) && 1366 !unsolid(mtmp2->data)) { 1367 struct obj *helmet = which_armor(mtmp2, W_ARMH); 1368 int mdmg; 1369 1370 if (cansee(mtmp2->mx, mtmp2->my)) { 1371 pline("%s is hit by %s!", Monnam(mtmp2), 1372 doname(otmp2)); 1373 if (mtmp2->minvis && !canspotmon(mtmp2)) 1374 map_invisible(mtmp2->mx, mtmp2->my); 1375 } 1376 mdmg = dmgval(otmp2, mtmp2) * otmp2->quan; 1377 if (helmet) { 1378 if(is_metallic(helmet)) { 1379 if (canspotmon(mtmp2)) 1380 pline("Fortunately, %s is wearing a hard helmet.", mon_nam(mtmp2)); 1381 else if (flags.soundok) 1382 You_hear("a clanging sound."); 1383 if (mdmg > 2) mdmg = 2; 1384 } else { 1385 if (canspotmon(mtmp2)) 1386 pline("%s's %s does not protect %s.", 1387 Monnam(mtmp2), xname(helmet), 1388 mhim(mtmp2)); 1389 } 1390 } 1391 mtmp2->mhp -= mdmg; 1392 if (mtmp2->mhp <= 0) { 1393 pline("%s is killed.", Monnam(mtmp2)); 1394 mondied(mtmp2); 1395 } 1396 } 1397 /* Drop the rock/boulder to the floor */ 1398 if (!flooreffects(otmp2, x, y, "fall")) { 1399 place_object(otmp2, x, y); 1400 stackobj(otmp2); 1401 newsym(x, y); /* map the rock */ 1402 } 1403 } 1404 } 1405 } 1406 m_useup(mtmp, otmp); 1407 /* Attack the player */ 1408 if (distmin(mmx, mmy, u.ux, u.uy) == 1 && !otmp->cursed) { 1409 int dmg; 1410 struct obj *otmp2; 1411 1412 /* Okay, _you_ write this without repeating the code */ 1413 otmp2 = mksobj(confused ? ROCK : BOULDER, 1414 FALSE, FALSE); 1415 if (!otmp2) goto xxx_noobj; /* Shouldn't happen */ 1416 otmp2->quan = confused ? rn1(5,2) : 1; 1417 otmp2->owt = weight(otmp2); 1418 if (!amorphous(youmonst.data) && 1419 !Passes_walls && 1420 !noncorporeal(youmonst.data) && 1421 !unsolid(youmonst.data)) { 1422 You("are hit by %s!", doname(otmp2)); 1423 dmg = dmgval(otmp2, &youmonst) * otmp2->quan; 1424 if (uarmh) { 1425 if(is_metallic(uarmh)) { 1426 pline("Fortunately, you are wearing a hard helmet."); 1427 if (dmg > 2) dmg = 2; 1428 } else if (flags.verbose) { 1429 Your("%s does not protect you.", 1430 xname(uarmh)); 1431 } 1432 } 1433 } else 1434 dmg = 0; 1435 if (!flooreffects(otmp2, u.ux, u.uy, "fall")) { 1436 place_object(otmp2, u.ux, u.uy); 1437 stackobj(otmp2); 1438 newsym(u.ux, u.uy); 1439 } 1440 if (dmg) losehp(dmg, "scroll of earth", KILLED_BY_AN); 1441 } 1442 xxx_noobj: 1443 1444 return (mtmp->mhp <= 0) ? 1 : 2; 1445 } 1446#if 0 1447 case MUSE_SCR_FIRE: 1448 { 1449 boolean vis = cansee(mtmp->mx, mtmp->my); 1450 1451 mreadmsg(mtmp, otmp); 1452 if (mtmp->mconf) { 1453 if (vis) 1454 pline("Oh, what a pretty fire!"); 1455 } else { 1456 struct monst *mtmp2; 1457 int num; 1458 1459 if (vis) 1460 pline_The("scroll erupts in a tower of flame!"); 1461 shieldeff(mtmp->mx, mtmp->my); 1462 pline("%s is uninjured.", Monnam(mtmp)); 1463 (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE); 1464 (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); 1465 (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE); 1466 num = (2*(rn1(3, 3) + 2 * bcsign(otmp)) + 1)/3; 1467 if (Fire_resistance) 1468 You("are not harmed."); 1469 burn_away_slime(); 1470 if (Half_spell_damage) num = (num+1) / 2; 1471 else losehp(num, "scroll of fire", KILLED_BY_AN); 1472 for(mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon) { 1473 if(DEADMONSTER(mtmp2)) continue; 1474 if(mtmp == mtmp2) continue; 1475 if(dist2(mtmp2->mx,mtmp2->my,mtmp->mx,mtmp->my) < 3){ 1476 if (resists_fire(mtmp2)) continue; 1477 mtmp2->mhp -= num; 1478 if (resists_cold(mtmp2)) 1479 mtmp2->mhp -= 3*num; 1480 if(mtmp2->mhp < 1) { 1481 mondied(mtmp2); 1482 break; 1483 } 1484 } 1485 } 1486 } 1487 return 2; 1488 } 1489#endif /* 0 */ 1490 case MUSE_POT_PARALYSIS: 1491 case MUSE_POT_BLINDNESS: 1492 case MUSE_POT_CONFUSION: 1493 case MUSE_POT_SLEEPING: 1494 case MUSE_POT_ACID: 1495 /* Note: this setting of dknown doesn't suffice. A monster 1496 * which is out of sight might throw and it hits something _in_ 1497 * sight, a problem not existing with wands because wand rays 1498 * are not objects. Also set dknown in mthrowu.c. 1499 */ 1500 if (cansee(mtmp->mx, mtmp->my)) { 1501 otmp->dknown = 1; 1502 pline("%s hurls %s!", Monnam(mtmp), 1503 singular(otmp, doname)); 1504 } 1505 m_throw(mtmp, mtmp->mx, mtmp->my, sgn(mtmp->mux-mtmp->mx), 1506 sgn(mtmp->muy-mtmp->my), 1507 distmin(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy), otmp); 1508 return 2; 1509 case 0: return 0; /* i.e. an exploded wand */ 1510 default: impossible("%s wanted to perform action %d?", Monnam(mtmp), 1511 m.has_offense); 1512 break; 1513 } 1514 return 0; 1515} 1516 1517int 1518rnd_offensive_item(mtmp) 1519struct monst *mtmp; 1520{ 1521 struct permonst *pm = mtmp->data; 1522 int difficulty = monstr[(monsndx(pm))]; 1523 1524 if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data) 1525 || pm->mlet == S_GHOST 1526# ifdef KOPS 1527 || pm->mlet == S_KOP 1528# endif 1529 ) return 0; 1530 if (difficulty > 7 && !rn2(35)) return WAN_DEATH; 1531 switch (rn2(9 - (difficulty < 4) + 4 * (difficulty > 6))) { 1532 case 0: { 1533 struct obj *helmet = which_armor(mtmp, W_ARMH); 1534 1535 if ((helmet && is_metallic(helmet)) || amorphous(pm) || passes_walls(pm) || noncorporeal(pm) || unsolid(pm)) 1536 return SCR_EARTH; 1537 } /* fall through */ 1538 case 1: return WAN_STRIKING; 1539 case 2: return POT_ACID; 1540 case 3: return POT_CONFUSION; 1541 case 4: return POT_BLINDNESS; 1542 case 5: return POT_SLEEPING; 1543 case 6: return POT_PARALYSIS; 1544 case 7: case 8: 1545 return WAN_MAGIC_MISSILE; 1546 case 9: return WAN_SLEEP; 1547 case 10: return WAN_FIRE; 1548 case 11: return WAN_COLD; 1549 case 12: return WAN_LIGHTNING; 1550 } 1551 /*NOTREACHED*/ 1552 return 0; 1553} 1554 1555#define MUSE_POT_GAIN_LEVEL 1 1556#define MUSE_WAN_MAKE_INVISIBLE 2 1557#define MUSE_POT_INVISIBILITY 3 1558#define MUSE_POLY_TRAP 4 1559#define MUSE_WAN_POLYMORPH 5 1560#define MUSE_POT_SPEED 6 1561#define MUSE_WAN_SPEED_MONSTER 7 1562#define MUSE_BULLWHIP 8 1563#define MUSE_POT_POLYMORPH 9 1564 1565boolean 1566find_misc(mtmp) 1567struct monst *mtmp; 1568{ 1569 register struct obj *obj; 1570 struct permonst *mdat = mtmp->data; 1571 int x = mtmp->mx, y = mtmp->my; 1572 struct trap *t; 1573 int xx, yy; 1574 boolean immobile = (mdat->mmove == 0); 1575 boolean stuck = (mtmp == u.ustuck); 1576 1577 m.misc = (struct obj *)0; 1578 m.has_misc = 0; 1579 if (is_animal(mdat) || mindless(mdat)) 1580 return 0; 1581 if (u.uswallow && stuck) return FALSE; 1582 1583 /* We arbitrarily limit to times when a player is nearby for the 1584 * same reason as Junior Pac-Man doesn't have energizers eaten until 1585 * you can see them... 1586 */ 1587 if(dist2(x, y, mtmp->mux, mtmp->muy) > 36) 1588 return FALSE; 1589 1590 if (!stuck && !immobile && !mtmp->cham && monstr[monsndx(mdat)] < 6) { 1591 boolean ignore_boulders = (verysmall(mdat) || 1592 throws_rocks(mdat) || 1593 passes_walls(mdat)); 1594 for(xx = x-1; xx <= x+1; xx++) 1595 for(yy = y-1; yy <= y+1; yy++) 1596 if (isok(xx,yy) && (xx != u.ux || yy != u.uy)) 1597 if (mdat != &mons[PM_GRID_BUG] || xx == x || yy == y) 1598 if (/* (xx==x && yy==y) || */ !level.monsters[xx][yy]) 1599 if ((t = t_at(xx, yy)) != 0 && 1600 (ignore_boulders || !sobj_at(BOULDER, xx, yy)) 1601 && !onscary(xx, yy, mtmp)) { 1602 if (t->ttyp == POLY_TRAP) { 1603 trapx = xx; 1604 trapy = yy; 1605 m.has_misc = MUSE_POLY_TRAP; 1606 return TRUE; 1607 } 1608 } 1609 } 1610 if (nohands(mdat)) 1611 return 0; 1612 1613#define nomore(x) if(m.has_misc==x) continue; 1614 for(obj=mtmp->minvent; obj; obj=obj->nobj) { 1615 /* Monsters shouldn't recognize cursed items; this kludge is */ 1616 /* necessary to prevent serious problems though... */ 1617 if(obj->otyp == POT_GAIN_LEVEL && (!obj->cursed || 1618 (!mtmp->isgd && !mtmp->isshk && !mtmp->ispriest))) { 1619 m.misc = obj; 1620 m.has_misc = MUSE_POT_GAIN_LEVEL; 1621 } 1622 nomore(MUSE_BULLWHIP); 1623 if(obj->otyp == BULLWHIP && (MON_WEP(mtmp) == obj) && 1624 distu(mtmp->mx,mtmp->my)==1 && uwep && !mtmp->mpeaceful) { 1625 m.misc = obj; 1626 m.has_misc = MUSE_BULLWHIP; 1627 } 1628 /* Note: peaceful/tame monsters won't make themselves 1629 * invisible unless you can see them. Not really right, but... 1630 */ 1631 nomore(MUSE_WAN_MAKE_INVISIBLE); 1632 if(obj->otyp == WAN_MAKE_INVISIBLE && obj->spe > 0 && 1633 !mtmp->minvis && !mtmp->invis_blkd && 1634 (!mtmp->mpeaceful || See_invisible) && 1635 (!attacktype(mtmp->data, AT_GAZE) || mtmp->mcan)) { 1636 m.misc = obj; 1637 m.has_misc = MUSE_WAN_MAKE_INVISIBLE; 1638 } 1639 nomore(MUSE_POT_INVISIBILITY); 1640 if(obj->otyp == POT_INVISIBILITY && 1641 !mtmp->minvis && !mtmp->invis_blkd && 1642 (!mtmp->mpeaceful || See_invisible) && 1643 (!attacktype(mtmp->data, AT_GAZE) || mtmp->mcan)) { 1644 m.misc = obj; 1645 m.has_misc = MUSE_POT_INVISIBILITY; 1646 } 1647 nomore(MUSE_WAN_SPEED_MONSTER); 1648 if(obj->otyp == WAN_SPEED_MONSTER && obj->spe > 0 1649 && mtmp->mspeed != MFAST && !mtmp->isgd) { 1650 m.misc = obj; 1651 m.has_misc = MUSE_WAN_SPEED_MONSTER; 1652 } 1653 nomore(MUSE_POT_SPEED); 1654 if(obj->otyp == POT_SPEED && mtmp->mspeed != MFAST 1655 && !mtmp->isgd) { 1656 m.misc = obj; 1657 m.has_misc = MUSE_POT_SPEED; 1658 } 1659 nomore(MUSE_WAN_POLYMORPH); 1660 if(obj->otyp == WAN_POLYMORPH && obj->spe > 0 && !mtmp->cham 1661 && monstr[monsndx(mdat)] < 6) { 1662 m.misc = obj; 1663 m.has_misc = MUSE_WAN_POLYMORPH; 1664 } 1665 nomore(MUSE_POT_POLYMORPH); 1666 if(obj->otyp == POT_POLYMORPH && !mtmp->cham 1667 && monstr[monsndx(mdat)] < 6) { 1668 m.misc = obj; 1669 m.has_misc = MUSE_POT_POLYMORPH; 1670 } 1671 } 1672 return((boolean)(!!m.has_misc)); 1673#undef nomore 1674} 1675 1676/* type of monster to polymorph into; defaults to one suitable for the 1677 current level rather than the totally arbitrary choice of newcham() */ 1678static struct permonst * 1679muse_newcham_mon(mon) 1680struct monst *mon; 1681{ 1682 struct obj *m_armr; 1683 1684 if ((m_armr = which_armor(mon, W_ARM)) != 0) { 1685 if (Is_dragon_scales(m_armr)) 1686 return Dragon_scales_to_pm(m_armr); 1687 else if (Is_dragon_mail(m_armr)) 1688 return Dragon_mail_to_pm(m_armr); 1689 } 1690 return rndmonst(); 1691} 1692 1693int 1694use_misc(mtmp) 1695struct monst *mtmp; 1696{ 1697 int i; 1698 struct obj *otmp = m.misc; 1699 boolean vis, vismon, oseen; 1700 char nambuf[BUFSZ]; 1701 1702 if ((i = precheck(mtmp, otmp)) != 0) return i; 1703 vis = cansee(mtmp->mx, mtmp->my); 1704 vismon = canseemon(mtmp); 1705 oseen = otmp && vismon; 1706 1707 switch(m.has_misc) { 1708 case MUSE_POT_GAIN_LEVEL: 1709 mquaffmsg(mtmp, otmp); 1710 if (otmp->cursed) { 1711 if (Can_rise_up(mtmp->mx, mtmp->my, &u.uz)) { 1712 register int tolev = depth(&u.uz)-1; 1713 d_level tolevel; 1714 1715 get_level(&tolevel, tolev); 1716 /* insurance against future changes... */ 1717 if(on_level(&tolevel, &u.uz)) goto skipmsg; 1718 if (vismon) { 1719 pline("%s rises up, through the %s!", 1720 Monnam(mtmp), ceiling(mtmp->mx, mtmp->my)); 1721 if(!objects[POT_GAIN_LEVEL].oc_name_known 1722 && !objects[POT_GAIN_LEVEL].oc_uname) 1723 docall(otmp); 1724 } 1725 m_useup(mtmp, otmp); 1726 migrate_to_level(mtmp, ledger_no(&tolevel), 1727 MIGR_RANDOM, (coord *)0); 1728 return 2; 1729 } else { 1730skipmsg: 1731 if (vismon) { 1732 pline("%s looks uneasy.", Monnam(mtmp)); 1733 if(!objects[POT_GAIN_LEVEL].oc_name_known 1734 && !objects[POT_GAIN_LEVEL].oc_uname) 1735 docall(otmp); 1736 } 1737 m_useup(mtmp, otmp); 1738 return 2; 1739 } 1740 } 1741 if (vismon) pline("%s seems more experienced.", Monnam(mtmp)); 1742 if (oseen) makeknown(POT_GAIN_LEVEL); 1743 m_useup(mtmp, otmp); 1744 if (!grow_up(mtmp,(struct monst *)0)) return 1; 1745 /* grew into genocided monster */ 1746 return 2; 1747 case MUSE_WAN_MAKE_INVISIBLE: 1748 case MUSE_POT_INVISIBILITY: 1749 if (otmp->otyp == WAN_MAKE_INVISIBLE) { 1750 mzapmsg(mtmp, otmp, TRUE); 1751 otmp->spe--; 1752 } else 1753 mquaffmsg(mtmp, otmp); 1754 /* format monster's name before altering its visibility */ 1755 Strcpy(nambuf, See_invisible ? Monnam(mtmp) : mon_nam(mtmp)); 1756 mon_set_minvis(mtmp); 1757 if (vismon && mtmp->minvis) { /* was seen, now invisible */ 1758 if (See_invisible) 1759 pline("%s body takes on a %s transparency.", 1760 s_suffix(nambuf), 1761 Hallucination ? "normal" : "strange"); 1762 else 1763 pline("Suddenly you cannot see %s.", nambuf); 1764 if (oseen) makeknown(otmp->otyp); 1765 } 1766 if (otmp->otyp == POT_INVISIBILITY) { 1767 if (otmp->cursed) you_aggravate(mtmp); 1768 m_useup(mtmp, otmp); 1769 } 1770 return 2; 1771 case MUSE_WAN_SPEED_MONSTER: 1772 mzapmsg(mtmp, otmp, TRUE); 1773 otmp->spe--; 1774 mon_adjust_speed(mtmp, 1, otmp); 1775 return 2; 1776 case MUSE_POT_SPEED: 1777 mquaffmsg(mtmp, otmp); 1778 /* note difference in potion effect due to substantially 1779 different methods of maintaining speed ratings: 1780 player's character becomes "very fast" temporarily; 1781 monster becomes "one stage faster" permanently */ 1782 mon_adjust_speed(mtmp, 1, otmp); 1783 m_useup(mtmp, otmp); 1784 return 2; 1785 case MUSE_WAN_POLYMORPH: 1786 mzapmsg(mtmp, otmp, TRUE); 1787 otmp->spe--; 1788 (void) newcham(mtmp, muse_newcham_mon(mtmp), TRUE, FALSE); 1789 if (oseen) makeknown(WAN_POLYMORPH); 1790 return 2; 1791 case MUSE_POT_POLYMORPH: 1792 mquaffmsg(mtmp, otmp); 1793 if (vismon) pline("%s suddenly mutates!", Monnam(mtmp)); 1794 (void) newcham(mtmp, muse_newcham_mon(mtmp), FALSE, FALSE); 1795 if (oseen) makeknown(POT_POLYMORPH); 1796 m_useup(mtmp, otmp); 1797 return 2; 1798 case MUSE_POLY_TRAP: 1799 if (vismon) 1800 pline("%s deliberately %s onto a polymorph trap!", 1801 Monnam(mtmp), 1802 makeplural(locomotion(mtmp->data, "jump"))); 1803 if (vis) seetrap(t_at(trapx,trapy)); 1804 1805 /* don't use rloc() due to worms */ 1806 remove_monster(mtmp->mx, mtmp->my); 1807 newsym(mtmp->mx, mtmp->my); 1808 place_monster(mtmp, trapx, trapy); 1809 if (mtmp->wormno) worm_move(mtmp); 1810 newsym(trapx, trapy); 1811 1812 (void) newcham(mtmp, (struct permonst *)0, FALSE, FALSE); 1813 return 2; 1814 case MUSE_BULLWHIP: 1815 /* attempt to disarm hero */ 1816 if (uwep && !rn2(5)) { 1817 const char *The_whip = vismon ? "The bullwhip" : "A whip"; 1818 int where_to = rn2(4); 1819 struct obj *obj = uwep; 1820 const char *hand; 1821 char the_weapon[BUFSZ]; 1822 1823 Strcpy(the_weapon, the(xname(obj))); 1824 hand = body_part(HAND); 1825 if (bimanual(obj)) hand = makeplural(hand); 1826 1827 if (vismon) 1828 pline("%s flicks a bullwhip towards your %s!", 1829 Monnam(mtmp), hand); 1830 if (obj->otyp == HEAVY_IRON_BALL) { 1831 pline("%s fails to wrap around %s.", 1832 The_whip, the_weapon); 1833 return 1; 1834 } 1835 pline("%s wraps around %s you're wielding!", 1836 The_whip, the_weapon); 1837 if (welded(obj)) { 1838 pline("%s welded to your %s%c", 1839 !is_plural(obj) ? "It is" : "They are", 1840 hand, !obj->bknown ? '!' : '.'); 1841 /* obj->bknown = 1; */ /* welded() takes care of this */ 1842 where_to = 0; 1843 } 1844 if (!where_to) { 1845 pline_The("whip slips free."); /* not `The_whip' */ 1846 return 1; 1847 } else if (where_to == 3 && hates_silver(mtmp->data) && 1848 objects[obj->otyp].oc_material == SILVER) { 1849 /* this monster won't want to catch a silver 1850 weapon; drop it at hero's feet instead */ 1851 where_to = 2; 1852 } 1853 freeinv(obj); 1854 uwepgone(); 1855 switch (where_to) { 1856 case 1: /* onto floor beneath mon */ 1857 pline("%s yanks %s from your %s!", Monnam(mtmp), 1858 the_weapon, hand); 1859 place_object(obj, mtmp->mx, mtmp->my); 1860 break; 1861 case 2: /* onto floor beneath you */ 1862 pline("%s yanks %s to the %s!", Monnam(mtmp), 1863 the_weapon, surface(u.ux, u.uy)); 1864 dropy(obj); 1865 break; 1866 case 3: /* into mon's inventory */ 1867 pline("%s snatches %s!", Monnam(mtmp), 1868 the_weapon); 1869 (void) mpickobj(mtmp,obj); 1870 break; 1871 } 1872 return 1; 1873 } 1874 return 0; 1875 case 0: return 0; /* i.e. an exploded wand */ 1876 default: impossible("%s wanted to perform action %d?", Monnam(mtmp), 1877 m.has_misc); 1878 break; 1879 } 1880 return 0; 1881} 1882 1883STATIC_OVL void 1884you_aggravate(mtmp) 1885struct monst *mtmp; 1886{ 1887 pline("For some reason, %s presence is known to you.", 1888 s_suffix(noit_mon_nam(mtmp))); 1889 cls(); 1890#ifdef CLIPPING 1891 cliparound(mtmp->mx, mtmp->my); 1892#endif 1893 show_glyph(mtmp->mx, mtmp->my, mon_to_glyph(mtmp)); 1894 display_self(); 1895 You_feel("aggravated at %s.", noit_mon_nam(mtmp)); 1896 display_nhwindow(WIN_MAP, TRUE); 1897 docrt(); 1898 if (unconscious()) { 1899 multi = -1; 1900 nomovemsg = 1901 "Aggravated, you are jolted into full consciousness."; 1902 } 1903 newsym(mtmp->mx,mtmp->my); 1904 if (!canspotmon(mtmp)) 1905 map_invisible(mtmp->mx, mtmp->my); 1906} 1907 1908int 1909rnd_misc_item(mtmp) 1910struct monst *mtmp; 1911{ 1912 struct permonst *pm = mtmp->data; 1913 int difficulty = monstr[(monsndx(pm))]; 1914 1915 if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data) 1916 || pm->mlet == S_GHOST 1917# ifdef KOPS 1918 || pm->mlet == S_KOP 1919# endif 1920 ) return 0; 1921 /* Unlike other rnd_item functions, we only allow _weak_ monsters 1922 * to have this item; after all, the item will be used to strengthen 1923 * the monster and strong monsters won't use it at all... 1924 */ 1925 if (difficulty < 6 && !rn2(30)) 1926 return rn2(6) ? POT_POLYMORPH : WAN_POLYMORPH; 1927 1928 if (!rn2(40) && !nonliving(pm)) return AMULET_OF_LIFE_SAVING; 1929 1930 switch (rn2(3)) { 1931 case 0: 1932 if (mtmp->isgd) return 0; 1933 return rn2(6) ? POT_SPEED : WAN_SPEED_MONSTER; 1934 case 1: 1935 if (mtmp->mpeaceful && !See_invisible) return 0; 1936 return rn2(6) ? POT_INVISIBILITY : WAN_MAKE_INVISIBLE; 1937 case 2: 1938 return POT_GAIN_LEVEL; 1939 } 1940 /*NOTREACHED*/ 1941 return 0; 1942} 1943 1944boolean 1945searches_for_item(mon, obj) 1946struct monst *mon; 1947struct obj *obj; 1948{ 1949 int typ = obj->otyp; 1950 1951 if (is_animal(mon->data) || 1952 mindless(mon->data) || 1953 mon->data == &mons[PM_GHOST]) /* don't loot bones piles */ 1954 return FALSE; 1955 1956 if (typ == WAN_MAKE_INVISIBLE || typ == POT_INVISIBILITY) 1957 return (boolean)(!mon->minvis && !mon->invis_blkd && !attacktype(mon->data, AT_GAZE)); 1958 if (typ == WAN_SPEED_MONSTER || typ == POT_SPEED) 1959 return (boolean)(mon->mspeed != MFAST); 1960 1961 switch (obj->oclass) { 1962 case WAND_CLASS: 1963 if (obj->spe <= 0) 1964 return FALSE; 1965 if (typ == WAN_DIGGING) 1966 return (boolean)(!is_floater(mon->data)); 1967 if (typ == WAN_POLYMORPH) 1968 return (boolean)(monstr[monsndx(mon->data)] < 6); 1969 if (objects[typ].oc_dir == RAY || 1970 typ == WAN_STRIKING || 1971 typ == WAN_TELEPORTATION || 1972 typ == WAN_CREATE_MONSTER) 1973 return TRUE; 1974 break; 1975 case POTION_CLASS: 1976 if (typ == POT_HEALING || 1977 typ == POT_EXTRA_HEALING || 1978 typ == POT_FULL_HEALING || 1979 typ == POT_POLYMORPH || 1980 typ == POT_GAIN_LEVEL || 1981 typ == POT_PARALYSIS || 1982 typ == POT_SLEEPING || 1983 typ == POT_ACID || 1984 typ == POT_CONFUSION) 1985 return TRUE; 1986 if (typ == POT_BLINDNESS && !attacktype(mon->data, AT_GAZE)) 1987 return TRUE; 1988 break; 1989 case SCROLL_CLASS: 1990 if (typ == SCR_TELEPORTATION || typ == SCR_CREATE_MONSTER 1991 || typ == SCR_EARTH) 1992 return TRUE; 1993 break; 1994 case AMULET_CLASS: 1995 if (typ == AMULET_OF_LIFE_SAVING) 1996 return (boolean)(!nonliving(mon->data)); 1997 if (typ == AMULET_OF_REFLECTION) 1998 return TRUE; 1999 break; 2000 case TOOL_CLASS: 2001 if (typ == PICK_AXE) 2002 return (boolean)needspick(mon->data); 2003 if (typ == UNICORN_HORN) 2004 return (boolean)(!obj->cursed && !is_unicorn(mon->data)); 2005 if (typ == FROST_HORN || typ == FIRE_HORN) 2006 return (obj->spe > 0); 2007 break; 2008 case FOOD_CLASS: 2009 if (typ == CORPSE) 2010 return (boolean)(((mon->misc_worn_check & W_ARMG) && 2011 touch_petrifies(&mons[obj->corpsenm])) || 2012 (!resists_ston(mon) && 2013 (obj->corpsenm == PM_LIZARD || 2014 (acidic(&mons[obj->corpsenm]) && 2015 obj->corpsenm != PM_GREEN_SLIME)))); 2016 if (typ == EGG) 2017 return (boolean)(touch_petrifies(&mons[obj->corpsenm])); 2018 break; 2019 default: 2020 break; 2021 } 2022 2023 return FALSE; 2024} 2025 2026boolean 2027mon_reflects(mon,str) 2028struct monst *mon; 2029const char *str; 2030{ 2031 struct obj *orefl = which_armor(mon, W_ARMS); 2032 2033 if (orefl && orefl->otyp == SHIELD_OF_REFLECTION) { 2034 if (str) { 2035 pline(str, s_suffix(mon_nam(mon)), "shield"); 2036 makeknown(SHIELD_OF_REFLECTION); 2037 } 2038 return TRUE; 2039 } else if (arti_reflects(MON_WEP(mon))) { 2040 /* due to wielded artifact weapon */ 2041 if (str) 2042 pline(str, s_suffix(mon_nam(mon)), "weapon"); 2043 return TRUE; 2044 } else if ((orefl = which_armor(mon, W_AMUL)) && 2045 orefl->otyp == AMULET_OF_REFLECTION) { 2046 if (str) { 2047 pline(str, s_suffix(mon_nam(mon)), "amulet"); 2048 makeknown(AMULET_OF_REFLECTION); 2049 } 2050 return TRUE; 2051 } else if ((orefl = which_armor(mon, W_ARM)) && 2052 (orefl->otyp == SILVER_DRAGON_SCALES || orefl->otyp == SILVER_DRAGON_SCALE_MAIL)) { 2053 if (str) 2054 pline(str, s_suffix(mon_nam(mon)), "armor"); 2055 return TRUE; 2056 } else if (mon->data == &mons[PM_SILVER_DRAGON] || 2057 mon->data == &mons[PM_CHROMATIC_DRAGON]) { 2058 /* Silver dragons only reflect when mature; babies do not */ 2059 if (str) 2060 pline(str, s_suffix(mon_nam(mon)), "scales"); 2061 return TRUE; 2062 } 2063 return FALSE; 2064} 2065 2066boolean 2067ureflects (fmt, str) 2068const char *fmt, *str; 2069{ 2070 /* Check from outermost to innermost objects */ 2071 if (EReflecting & W_ARMS) { 2072 if (fmt && str) { 2073 pline(fmt, str, "shield"); 2074 makeknown(SHIELD_OF_REFLECTION); 2075 } 2076 return TRUE; 2077 } else if (EReflecting & W_WEP) { 2078 /* Due to wielded artifact weapon */ 2079 if (fmt && str) 2080 pline(fmt, str, "weapon"); 2081 return TRUE; 2082 } else if (EReflecting & W_AMUL) { 2083 if (fmt && str) { 2084 pline(fmt, str, "medallion"); 2085 makeknown(AMULET_OF_REFLECTION); 2086 } 2087 return TRUE; 2088 } else if (EReflecting & W_ARM) { 2089 if (fmt && str) 2090 pline(fmt, str, "armor"); 2091 return TRUE; 2092 } else if (youmonst.data == &mons[PM_SILVER_DRAGON]) { 2093 if (fmt && str) 2094 pline(fmt, str, "scales"); 2095 return TRUE; 2096 } 2097 return FALSE; 2098} 2099 2100 2101/* TRUE if the monster ate something */ 2102boolean 2103munstone(mon, by_you) 2104struct monst *mon; 2105boolean by_you; 2106{ 2107 struct obj *obj; 2108 2109 if (resists_ston(mon)) return FALSE; 2110 if (mon->meating || !mon->mcanmove || mon->msleeping) return FALSE; 2111 2112 for(obj = mon->minvent; obj; obj = obj->nobj) { 2113 /* Monsters can also use potions of acid */ 2114 if ((obj->otyp == POT_ACID) || (obj->otyp == CORPSE && 2115 (obj->corpsenm == PM_LIZARD || (acidic(&mons[obj->corpsenm]) && obj->corpsenm != PM_GREEN_SLIME)))) { 2116 mon_consume_unstone(mon, obj, by_you, TRUE); 2117 return TRUE; 2118 } 2119 } 2120 return FALSE; 2121} 2122 2123STATIC_OVL void 2124mon_consume_unstone(mon, obj, by_you, stoning) 2125struct monst *mon; 2126struct obj *obj; 2127boolean by_you; 2128boolean stoning; 2129{ 2130 int nutrit = (obj->otyp == CORPSE) ? dog_nutrition(mon, obj) : 0; 2131 /* also sets meating */ 2132 2133 /* give a "<mon> is slowing down" message and also remove 2134 intrinsic speed (comparable to similar effect on the hero) */ 2135 mon_adjust_speed(mon, -3, (struct obj *)0); 2136 2137 if (canseemon(mon)) { 2138 long save_quan = obj->quan; 2139 2140 obj->quan = 1L; 2141 pline("%s %ss %s.", Monnam(mon), 2142 (obj->otyp == POT_ACID) ? "quaff" : "eat", 2143 distant_name(obj,doname)); 2144 obj->quan = save_quan; 2145 } else if (flags.soundok) 2146 You_hear("%s.", (obj->otyp == POT_ACID) ? "drinking" : "chewing"); 2147 m_useup(mon, obj); 2148 if (((obj->otyp == POT_ACID) || acidic(&mons[obj->corpsenm])) && 2149 !resists_acid(mon)) { 2150 mon->mhp -= rnd(15); 2151 pline("%s has a very bad case of stomach acid.", 2152 Monnam(mon)); 2153 } 2154 if (mon->mhp <= 0) { 2155 pline("%s dies!", Monnam(mon)); 2156 if (by_you) xkilled(mon, 0); 2157 else mondead(mon); 2158 return; 2159 } 2160 if (stoning && canseemon(mon)) { 2161 if (Hallucination) 2162 pline("What a pity - %s just ruined a future piece of art!", 2163 mon_nam(mon)); 2164 else 2165 pline("%s seems limber!", Monnam(mon)); 2166 } 2167 if (obj->otyp == CORPSE && obj->corpsenm == PM_LIZARD && mon->mconf) { 2168 mon->mconf = 0; 2169 if (canseemon(mon)) 2170 pline("%s seems steadier now.", Monnam(mon)); 2171 } 2172 if (mon->mtame && !mon->isminion && nutrit > 0) { 2173 struct edog *edog = EDOG(mon); 2174 2175 if (edog->hungrytime < monstermoves) edog->hungrytime = monstermoves; 2176 edog->hungrytime += nutrit; 2177 mon->mconf = 0; 2178 } 2179 mon->mlstmv = monstermoves; /* it takes a turn */ 2180} 2181 2182/*muse.c*/ 2183