int dospinweb(void) { struct trap *ttmp = t_at(level, u.ux, u.uy); if (Levitation || Is_airlevel(&u.uz) || Underwater || Is_waterlevel(&u.uz)) { pline("You must be on the ground to spin a web."); return 0; } if (u.uswallow) { pline("You release web fluid inside %s.", mon_nam(u.ustuck)); if (is_animal(u.ustuck->data)) { expels(u.ustuck, u.ustuck->data, TRUE); return 0; } if (is_whirly(u.ustuck->data)) { int i; for (i = 0; i < NATTK; i++) if (u.ustuck->data->mattk[i].aatyp == AT_ENGL) break; if (i == NATTK) impossible("Swallower has no engulfing attack?"); else { char sweep[30]; sweep[0] = '\0'; switch(u.ustuck->data->mattk[i].adtyp) { case AD_FIRE: strcpy(sweep, "ignites and "); break; case AD_ELEC: strcpy(sweep, "fries and "); break; case AD_COLD: strcpy(sweep, "freezes, shatters and "); break; } pline("The web %sis swept away!", sweep); } return 0; } /* default: a nasty jelly-like creature */ pline("The web dissolves into %s.", mon_nam(u.ustuck)); return 0; } if (u.utrap) { pline("You cannot spin webs while stuck in a trap."); return 0; } exercise(A_DEX, TRUE); if (ttmp) switch (ttmp->ttyp) { case PIT: case SPIKED_PIT: pline("You spin a web, covering up the pit."); deltrap(ttmp); bury_objs(u.ux, u.uy); newsym(u.ux, u.uy); return 1; case SQKY_BOARD: pline("The squeaky board is muffled."); deltrap(ttmp); newsym(u.ux, u.uy); return 1; case TELEP_TRAP: case LEVEL_TELEP: case MAGIC_PORTAL: case VIBRATING_SQUARE: pline("Your webbing vanishes!"); return 0; case WEB: pline("You make the web thicker."); return 1; case HOLE: case TRAPDOOR: pline("You web over the %s.", (ttmp->ttyp == TRAPDOOR) ? "trap door" : "hole"); deltrap(ttmp); newsym(u.ux, u.uy); return 1; case ROLLING_BOULDER_TRAP: pline("You spin a web, jamming the trigger."); deltrap(ttmp); newsym(u.ux, u.uy); return 1; case ARROW_TRAP: case DART_TRAP: case BEAR_TRAP: case ROCKTRAP: case FIRE_TRAP: case LANDMINE: case SLP_GAS_TRAP: case RUST_TRAP: case MAGIC_TRAP: case ANTI_MAGIC: case POLY_TRAP: pline("You have triggered a trap!"); dotrap(ttmp, 0); return 1; default: impossible("Webbing over trap type %d?", ttmp->ttyp); return 0; } else if (On_stairs(u.ux, u.uy)) { /* cop out: don't let them hide the stairs */ pline("Your web fails to impede access to the %s.", (level->locations[u.ux][u.uy].typ == STAIRS) ? "stairs" : "ladder"); return 1; } ttmp = maketrap(level, u.ux, u.uy, WEB); if (ttmp) { ttmp->tseen = 1; ttmp->madeby_u = 1; } newsym(u.ux, u.uy); 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; }