1290001Sglebius/* SCCS Id: @(#)wizard.c 3.4 2003/02/18 */ 2290001Sglebius/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3290001Sglebius/* NetHack may be freely redistributed. See license for details. */ 4290001Sglebius 5290001Sglebius/* wizard code - inspired by rogue code from Merlyn Leroy (digi-g!brian) */ 6290001Sglebius/* - heavily modified to give the wiz balls. (genat!mike) */ 7290001Sglebius/* - dewimped and given some maledictions. -3. */ 8290001Sglebius/* - generalized for 3.1 (mike@bullns.on01.bull.ca) */ 9290001Sglebius 10290001Sglebius#include "hack.h" 11290001Sglebius#include "qtext.h" 12290001Sglebius#include "epri.h" 13290001Sglebius 14290001Sglebiusextern const int monstr[]; 15290001Sglebius 16290001Sglebius#ifdef OVLB 17290001Sglebius 18290001SglebiusSTATIC_DCL short FDECL(which_arti, (int)); 19290001SglebiusSTATIC_DCL boolean FDECL(mon_has_arti, (struct monst *,SHORT_P)); 20290001SglebiusSTATIC_DCL struct monst *FDECL(other_mon_has_arti, (struct monst *,SHORT_P)); 21290001SglebiusSTATIC_DCL struct obj *FDECL(on_ground, (SHORT_P)); 22290001SglebiusSTATIC_DCL boolean FDECL(you_have, (int)); 23290001SglebiusSTATIC_DCL long FDECL(target_on, (int,struct monst *)); 24290001SglebiusSTATIC_DCL long FDECL(strategy, (struct monst *)); 25290001Sglebius 26290001Sglebiusstatic NEARDATA const int nasties[] = { 27290001Sglebius PM_COCKATRICE, PM_ETTIN, PM_STALKER, PM_MINOTAUR, PM_RED_DRAGON, 28290001Sglebius PM_BLACK_DRAGON, PM_GREEN_DRAGON, PM_OWLBEAR, PM_PURPLE_WORM, 29290001Sglebius PM_ROCK_TROLL, PM_XAN, PM_GREMLIN, PM_UMBER_HULK, PM_VAMPIRE_LORD, 30290001Sglebius PM_XORN, PM_ZRUTY, PM_ELF_LORD, PM_ELVENKING, PM_YELLOW_DRAGON, 31290001Sglebius PM_LEOCROTTA, PM_BALUCHITHERIUM, PM_CARNIVOROUS_APE, PM_FIRE_GIANT, 32290001Sglebius PM_COUATL, PM_CAPTAIN, PM_WINGED_GARGOYLE, PM_MASTER_MIND_FLAYER, 33290001Sglebius PM_FIRE_ELEMENTAL, PM_JABBERWOCK, PM_ARCH_LICH, PM_OGRE_KING, 34290001Sglebius PM_OLOG_HAI, PM_IRON_GOLEM, PM_OCHRE_JELLY, PM_GREEN_SLIME, 35290001Sglebius PM_DISENCHANTER 36290001Sglebius }; 37290001Sglebius 38290001Sglebiusstatic NEARDATA const unsigned wizapp[] = { 39290001Sglebius PM_HUMAN, PM_WATER_DEMON, PM_VAMPIRE, 40290001Sglebius PM_RED_DRAGON, PM_TROLL, PM_UMBER_HULK, 41290001Sglebius PM_XORN, PM_XAN, PM_COCKATRICE, 42290001Sglebius PM_FLOATING_EYE, 43290001Sglebius PM_GUARDIAN_NAGA, 44290001Sglebius PM_TRAPPER 45290001Sglebius}; 46290001Sglebius 47290001Sglebius#endif /* OVLB */ 48290001Sglebius#ifdef OVL0 49290001Sglebius 50290001Sglebius/* If you've found the Amulet, make the Wizard appear after some time */ 51290001Sglebius/* Also, give hints about portal locations, if amulet is worn/wielded -dlc */ 52290001Sglebiusvoid 53290001Sglebiusamulet() 54290001Sglebius{ 55290001Sglebius struct monst *mtmp; 56290001Sglebius struct trap *ttmp; 57290001Sglebius struct obj *amu; 58290001Sglebius 59290001Sglebius#if 0 /* caller takes care of this check */ 60290001Sglebius if (!u.uhave.amulet) 61290001Sglebius return; 62290001Sglebius#endif 63290001Sglebius if ((((amu = uamul) != 0 && amu->otyp == AMULET_OF_YENDOR) || 64290001Sglebius ((amu = uwep) != 0 && amu->otyp == AMULET_OF_YENDOR)) 65290001Sglebius && !rn2(15)) { 66290001Sglebius for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) { 67290001Sglebius if(ttmp->ttyp == MAGIC_PORTAL) { 68290001Sglebius int du = distu(ttmp->tx, ttmp->ty); 69290001Sglebius if (du <= 9) 70290001Sglebius pline("%s hot!", Tobjnam(amu, "feel")); 71290001Sglebius else if (du <= 64) 72290001Sglebius pline("%s very warm.", Tobjnam(amu, "feel")); 73290001Sglebius else if (du <= 144) 74290001Sglebius pline("%s warm.", Tobjnam(amu, "feel")); 75290001Sglebius /* else, the amulet feels normal */ 76290001Sglebius break; 77290001Sglebius } 78290001Sglebius } 79290001Sglebius } 80290001Sglebius 81290001Sglebius if (!flags.no_of_wizards) 82290001Sglebius return; 83290001Sglebius /* find Wizard, and wake him if necessary */ 84290001Sglebius for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 85290001Sglebius if (!DEADMONSTER(mtmp) && mtmp->iswiz && mtmp->msleeping && !rn2(40)) { 86290001Sglebius mtmp->msleeping = 0; 87290001Sglebius if (distu(mtmp->mx,mtmp->my) > 2) 88290001Sglebius You( 89290001Sglebius "get the creepy feeling that somebody noticed your taking the Amulet." 90290001Sglebius ); 91290001Sglebius return; 92290001Sglebius } 93290001Sglebius} 94290001Sglebius 95290001Sglebius#endif /* OVL0 */ 96290001Sglebius#ifdef OVLB 97290001Sglebius 98290001Sglebiusint 99290001Sglebiusmon_has_amulet(mtmp) 100290001Sglebiusregister struct monst *mtmp; 101290001Sglebius{ 102290001Sglebius register struct obj *otmp; 103290001Sglebius 104290001Sglebius for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj) 105290001Sglebius if(otmp->otyp == AMULET_OF_YENDOR) return(1); 106290001Sglebius return(0); 107290001Sglebius} 108290001Sglebius 109290001Sglebiusint 110290001Sglebiusmon_has_special(mtmp) 111290001Sglebiusregister struct monst *mtmp; 112290001Sglebius{ 113290001Sglebius register struct obj *otmp; 114290001Sglebius 115290001Sglebius for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj) 116290001Sglebius if(otmp->otyp == AMULET_OF_YENDOR || 117290001Sglebius is_quest_artifact(otmp) || 118290001Sglebius otmp->otyp == BELL_OF_OPENING || 119290001Sglebius otmp->otyp == CANDELABRUM_OF_INVOCATION || 120290001Sglebius otmp->otyp == SPE_BOOK_OF_THE_DEAD) return(1); 121290001Sglebius return(0); 122290001Sglebius} 123290001Sglebius 124290001Sglebius/* 125290001Sglebius * New for 3.1 Strategy / Tactics for the wiz, as well as other 126290001Sglebius * monsters that are "after" something (defined via mflag3). 127290001Sglebius * 128290001Sglebius * The strategy section decides *what* the monster is going 129290001Sglebius * to attempt, the tactics section implements the decision. 130290001Sglebius */ 131290001Sglebius#define STRAT(w, x, y, typ) (w | ((long)(x)<<16) | ((long)(y)<<8) | (long)typ) 132290001Sglebius 133290001Sglebius#define M_Wants(mask) (mtmp->data->mflags3 & (mask)) 134290001Sglebius 135290001SglebiusSTATIC_OVL short 136290001Sglebiuswhich_arti(mask) 137290001Sglebius register int mask; 138290001Sglebius{ 139290001Sglebius switch(mask) { 140290001Sglebius case M3_WANTSAMUL: return(AMULET_OF_YENDOR); 141290001Sglebius case M3_WANTSBELL: return(BELL_OF_OPENING); 142290001Sglebius case M3_WANTSCAND: return(CANDELABRUM_OF_INVOCATION); 143290001Sglebius case M3_WANTSBOOK: return(SPE_BOOK_OF_THE_DEAD); 144290001Sglebius default: break; /* 0 signifies quest artifact */ 145290001Sglebius } 146290001Sglebius return(0); 147290001Sglebius} 148290001Sglebius 149290001Sglebius/* 150290001Sglebius * If "otyp" is zero, it triggers a check for the quest_artifact, 151290001Sglebius * since bell, book, candle, and amulet are all objects, not really 152290001Sglebius * artifacts right now. [MRS] 153290001Sglebius */ 154290001SglebiusSTATIC_OVL boolean 155290001Sglebiusmon_has_arti(mtmp, otyp) 156290001Sglebius register struct monst *mtmp; 157290001Sglebius register short otyp; 158290001Sglebius{ 159290001Sglebius register struct obj *otmp; 160290001Sglebius 161290001Sglebius for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj) { 162290001Sglebius if(otyp) { 163290001Sglebius if(otmp->otyp == otyp) 164290001Sglebius return(1); 165290001Sglebius } 166290001Sglebius else if(is_quest_artifact(otmp)) return(1); 167290001Sglebius } 168290001Sglebius return(0); 169290001Sglebius 170290001Sglebius} 171290001Sglebius 172290001SglebiusSTATIC_OVL struct monst * 173290001Sglebiusother_mon_has_arti(mtmp, otyp) 174290001Sglebius register struct monst *mtmp; 175290001Sglebius register short otyp; 176290001Sglebius{ 177290001Sglebius register struct monst *mtmp2; 178290001Sglebius 179290001Sglebius for(mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon) 180290001Sglebius /* no need for !DEADMONSTER check here since they have no inventory */ 181290001Sglebius if(mtmp2 != mtmp) 182290001Sglebius if(mon_has_arti(mtmp2, otyp)) return(mtmp2); 183290001Sglebius 184290001Sglebius return((struct monst *)0); 185290001Sglebius} 186290001Sglebius 187290001SglebiusSTATIC_OVL struct obj * 188290001Sglebiuson_ground(otyp) 189290001Sglebius register short otyp; 190290001Sglebius{ 191290001Sglebius register struct obj *otmp; 192290001Sglebius 193290001Sglebius for (otmp = fobj; otmp; otmp = otmp->nobj) 194290001Sglebius if (otyp) { 195290001Sglebius if (otmp->otyp == otyp) 196290001Sglebius return(otmp); 197290001Sglebius } else if (is_quest_artifact(otmp)) 198290001Sglebius return(otmp); 199290001Sglebius return((struct obj *)0); 200290001Sglebius} 201290001Sglebius 202290001SglebiusSTATIC_OVL boolean 203290001Sglebiusyou_have(mask) 204290001Sglebius register int mask; 205290001Sglebius{ 206290001Sglebius switch(mask) { 207290001Sglebius case M3_WANTSAMUL: return(boolean)(u.uhave.amulet); 208290001Sglebius case M3_WANTSBELL: return(boolean)(u.uhave.bell); 209290001Sglebius case M3_WANTSCAND: return(boolean)(u.uhave.menorah); 210290001Sglebius case M3_WANTSBOOK: return(boolean)(u.uhave.book); 211290001Sglebius case M3_WANTSARTI: return(boolean)(u.uhave.questart); 212290001Sglebius default: break; 213290001Sglebius } 214290001Sglebius return(0); 215290001Sglebius} 216290001Sglebius 217290001SglebiusSTATIC_OVL long 218290001Sglebiustarget_on(mask, mtmp) 219290001Sglebius register int mask; 220 register struct monst *mtmp; 221{ 222 register short otyp; 223 register struct obj *otmp; 224 register struct monst *mtmp2; 225 226 if(!M_Wants(mask)) return(STRAT_NONE); 227 228 otyp = which_arti(mask); 229 if(!mon_has_arti(mtmp, otyp)) { 230 if(you_have(mask)) 231 return(STRAT(STRAT_PLAYER, u.ux, u.uy, mask)); 232 else if((otmp = on_ground(otyp))) 233 return(STRAT(STRAT_GROUND, otmp->ox, otmp->oy, mask)); 234 else if((mtmp2 = other_mon_has_arti(mtmp, otyp))) 235 return(STRAT(STRAT_MONSTR, mtmp2->mx, mtmp2->my, mask)); 236 } 237 return(STRAT_NONE); 238} 239 240STATIC_OVL long 241strategy(mtmp) 242 register struct monst *mtmp; 243{ 244 long strat, dstrat; 245 246 if (!is_covetous(mtmp->data) || 247 /* perhaps a shopkeeper has been polymorphed into a master 248 lich; we don't want it teleporting to the stairs to heal 249 because that will leave its shop untended */ 250 (mtmp->isshk && inhishop(mtmp))) 251 return STRAT_NONE; 252 253 switch((mtmp->mhp*3)/mtmp->mhpmax) { /* 0-3 */ 254 255 default: 256 case 0: /* panic time - mtmp is almost snuffed */ 257 return(STRAT_HEAL); 258 259 case 1: /* the wiz is less cautious */ 260 if(mtmp->data != &mons[PM_WIZARD_OF_YENDOR]) 261 return(STRAT_HEAL); 262 /* else fall through */ 263 264 case 2: dstrat = STRAT_HEAL; 265 break; 266 267 case 3: dstrat = STRAT_NONE; 268 break; 269 } 270 271 if(flags.made_amulet) 272 if((strat = target_on(M3_WANTSAMUL, mtmp)) != STRAT_NONE) 273 return(strat); 274 275 if(u.uevent.invoked) { /* priorities change once gate opened */ 276 277 if((strat = target_on(M3_WANTSARTI, mtmp)) != STRAT_NONE) 278 return(strat); 279 if((strat = target_on(M3_WANTSBOOK, mtmp)) != STRAT_NONE) 280 return(strat); 281 if((strat = target_on(M3_WANTSBELL, mtmp)) != STRAT_NONE) 282 return(strat); 283 if((strat = target_on(M3_WANTSCAND, mtmp)) != STRAT_NONE) 284 return(strat); 285 } else { 286 287 if((strat = target_on(M3_WANTSBOOK, mtmp)) != STRAT_NONE) 288 return(strat); 289 if((strat = target_on(M3_WANTSBELL, mtmp)) != STRAT_NONE) 290 return(strat); 291 if((strat = target_on(M3_WANTSCAND, mtmp)) != STRAT_NONE) 292 return(strat); 293 if((strat = target_on(M3_WANTSARTI, mtmp)) != STRAT_NONE) 294 return(strat); 295 } 296 return(dstrat); 297} 298 299int 300tactics(mtmp) 301 register struct monst *mtmp; 302{ 303 long strat = strategy(mtmp); 304 305 mtmp->mstrategy = (mtmp->mstrategy & STRAT_WAITMASK) | strat; 306 307 switch (strat) { 308 case STRAT_HEAL: /* hide and recover */ 309 /* if wounded, hole up on or near the stairs (to block them) */ 310 /* unless, of course, there are no stairs (e.g. endlevel) */ 311 mtmp->mavenge = 1; /* covetous monsters attack while fleeing */ 312 if (In_W_tower(mtmp->mx, mtmp->my, &u.uz) || 313 (mtmp->iswiz && !xupstair && !mon_has_amulet(mtmp))) { 314 if (!rn2(3 + mtmp->mhp/10)) (void) rloc(mtmp, FALSE); 315 } else if (xupstair && 316 (mtmp->mx != xupstair || mtmp->my != yupstair)) { 317 (void) mnearto(mtmp, xupstair, yupstair, TRUE); 318 } 319 /* if you're not around, cast healing spells */ 320 if (distu(mtmp->mx,mtmp->my) > (BOLT_LIM * BOLT_LIM)) 321 if(mtmp->mhp <= mtmp->mhpmax - 8) { 322 mtmp->mhp += rnd(8); 323 return(1); 324 } 325 /* fall through :-) */ 326 327 case STRAT_NONE: /* harrass */ 328 if (!rn2(!mtmp->mflee ? 5 : 33)) mnexto(mtmp); 329 return(0); 330 331 default: /* kill, maim, pillage! */ 332 { 333 long where = (strat & STRAT_STRATMASK); 334 xchar tx = STRAT_GOALX(strat), 335 ty = STRAT_GOALY(strat); 336 int targ = strat & STRAT_GOAL; 337 struct obj *otmp; 338 339 if(!targ) { /* simply wants you to close */ 340 return(0); 341 } 342 if((u.ux == tx && u.uy == ty) || where == STRAT_PLAYER) { 343 /* player is standing on it (or has it) */ 344 mnexto(mtmp); 345 return(0); 346 } 347 if(where == STRAT_GROUND) { 348 if(!MON_AT(tx, ty) || (mtmp->mx == tx && mtmp->my == ty)) { 349 /* teleport to it and pick it up */ 350 rloc_to(mtmp, tx, ty); /* clean old pos */ 351 352 if ((otmp = on_ground(which_arti(targ))) != 0) { 353 if (cansee(mtmp->mx, mtmp->my)) 354 pline("%s picks up %s.", 355 Monnam(mtmp), 356 (distu(mtmp->mx, mtmp->my) <= 5) ? 357 doname(otmp) : distant_name(otmp, doname)); 358 obj_extract_self(otmp); 359 (void) mpickobj(mtmp, otmp); 360 return(1); 361 } else return(0); 362 } else { 363 /* a monster is standing on it - cause some trouble */ 364 if (!rn2(5)) mnexto(mtmp); 365 return(0); 366 } 367 } else { /* a monster has it - 'port beside it. */ 368 (void) mnearto(mtmp, tx, ty, FALSE); 369 return(0); 370 } 371 } 372 } 373 /*NOTREACHED*/ 374 return(0); 375} 376 377void 378aggravate() 379{ 380 register struct monst *mtmp; 381 382 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 383 if (!DEADMONSTER(mtmp)) { 384 mtmp->msleeping = 0; 385 if(!mtmp->mcanmove && !rn2(5)) { 386 mtmp->mfrozen = 0; 387 mtmp->mcanmove = 1; 388 } 389 } 390} 391 392void 393clonewiz() 394{ 395 register struct monst *mtmp2; 396 397 if ((mtmp2 = makemon(&mons[PM_WIZARD_OF_YENDOR], 398 u.ux, u.uy, NO_MM_FLAGS)) != 0) { 399 mtmp2->msleeping = mtmp2->mtame = mtmp2->mpeaceful = 0; 400 if (!u.uhave.amulet && rn2(2)) { /* give clone a fake */ 401 (void) add_to_minv(mtmp2, mksobj(FAKE_AMULET_OF_YENDOR, 402 TRUE, FALSE)); 403 } 404 mtmp2->m_ap_type = M_AP_MONSTER; 405 mtmp2->mappearance = wizapp[rn2(SIZE(wizapp))]; 406 newsym(mtmp2->mx,mtmp2->my); 407 } 408} 409 410/* also used by newcham() */ 411int 412pick_nasty() 413{ 414 /* To do? Possibly should filter for appropriate forms when 415 in the elemental planes or surrounded by water or lava. */ 416 return nasties[rn2(SIZE(nasties))]; 417} 418 419/* create some nasty monsters, aligned or neutral with the caster */ 420/* a null caster defaults to a chaotic caster (e.g. the wizard) */ 421int 422nasty(mcast) 423 struct monst *mcast; 424{ 425 register struct monst *mtmp; 426 register int i, j, tmp; 427 int castalign = (mcast ? mcast->data->maligntyp : -1); 428 coord bypos; 429 int count=0; 430 431 if(!rn2(10) && Inhell) { 432 msummon((struct monst *) 0); /* summons like WoY */ 433 count++; 434 } else { 435 tmp = (u.ulevel > 3) ? u.ulevel/3 : 1; /* just in case -- rph */ 436 /* if we don't have a casting monster, the nasties appear around you */ 437 bypos.x = u.ux; 438 bypos.y = u.uy; 439 for(i = rnd(tmp); i > 0; --i) 440 for(j=0; j<20; j++) { 441 int makeindex; 442 443 /* Don't create more spellcasters of the monsters' level or 444 * higher--avoids chain summoners filling up the level. 445 */ 446 do { 447 makeindex = pick_nasty(); 448 } while(mcast && attacktype(&mons[makeindex], AT_MAGC) && 449 monstr[makeindex] >= monstr[mcast->mnum]); 450 /* do this after picking the monster to place */ 451 if (mcast && 452 !enexto(&bypos, mcast->mux, mcast->muy, &mons[makeindex])) 453 continue; 454 if ((mtmp = makemon(&mons[makeindex], 455 bypos.x, bypos.y, NO_MM_FLAGS)) != 0) { 456 mtmp->msleeping = mtmp->mpeaceful = mtmp->mtame = 0; 457 set_malign(mtmp); 458 } else /* GENOD? */ 459 mtmp = makemon((struct permonst *)0, 460 bypos.x, bypos.y, NO_MM_FLAGS); 461 if(mtmp && (mtmp->data->maligntyp == 0 || 462 sgn(mtmp->data->maligntyp) == sgn(castalign)) ) { 463 count++; 464 break; 465 } 466 } 467 } 468 return count; 469} 470 471/* Let's resurrect the wizard, for some unexpected fun. */ 472void 473resurrect() 474{ 475 struct monst *mtmp, **mmtmp; 476 long elapsed; 477 const char *verb; 478 479 if (!flags.no_of_wizards) { 480 /* make a new Wizard */ 481 verb = "kill"; 482 mtmp = makemon(&mons[PM_WIZARD_OF_YENDOR], u.ux, u.uy, MM_NOWAIT); 483 } else { 484 /* look for a migrating Wizard */ 485 verb = "elude"; 486 mmtmp = &migrating_mons; 487 while ((mtmp = *mmtmp) != 0) { 488 if (mtmp->iswiz && 489 /* if he has the Amulet, he won't bring it to you */ 490 !mon_has_amulet(mtmp) && 491 (elapsed = monstermoves - mtmp->mlstmv) > 0L) { 492 mon_catchup_elapsed_time(mtmp, elapsed); 493 if (elapsed >= LARGEST_INT) elapsed = LARGEST_INT - 1; 494 elapsed /= 50L; 495 if (mtmp->msleeping && rn2((int)elapsed + 1)) 496 mtmp->msleeping = 0; 497 if (mtmp->mfrozen == 1) /* would unfreeze on next move */ 498 mtmp->mfrozen = 0, mtmp->mcanmove = 1; 499 if (mtmp->mcanmove && !mtmp->msleeping) { 500 *mmtmp = mtmp->nmon; 501 mon_arrive(mtmp, TRUE); 502 /* note: there might be a second Wizard; if so, 503 he'll have to wait til the next resurrection */ 504 break; 505 } 506 } 507 mmtmp = &mtmp->nmon; 508 } 509 } 510 511 if (mtmp) { 512 mtmp->msleeping = mtmp->mtame = mtmp->mpeaceful = 0; 513 set_malign(mtmp); 514 pline("A voice booms out..."); 515 verbalize("So thou thought thou couldst %s me, fool.", verb); 516 } 517 518} 519 520/* Here, we make trouble for the poor shmuck who actually */ 521/* managed to do in the Wizard. */ 522void 523intervene() 524{ 525 int which = Is_astralevel(&u.uz) ? rnd(4) : rn2(6); 526 /* cases 0 and 5 don't apply on the Astral level */ 527 switch (which) { 528 case 0: 529 case 1: You_feel("vaguely nervous."); 530 break; 531 case 2: if (!Blind) 532 You("notice a %s glow surrounding you.", 533 hcolor(NH_BLACK)); 534 rndcurse(); 535 break; 536 case 3: aggravate(); 537 break; 538 case 4: (void)nasty((struct monst *)0); 539 break; 540 case 5: resurrect(); 541 break; 542 } 543} 544 545void 546wizdead() 547{ 548 flags.no_of_wizards--; 549 if (!u.uevent.udemigod) { 550 u.uevent.udemigod = TRUE; 551 u.udg_cnt = rn1(250, 50); 552 } 553} 554 555const char * const random_insult[] = { 556 "antic", 557 "blackguard", 558 "caitiff", 559 "chucklehead", 560 "coistrel", 561 "craven", 562 "cretin", 563 "cur", 564 "dastard", 565 "demon fodder", 566 "dimwit", 567 "dolt", 568 "fool", 569 "footpad", 570 "imbecile", 571 "knave", 572 "maledict", 573 "miscreant", 574 "niddering", 575 "poltroon", 576 "rattlepate", 577 "reprobate", 578 "scapegrace", 579 "varlet", 580 "villein", /* (sic.) */ 581 "wittol", 582 "worm", 583 "wretch", 584}; 585 586const char * const random_malediction[] = { 587 "Hell shall soon claim thy remains,", 588 "I chortle at thee, thou pathetic", 589 "Prepare to die, thou", 590 "Resistance is useless,", 591 "Surrender or die, thou", 592 "There shall be no mercy, thou", 593 "Thou shalt repent of thy cunning,", 594 "Thou art as a flea to me,", 595 "Thou art doomed,", 596 "Thy fate is sealed,", 597 "Verily, thou shalt be one dead" 598}; 599 600/* Insult or intimidate the player */ 601void 602cuss(mtmp) 603register struct monst *mtmp; 604{ 605 if (mtmp->iswiz) { 606 if (!rn2(5)) /* typical bad guy action */ 607 pline("%s laughs fiendishly.", Monnam(mtmp)); 608 else 609 if (u.uhave.amulet && !rn2(SIZE(random_insult))) 610 verbalize("Relinquish the amulet, %s!", 611 random_insult[rn2(SIZE(random_insult))]); 612 else if (u.uhp < 5 && !rn2(2)) /* Panic */ 613 verbalize(rn2(2) ? 614 "Even now thy life force ebbs, %s!" : 615 "Savor thy breath, %s, it be thy last!", 616 random_insult[rn2(SIZE(random_insult))]); 617 else if (mtmp->mhp < 5 && !rn2(2)) /* Parthian shot */ 618 verbalize(rn2(2) ? 619 "I shall return." : 620 "I'll be back."); 621 else 622 verbalize("%s %s!", 623 random_malediction[rn2(SIZE(random_malediction))], 624 random_insult[rn2(SIZE(random_insult))]); 625 } else if(is_lminion(mtmp)) { 626 com_pager(rn2(QTN_ANGELIC - 1 + (Hallucination ? 1 : 0)) + 627 QT_ANGELIC); 628 } else { 629 if (!rn2(5)) 630 pline("%s casts aspersions on your ancestry.", Monnam(mtmp)); 631 else 632 com_pager(rn2(QTN_DEMONIC) + QT_DEMONIC); 633 } 634} 635 636#endif /* OVLB */ 637 638/*wizard.c*/ 639