/* Charm monsters in range. Note that they may resist the spell. If swallowed, range is reduced to 0. */ static void charm_monsters(int distance) { struct monst *mtmp, *mtmp2; if (Engulfed) { if (!resist(&youmonst, u.ustuck, TOOL_CLASS, NOTELL, 0)) tamedog(u.ustuck, NULL); } else { for (mtmp = level->monlist; mtmp; mtmp = mtmp2) { mtmp2 = mtmp->nmon; if (DEADMONSTER(mtmp)) continue; if (distu(mtmp->mx, mtmp->my) <= distance) { if (!resist(&youmonst, mtmp, TOOL_CLASS, NOTELL, 0)) tamedog(mtmp, NULL); } } } }
/* were-creature (even you) summons a horde */ int were_summon(const struct permonst *ptr, boolean yours, int *visible, /* number of visible helpers created */ char *genbuf) { int i, typ, pm = monsndx(ptr); struct monst *mtmp; int total = 0; *visible = 0; if (Protection_from_shape_changers && !yours) return 0; for (i = rnd(5); i > 0; i--) { switch(pm) { case PM_WERERAT: case PM_HUMAN_WERERAT: typ = rn2(3) ? PM_SEWER_RAT : rn2(3) ? PM_GIANT_RAT : PM_RABID_RAT ; if (genbuf) strcpy(genbuf, "rat"); break; case PM_WEREJACKAL: case PM_HUMAN_WEREJACKAL: typ = PM_JACKAL; if (genbuf) strcpy(genbuf, "jackal"); break; case PM_WEREWOLF: case PM_HUMAN_WEREWOLF: typ = rn2(5) ? PM_WOLF : PM_WINTER_WOLF ; if (genbuf) strcpy(genbuf, "wolf"); break; default: continue; } mtmp = makemon(&mons[typ], level, u.ux, u.uy, NO_MM_FLAGS); if (mtmp) { total++; if (canseemon(mtmp)) *visible += 1; } if (yours && mtmp) tamedog(mtmp, NULL); } return total; }
static int dochat(void) { struct monst *mtmp; int tx, ty; struct obj *otmp; schar dx, dy, dz; int mdx, mdy, mon_count; if (is_silent(youmonst.data)) { pline("As %s, you cannot speak.", an(mons_mname(youmonst.data))); return 0; } if (Strangled) { pline("You can't speak. You're choking!"); return 0; } if (u.uswallow) { pline("They won't hear you out there."); return 0; } if (Underwater) { pline("Your speech is unintelligible underwater."); return 0; } if (!Blind && (otmp = shop_object(u.ux, u.uy)) != NULL) { /* standing on something in a shop and chatting causes the shopkeeper to describe the price(s). This can inhibit other chatting inside a shop, but that shouldn't matter much. shop_object() returns an object iff inside a shop and the shopkeeper is present and willing (not angry) and able (not asleep) to speak and the position contains any objects other than just gold. */ price_quote(otmp); return 1; } /* count the monsters around the player */ mon_count = 0; for (mdx = -1; mdx <= 1; mdx++) { for (mdy = -1; mdy <= 1; mdy++) { if (mdx == 0 && mdy == 0) { /* account for steed */ if (u.usteed) { mon_count++; dx = 0; dy = 0; dz = 1; } continue; } mtmp = m_at(level, u.ux + mdx, u.uy + mdy); if (mtmp && canspotmon(level, mtmp)) { mon_count++; dx = mdx; dy = mdy; dz = 0; } } } /* don't ask for a direction if there's only one monster around */ if ((mon_count != 1 || iflags.paranoid_chat) && !getdir("Talk to whom? (in what direction)", &dx, &dy, &dz)) { /* decided not to chat */ return 0; } if (u.usteed && dz > 0) { if (!u.usteed->mcanmove || u.usteed->msleeping) { pline("Your steed remains silent..."); return 0; } return domonnoise(u.usteed); } if (dz) { pline("They won't hear you %s there.", dz < 0 ? "up" : "down"); return 0; } if (dx == 0 && dy == 0) { /* * Let's not include this. It raises all sorts of questions: can you wear * 2 helmets, 2 amulets, 3 pairs of gloves or 6 rings as a marilith, * etc... --KAA if (u.umonnum == PM_ETTIN) { pline("You discover that your other head makes boring conversation."); return 1; } */ pline("Talking to yourself is a bad habit for a dungeoneer."); return 0; } tx = u.ux + dx; ty = u.uy + dy; mtmp = m_at(level, tx, ty); if (!mtmp || mtmp->mundetected || mtmp->m_ap_type == M_AP_FURNITURE || mtmp->m_ap_type == M_AP_OBJECT) return 0; /* sleeping monsters won't talk, except priests (who wake up) */ if ((!mtmp->mcanmove || mtmp->msleeping) && !mtmp->ispriest) { /* If it is unseen, the player can't tell the difference between not noticing him and just not existing, so skip the message. */ if (canspotmon(level, mtmp)) pline("%s seems not to notice you.", Monnam(mtmp)); return 0; } /* if this monster is waiting for something, prod it into action */ mtmp->mstrategy &= ~STRAT_WAITMASK; if (mtmp->mtame && mtmp->meating) { if (!canspotmon(level, mtmp)) map_invisible(mtmp->mx, mtmp->my); pline("%s is eating noisily.", Monnam(mtmp)); return 0; } if (Role_if(PM_CONVICT) && is_rat(mtmp->data) && !mtmp->mpeaceful && !mtmp->mtame) { int soothe_roll = rnl(10); pline("You attempt to soothe the %s with chittering sounds.", l_monnam(mtmp)); if (soothe_roll < 2) { tamedog(mtmp, NULL); } else if (soothe_roll > 8) { pline("%s unfortunately ignores your overtures.", Monnam(mtmp)); } else { mtmp->mpeaceful = 1; set_malign(mtmp); } return 1; } return domonnoise(mtmp); }
int doread() { struct obj *scroll; boolean confused = (Confusion != 0); boolean known = FALSE; scroll = getobj("?", "read"); if(!scroll) return(0); if(!scroll->dknown && Blind) { pline("Being blind, you cannot read the formula on the scroll."); return(0); } if(Blind) pline("As you pronounce the formula on it, the scroll disappears."); else pline("As you read the scroll, it disappears."); if(confused) pline("Being confused, you mispronounce the magic words ... "); switch(scroll->otyp) { #ifdef MAIL case SCR_MAIL: readmail(/* scroll */); break; #endif /* MAIL */ case SCR_ENCHANT_ARMOR: { struct obj *otmp = some_armor(); if(!otmp) { strange_feeling(scroll,"Your skin glows then fades."); return(1); } if(confused) { pline("Your %s glows silver for a moment.", objects[otmp->otyp].oc_name); otmp->rustfree = 1; break; } if(otmp->spe > 3 && rn2(otmp->spe)) { pline("Your %s glows violently green for a while, then evaporates.", objects[otmp->otyp].oc_name); useup(otmp); break; } pline("Your %s glows green for a moment.", objects[otmp->otyp].oc_name); otmp->cursed = 0; otmp->spe++; break; } case SCR_DESTROY_ARMOR: if(confused) { struct obj *otmp = some_armor(); if(!otmp) { strange_feeling(scroll,"Your bones itch."); return(1); } pline("Your %s glows purple for a moment.", objects[otmp->otyp].oc_name); otmp->rustfree = 0; break; } if(uarm) { pline("Your armor turns to dust and falls to the floor!"); useup(uarm); } else if(uarmh) { pline("Your helmet turns to dust and is blown away!"); useup(uarmh); } else if(uarmg) { pline("Your gloves vanish!"); useup(uarmg); selftouch("You"); } else { strange_feeling(scroll,"Your skin itches."); return(1); } break; case SCR_CONFUSE_MONSTER: if(confused) { pline("Your hands begin to glow purple."); Confusion += rnd(100); } else { pline("Your hands begin to glow blue."); u.umconf = 1; } break; case SCR_SCARE_MONSTER: { int ct = 0; struct monst *mtmp; for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(cansee(mtmp->mx,mtmp->my)) { if(confused) mtmp->mflee = mtmp->mfroz = mtmp->msleep = 0; else mtmp->mflee = 1; ct++; } if(!ct) { if(confused) pline("You hear sad wailing in the distance."); else pline("You hear maniacal laughter in the distance."); } break; } case SCR_BLANK_PAPER: if(confused) pline("You see strange patterns on this scroll."); else pline("This scroll seems to be blank."); break; case SCR_REMOVE_CURSE: { struct obj *obj; if(confused) pline("You feel like you need some help."); else pline("You feel like someone is helping you."); for(obj = invent; obj ; obj = obj->nobj) if(obj->owornmask) obj->cursed = confused; if(Punished && !confused) { Punished = 0; freeobj(uchain); unpobj(uchain); free(uchain); uball->spe = 0; uball->owornmask &= ~W_BALL; uchain = uball = (struct obj *) 0; } break; } case SCR_CREATE_MONSTER: { int cnt = 1; if(!rn2(73)) cnt += rnd(4); if(confused) cnt += 12; while(cnt--) (void) makemon(confused ? PM_ACID_BLOB : (struct permonst *) 0, u.ux, u.uy); break; } case SCR_ENCHANT_WEAPON: if(uwep && confused) { pline("Your %s glows silver for a moment.", objects[uwep->otyp].oc_name); uwep->rustfree = 1; } else if(!chwepon(scroll, 1)) /* tests for !uwep */ return(1); break; case SCR_DAMAGE_WEAPON: if(uwep && confused) { pline("Your %s glows purple for a moment.", objects[uwep->otyp].oc_name); uwep->rustfree = 0; } else if(!chwepon(scroll, -1)) /* tests for !uwep */ return(1); break; case SCR_TAMING: { int i,j; int bd = confused ? 5 : 1; struct monst *mtmp; for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++) if ((mtmp = m_at(u.ux+i, u.uy+j))) (void) tamedog(mtmp, NULL); break; } case SCR_GENOCIDE: { extern char genocided[], fut_geno[]; char buf[BUFSZ]; struct monst *mtmp, *mtmp2; pline("You have found a scroll of genocide!"); known = TRUE; if(confused) *buf = u.usym; else do { pline("What monster do you want to genocide (Type the letter)? "); getlin(buf); } while(strlen(buf) != 1 || !monstersym(*buf)); if(!strchr(fut_geno, *buf)) charcat(fut_geno, *buf); if(!strchr(genocided, *buf)) charcat(genocided, *buf); else { pline("Such monsters do not exist in this world."); break; } for(mtmp = fmon; mtmp; mtmp = mtmp2){ mtmp2 = mtmp->nmon; if(mtmp->data->mlet == *buf) mondead(mtmp); } pline("Wiped out all %c's.", *buf); if(*buf == u.usym) { killer = "scroll of genocide"; u.uhp = -1; } break; } case SCR_LIGHT: if(!Blind) known = TRUE; litroom(!confused); break; case SCR_TELEPORTATION: if(confused) level_tele(); else { #ifdef QUEST int oux = u.ux, ouy = u.uy; tele(); if(dist(oux, ouy) > 100) known = TRUE; #else /* QUEST */ int uroom = inroom(u.ux, u.uy); tele(); if(uroom != inroom(u.ux, u.uy)) known = TRUE; #endif /* QUEST */ } break; case SCR_GOLD_DETECTION: /* Unfortunately this code has become slightly less elegant, now that gold and traps no longer are of the same type. */ if(confused) { struct trap *ttmp; if(!ftrap) { strange_feeling(scroll, "Your toes stop itching."); return(1); } else { for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) if(ttmp->tx != u.ux || ttmp->ty != u.uy) goto outtrapmap; /* only under me - no separate display required */ pline("Your toes itch!"); break; outtrapmap: cls(); for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) at(ttmp->tx, ttmp->ty, '$'); prme(); pline("You feel very greedy!"); } } else { struct gold *gtmp; if(!fgold) { strange_feeling(scroll, "You feel materially poor."); return(1); } else { known = TRUE; for(gtmp = fgold; gtmp; gtmp = gtmp->ngold) if(gtmp->gx != u.ux || gtmp->gy != u.uy) goto outgoldmap; /* only under me - no separate display required */ pline("You notice some gold between your feet."); break; outgoldmap: cls(); for(gtmp = fgold; gtmp; gtmp = gtmp->ngold) at(gtmp->gx, gtmp->gy, '$'); prme(); pline("You feel very greedy, and sense gold!"); } } /* common sequel */ more(); docrt(); break; case SCR_FOOD_DETECTION: { int ct = 0, ctu = 0; struct obj *obj; char foodsym = confused ? POTION_SYM : FOOD_SYM; for(obj = fobj; obj; obj = obj->nobj) if(obj->olet == FOOD_SYM) { if(obj->ox == u.ux && obj->oy == u.uy) ctu++; else ct++; } if(!ct && !ctu) { strange_feeling(scroll,"Your nose twitches."); return(1); } else if(!ct) { known = TRUE; pline("You smell %s close nearby.", confused ? "something" : "food"); } else { known = TRUE; cls(); for(obj = fobj; obj; obj = obj->nobj) if(obj->olet == foodsym) at(obj->ox, obj->oy, FOOD_SYM); prme(); pline("Your nose tingles and you smell %s!", confused ? "something" : "food"); more(); docrt(); } break; } case SCR_IDENTIFY: /* known = TRUE; */ if(confused) pline("You identify this as an identify scroll."); else pline("This is an identify scroll."); useup(scroll); objects[SCR_IDENTIFY].oc_name_known = 1; if(!confused) while( !ggetobj("identify", identify, rn2(5) ? 1 : rn2(5)) && invent ); return(1); case SCR_MAGIC_MAPPING: { struct rm *lev; int num, zx, zy; known = TRUE; pline("On this scroll %s a map!", confused ? "was" : "is"); for(zy = 0; zy < ROWNO; zy++) for(zx = 0; zx < COLNO; zx++) { if(confused && rn2(7)) continue; lev = &(levl[zx][zy]); if((num = lev->typ) == 0) continue; if(num == SCORR) { lev->typ = CORR; lev->scrsym = CORR_SYM; } else if(num == SDOOR) { lev->typ = DOOR; lev->scrsym = '+'; /* do sth in doors ? */ } else if(lev->seen) continue; #ifndef QUEST if(num != ROOM) #endif /* QUEST */ { lev->seen = lev->new = 1; if(lev->scrsym == ' ' || !lev->scrsym) newsym(zx,zy); else on_scr(zx,zy); } } break; } case SCR_AMNESIA: { int zx, zy; known = TRUE; for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++) if(!confused || rn2(7)) if(!cansee(zx,zy)) levl[zx][zy].seen = 0; docrt(); pline("Thinking of Maud you forget everything else."); break; } case SCR_FIRE: { int num; struct monst *mtmp; known = TRUE; if(confused) { pline("The scroll catches fire and you burn your hands."); losehp(1, "scroll of fire"); } else { pline("The scroll erupts in a tower of flame!"); if(Fire_resistance) pline("You are uninjured."); else { num = rnd(6); u.uhpmax -= num; losehp(num, "scroll of fire"); } } num = (2*num + 1)/3; for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { if(dist(mtmp->mx,mtmp->my) < 3) { mtmp->mhp -= num; if(strchr("FY", mtmp->data->mlet)) mtmp->mhp -= 3*num; /* this might well kill 'F's */ if(mtmp->mhp < 1) { killed(mtmp); break; /* primitive */ } } } break; } case SCR_PUNISHMENT: known = TRUE; if(confused) { pline("You feel guilty."); break; } pline("You are being punished for your misbehaviour!"); if(Punished){ pline("Your iron ball gets heavier."); uball->owt += 15; break; } Punished = INTRINSIC; setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN); setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL); uball->spe = 1; /* special ball (see save) */ break; default: impossible("What weird language is this written in? (%u)", scroll->otyp); }
int dothrow() { struct obj *obj; struct monst *mon; int tmp; obj = getobj("#)", "throw"); /* it is also possible to throw food */ /* (or jewels, or iron balls ... ) */ if(!obj || !getdir(1)) /* ask "in what direction?" */ return(0); if(obj->owornmask & (W_ARMOR | W_RING)){ pline("You can't throw something you are wearing."); return(0); } u_wipe_engr(2); if(obj == uwep){ if(obj->cursed){ pline("Your weapon is welded to your hand."); return(1); } if(obj->quan > 1) setuwep(splitobj(obj, 1)); else setuwep((struct obj *) 0); } else if(obj->quan > 1) (void) splitobj(obj, 1); freeinv(obj); if(u.uswallow) { mon = u.ustuck; bhitpos.x = mon->mx; bhitpos.y = mon->my; } else if(u.dz) { if(u.dz < 0) { pline("%s hits the ceiling, then falls back on top of your head.", Doname(obj)); /* note: obj->quan == 1 */ if(obj->olet == POTION_SYM) potionhit(&youmonst, obj); else { if(uarmh) pline("Fortunately, you are wearing a helmet!"); losehp(uarmh ? 1 : rnd((int)(obj->owt)), "falling object"); dropy(obj); } } else { pline("%s hits the floor.", Doname(obj)); if(obj->otyp == EXPENSIVE_CAMERA) { pline("It is shattered in a thousand pieces!"); obfree(obj, Null(obj)); } else if(obj->otyp == EGG) { pline("\"Splash!\""); obfree(obj, Null(obj)); } else if(obj->olet == POTION_SYM) { pline("The flask breaks, and you smell a peculiar odor ..."); potionbreathe(obj); obfree(obj, Null(obj)); } else { dropy(obj); } } return(1); } else if(obj->otyp == BOOMERANG) { mon = boomhit(u.dx, u.dy); if(mon == &youmonst) { /* the thing was caught */ (void) addinv(obj); return(1); } } else { if(obj->otyp == PICK_AXE && shkcatch(obj)) return(1); mon = bhit(u.dx, u.dy, (obj->otyp == ICE_BOX) ? 1 : (!Punished || obj != uball) ? 8 : !u.ustuck ? 5 : 1, obj->olet, NULL, NULL, obj); } if(mon) { /* awake monster if sleeping */ wakeup(mon); if(obj->olet == WEAPON_SYM) { tmp = -1+u.ulevel+mon->data->ac+abon(); if(obj->otyp < ROCK) { if(!uwep || uwep->otyp != obj->otyp+(BOW-ARROW)) tmp -= 4; else { tmp += uwep->spe; } } else if(obj->otyp == BOOMERANG) tmp += 4; tmp += obj->spe; if(u.uswallow || tmp >= rnd(20)) { if(hmon(mon,obj,1) == TRUE){ /* mon still alive */ #ifndef NOWORM cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp); #endif /* NOWORM */ } else mon = 0; /* weapons thrown disappear sometimes */ if(obj->otyp < BOOMERANG && rn2(3)) { /* check bill; free */ obfree(obj, (struct obj *) 0); return(1); } } else miss(objects[obj->otyp].oc_name, mon); } else if(obj->otyp == HEAVY_IRON_BALL) { tmp = -1+u.ulevel+mon->data->ac+abon(); if(!Punished || obj != uball) tmp += 2; if(u.utrap) tmp -= 2; if(u.uswallow || tmp >= rnd(20)) { if(hmon(mon,obj,1) == FALSE) mon = 0; /* he died */ } else miss("iron ball", mon); } else if(obj->olet == POTION_SYM && u.ulevel > rn2(15)) { potionhit(mon, obj); return(1); } else { if(cansee(bhitpos.x,bhitpos.y)) pline("You miss %s.",monnam(mon)); else pline("You miss it."); if(obj->olet == FOOD_SYM && mon->data->mlet == 'd') if(tamedog(mon,obj)) return(1); if(obj->olet == GEM_SYM && mon->data->mlet == 'u' && !mon->mtame){ if(obj->dknown && objects[obj->otyp].oc_name_known){ if(objects[obj->otyp].g_val > 0){ u.uluck += 5; goto valuable; } else { pline("%s is not interested in your junk.", Monnam(mon)); } } else { /* value unknown to @ */ u.uluck++; valuable: if(u.uluck > LUCKMAX) /* dan@ut-ngp */ u.uluck = LUCKMAX; pline("%s graciously accepts your gift.", Monnam(mon)); mpickobj(mon, obj); rloc(mon); return(1); } } } } /* the code following might become part of dropy() */ if(obj->otyp == CRYSKNIFE) obj->otyp = WORM_TOOTH; obj->ox = bhitpos.x; obj->oy = bhitpos.y; obj->nobj = fobj; fobj = obj; /* prevent him from throwing articles to the exit and escaping */ /* subfrombill(obj); */ stackobj(obj); if(Punished && obj == uball && (bhitpos.x != u.ux || bhitpos.y != u.uy)){ freeobj(uchain); unpobj(uchain); if(u.utrap){ if(u.utraptype == TT_PIT) pline("The ball pulls you out of the pit!"); else { long side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE; pline("The ball pulls you out of the bear trap."); pline("Your %s leg is severely damaged.", (side == LEFT_SIDE) ? "left" : "right"); set_wounded_legs(side, 500+rn2(1000)); losehp(2, "thrown ball"); } u.utrap = 0; } unsee(); uchain->nobj = fobj; fobj = uchain; u.ux = uchain->ox = bhitpos.x - u.dx; u.uy = uchain->oy = bhitpos.y - u.dy; setsee(); (void) inshop(); } if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y); return(1); }
/* special effects for The Book of the Dead */ void deadbook(struct obj *book2, boolean invoked) { struct monst *mtmp, *mtmp2; coord mm; if (!invoked) pline("You turn the pages of the Book of the Dead..."); makeknown(SPE_BOOK_OF_THE_DEAD); /* KMH -- Need ->known to avoid "_a_ Book of the Dead" */ book2->known = 1; if (invocation_pos(&u.uz, u.ux, u.uy) && !On_stairs(u.ux, u.uy)) { struct obj *otmp; boolean arti1_primed = FALSE, arti2_primed = FALSE, arti_cursed = FALSE; if (invoked) { if (Blind) You_hear("a crisp flicker..."); else pline("The Book of the Dead opens of its own accord..."); } if (book2->cursed) { if (invoked) { if (Hallucination) You_hear("gratuitous bleeping."); else You_hear("a mumbled curse."); } else pline("The runes appear scrambled. You can't read them!"); return; } if (!Uhave_bell || !Uhave_menorah) { pline("A chill runs down your %s.", body_part(SPINE)); if (!Uhave_bell) { if (Hallucination) pline("You feel like a tuning fork!"); else You_hear("a faint chime..."); } if (!Uhave_menorah) { if (Hallucination) { pline("Nosferatu giggles."); } else if (mvitals[PM_DOPPELGANGER].mvflags & G_GENOD) { /* suggestion by b_jonas: can't talk about doppelgangers if they don't exist */ if (Uhave_bell) pline("Nothing seems to happen."); /* otherwise no message, we already printed one. */ } else { pline("Vlad's doppelganger is amused."); } } return; } for (otmp = invent; otmp; otmp = otmp->nobj) { if (otmp->otyp == CANDELABRUM_OF_INVOCATION && otmp->spe == 7 && otmp->lamplit) { if (!otmp->cursed) arti1_primed = TRUE; else arti_cursed = TRUE; } if (otmp->otyp == BELL_OF_OPENING && (moves - otmp->age) < 5L) { /* you rang it recently */ if (!otmp->cursed) arti2_primed = TRUE; else arti_cursed = TRUE; } } if (arti_cursed) { pline("The invocation fails!"); if (Hallucination) pline("At least one of your heirlooms is in a tizzy!"); else pline("At least one of your artifacts is cursed..."); } else if (arti1_primed && arti2_primed) { unsigned soon = (unsigned)dice(2, 6); /* time til next intervene */ /* successful invocation */ mkinvokearea(); u.uevent.invoked = 1; historic_event(FALSE, TRUE, "performed the invocation."); /* in case you haven't killed the Wizard yet, behave as if you just did */ u.uevent.udemigod = 1; /* wizdead() */ if (!u.udg_cnt || u.udg_cnt > soon) u.udg_cnt = soon; } else { /* at least one artifact not prepared properly */ pline("You have a feeling that something is amiss..."); goto raise_dead; } return; } /* when not an invocation situation */ if (invoked) { pline("Nothing happens."); return; } if (book2->cursed) { raise_dead: if (Hallucination) You_hear("Michael Jackson dancing!"); else pline("You raised the dead!"); /* first maybe place a dangerous adversary; don't bother with MM_CREATEMONSTER, that's mostly used to ensure that consistent species of monsters generate */ if (!rn2(3) && ((mtmp = makemon(&mons[PM_MASTER_LICH], level, u.ux, u.uy, NO_MINVENT)) != 0 || (mtmp = makemon(&mons[PM_NALFESHNEE], level, u.ux, u.uy, NO_MINVENT)) != 0)) { msethostility(mtmp, TRUE, TRUE); } /* next handle the effect on things you're carrying */ unturn_dead(&youmonst); /* last place some monsters around you */ mm.x = u.ux; mm.y = u.uy; mkundead(level, &mm, TRUE, NO_MINVENT); } else if (book2->blessed) { for (mtmp = level->monlist; mtmp; mtmp = mtmp2) { mtmp2 = mtmp->nmon; /* tamedog() changes chain */ if (DEADMONSTER(mtmp)) continue; if (is_undead(mtmp->data) && cansee(mtmp->mx, mtmp->my)) { msethostility(mtmp, FALSE, FALSE); /* TODO: reset alignment? */ if (sgn(mtmp->data->maligntyp) == sgn(u.ualign.type) && distu(mtmp->mx, mtmp->my) < 4) if (mtmp->mtame) { if (mtmp->mtame < 20) mtmp->mtame++; } else tamedog(mtmp, NULL); else monflee(mtmp, 0, FALSE, TRUE); } } } else { switch (rn2(3)) { case 0: pline("Your ancestors are annoyed with you!"); break; case 1: pline("The headstones in the cemetery begin to move!"); break; default: pline("Oh my! Your name appears in the book!"); } } return; }