Ejemplo n.º 1
0
/*
 * Open the drawbridge located at x,y
 */
void open_drawbridge(int x, int y)
{
	struct rm *loc1, *loc2;
	struct trap *t;
	int x2, y2;

	loc1 = &level->locations[x][y];
	if (loc1->typ != DRAWBRIDGE_UP) return;
	x2 = x; y2 = y;
	get_wall_for_db(&x2,&y2);
	if (cansee(x,y) || cansee(x2,y2))
		pline("You see a drawbridge %s down!",
		    (distu(x2,y2) < distu(x,y)) ? "going" : "coming");
	loc1->typ = DRAWBRIDGE_DOWN;
	loc2 = &level->locations[x2][y2];
	loc2->typ = DOOR;
	loc2->doormask = D_NODOOR;
	set_entity(x, y, &(occupants[0]));
	set_entity(x2, y2, &(occupants[1]));
	do_entity(&(occupants[0]));		/* do set_entity after first */
	set_entity(x2, y2, &(occupants[1]));	/* do_entity for worm tails */
	do_entity(&(occupants[1]));
	revive_nasty(x,y,NULL);
	delallobj(x, y);
	if ((t = t_at(level, x, y)) != 0) deltrap(level, t);
	if ((t = t_at(level, x2, y2)) != 0) deltrap(level, t);
	newsym(x, y);
	newsym(x2, y2);
	unblock_point(x2,y2);	/* vision */
	if (Is_stronghold(&u.uz)) u.uevent.uopened_dbridge = TRUE;
}
Ejemplo n.º 2
0
/*
 * Close the drawbridge located at x,y.
 * Returns TRUE if the drawbridge was closed, FALSE otherwise.
 */
boolean close_drawbridge(int x, int y)
{
	struct rm *loc1, *loc2;
	struct monst *m;
	struct trap *t;
	int x2, y2;

	loc1 = &level->locations[x][y];
	if (loc1->typ != DRAWBRIDGE_DOWN) return FALSE;
	/* A huge monster will block the drawbridge. */
	if ((m = m_at(level, x, y)) && hugemonst(m->data)) {
	    pline("%s blocks the drawbridge with %s weight!",
		  canseemon(level, m) ? Amonnam(m) : "Something",
		  canseemon(level, m) ? mhis(level, m) : "its");
	    return FALSE;
	}
	if (rn2(5) == 0) {
	    pline("The mechanism seems to have something stuck in it and won't close.");
	    return FALSE;
	}
	x2 = x; y2 = y;
	get_wall_for_db(&x2,&y2);
	if (cansee(x,y) || cansee(x2,y2))
		pline("You see a drawbridge %s up!",
		    (((u.ux == x || u.uy == y) && !Underwater) ||
		     distu(x2,y2) < distu(x,y)) ? "coming" : "going");
	loc1->typ = DRAWBRIDGE_UP;
	loc2 = &level->locations[x2][y2];
	loc2->typ = DBWALL;
	switch (loc1->drawbridgemask & DB_DIR) {
		case DB_NORTH:
		case DB_SOUTH:
			loc2->horizontal = TRUE;
			break;
		case DB_WEST:
		case DB_EAST:
			loc2->horizontal = FALSE;
			break;
	}
	loc2->wall_info = W_NONDIGGABLE;
	set_entity(x, y, &(occupants[0]));
	set_entity(x2, y2, &(occupants[1]));
	do_entity(&(occupants[0]));		/* Do set_entity after first */
	set_entity(x2, y2, &(occupants[1]));	/* do_entity for worm tail */
	do_entity(&(occupants[1]));
	if (OBJ_AT(x, y) && flags.soundok)
	    You_hear("smashing and crushing.");
	revive_nasty(x,y,NULL);
	revive_nasty(x2,y2,NULL);
	delallobj(x, y);
	delallobj(x2, y2);
	if ((t = t_at(level, x, y)) != 0) deltrap(level, t);
	if ((t = t_at(level, x2, y2)) != 0) deltrap(level, t);
	newsym(x, y);
	newsym(x2, y2);
	block_point(x2,y2);	/* vision */
	return TRUE;
}
Ejemplo n.º 3
0
/*
 * Close the drawbridge located at x,y
 */
void
close_drawbridge(int x, int y)
{
    struct rm *loc1, *loc2;
    struct trap *t;
    int x2, y2;

    loc1 = &level->locations[x][y];
    if (loc1->typ != DRAWBRIDGE_DOWN)
        return;
    x2 = x;
    y2 = y;
    get_wall_for_db(&x2, &y2);
    if (cansee(x, y) || cansee(x2, y2))
        pline("You see a drawbridge %s up!",
              (((u.ux == x || u.uy == y) && !Underwater) ||
               distu(x2, y2) < distu(x, y)) ? "coming" : "going");
    else if (canhear())
        pline("You hear chains rattling and gears turning.");
    loc1->typ = DRAWBRIDGE_UP;
    loc2 = &level->locations[x2][y2];
    loc2->typ = DBWALL;
    switch (loc1->drawbridgemask & DB_DIR) {
    case DB_NORTH:
    case DB_SOUTH:
        loc2->horizontal = TRUE;
        break;
    case DB_WEST:
    case DB_EAST:
        loc2->horizontal = FALSE;
        break;
    }
    loc2->wall_info = W_NONDIGGABLE;
    set_entity(x, y, &(occupants[0]));
    set_entity(x2, y2, &(occupants[1]));
    do_entity(&(occupants[0])); /* Do set_entity after first */
    set_entity(x2, y2, &(occupants[1]));        /* do_entity for worm tail */
    do_entity(&(occupants[1]));
    if (OBJ_AT(x, y))
        You_hear("smashing and crushing.");
    revive_nasty(x, y, NULL);
    revive_nasty(x2, y2, NULL);
    delallobj(x, y);
    delallobj(x2, y2);
    if ((t = t_at(level, x, y)) != 0)
        deltrap(level, t);
    if ((t = t_at(level, x2, y2)) != 0)
        deltrap(level, t);
    del_engr_at(level, x, y);
    del_engr_at(level, x2, y2);
    newsym(x, y);
    newsym(x2, y2);
    block_point(x2, y2);        /* vision */
}
Ejemplo n.º 4
0
Archivo: wizard.c Proyecto: yzh/yzhack
/* Also, give hints about portal locations, if amulet is worn/wielded -dlc */
void
amulet()
{
	struct monst *mtmp;
	struct trap *ttmp;
	struct obj *amu;

#if 0		/* caller takes care of this check */
	if (!u.uhave.amulet)
		return;
#endif
	if ((((amu = uamul) != 0 && amu->otyp == AMULET_OF_YENDOR) ||
	     ((amu = uwep) != 0 && amu->otyp == AMULET_OF_YENDOR))
	    && !rn2(15)) {
	    for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
		if(ttmp->ttyp == MAGIC_PORTAL) {
		    int du = distu(ttmp->tx, ttmp->ty);
		    if (du <= 9)
/*JP
			pline("%s hot!", Tobjnam(amu, "feel"));
*/
			pline("%sは熱く感じた!", xname(amu));
		    else if (du <= 64)
/*JP
			pline("%s very warm.", Tobjnam(amu, "feel"));
*/
			pline("%sはとても暖かく感じた。", xname(amu));
		    else if (du <= 144)
/*JP
			pline("%s warm.", Tobjnam(amu, "feel"));
*/
			pline("%sは暖かく感じた。", xname(amu));
		    /* else, the amulet feels normal */
		    break;
		}
	    }
	}

	if (!flags.no_of_wizards)
		return;
	/* find Wizard, and wake him if necessary */
	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
	    if (!DEADMONSTER(mtmp) && mtmp->iswiz && mtmp->msleeping && !rn2(40)) {
		mtmp->msleeping = 0;
		if (distu(mtmp->mx,mtmp->my) > 2)
		    You(
/*JP
    "get the creepy feeling that somebody noticed your taking the Amulet."
*/
 "あなたが魔除けを持っていることが誰かに知られたと感じてぞくぞくした。"
		    );
		return;
	    }
}
Ejemplo n.º 5
0
/* Charm snakes in range.  Note that the snakes are NOT tamed. */
static void
charm_snakes(int distance)
{
    struct monst *mtmp = level->monlist;
    int could_see_mon, was_peaceful;

    while (mtmp) {
        if (!DEADMONSTER(mtmp) && mtmp->data->mlet == S_SNAKE && mtmp->mcanmove
            && distu(mtmp->mx, mtmp->my) < distance) {
            was_peaceful = mtmp->mpeaceful;
            mtmp->mavenge = 0;
            could_see_mon = canspotmon(mtmp);
            mtmp->mundetected = 0;
            msethostility(mtmp, FALSE, FALSE); /* does a newsym() */
            if (canseemon(mtmp)) {
                if (!could_see_mon)
                    pline(msgc_youdiscover,
                          "You notice %s, swaying with the music.",
                          a_monnam(mtmp));
                else
                    pline(msgc_actionok,
                          "%s freezes, then sways with the music%s.",
                          Monnam(mtmp),
                          was_peaceful ? "" : ", and now seems quieter");
            }
        }
        mtmp = mtmp->nmon;
    }
}
Ejemplo n.º 6
0
int domindblast (void) {
    struct monst *mtmp, *nmon;

    if (u.uen < 10) {
        You("concentrate but lack the energy to maintain doing so.");
        return(0);
    }
    u.uen -= 10;

    You("concentrate.");
    pline("A wave of psychic energy pours out.");
    for(mtmp=fmon; mtmp; mtmp = nmon) {
        int u_sen;

        nmon = mtmp->nmon;
        if (DEADMONSTER(mtmp))
            continue;
        if (distu(mtmp->mx, mtmp->my) > BOLT_LIM * BOLT_LIM)
            continue;
        if (mtmp->mpeaceful)
            continue;
        u_sen = telepathic(mtmp->data) && !mtmp->mcansee;
        if (u_sen || (telepathic(mtmp->data) && rn2(2)) || !rn2(10)) {
            You("lock in on %s %s.", "TODO: s_suffix(mon_nam(mtmp))",
                    u_sen ? "telepathy" :
                    telepathic(mtmp->data) ? "latent telepathy" :
                    "mind");
            mtmp->mhp -= rnd(15);
            if (mtmp->mhp <= 0)
                killed(mtmp);
        }
    }
    return 1;
}
Ejemplo n.º 7
0
/* article: only ARTICLE_NONE and ARTICLE_THE are handled here */
char *distant_monnam(const struct monst *mon, int article, char *outbuf)
{
    /* high priest(ess)'s identity is concealed on the Astral Plane,
       unless you're adjacent (overridden for hallucination which does
       its own obfuscation) */
    if (mon->data == &mons[PM_HIGH_PRIEST] && !Hallucination &&
	    Is_astralevel(&u.uz) && distu(mon->mx, mon->my) > 2) {
	strcpy(outbuf, article == ARTICLE_THE ? "the " : "");
	strcat(outbuf, mon->female ? "high priestess" : "high priest");
    } else {
	strcpy(outbuf, x_monnam(mon, article, NULL, 0, TRUE));
    }
    return outbuf;
}
Ejemplo n.º 8
0
/* Make monsters fall asleep.  Note that they may resist the spell. */
static void
put_monsters_to_sleep(int distance)
{
    struct monst *mtmp = level->monlist;

    while (mtmp) {
        if (!DEADMONSTER(mtmp) && distu(mtmp->mx, mtmp->my) < distance &&
            sleep_monst(&youmonst, mtmp, dice(10, 10), TOOL_CLASS)) {
            mtmp->msleeping = 1;        /* 10d10 turns + wake_nearby to rouse */
            slept_monst(mtmp);
        }
        mtmp = mtmp->nmon;
    }
}
Ejemplo n.º 9
0
/*ARGSUSED*/
STATIC_OVL void
newmail(struct mail_info *info)
{
    struct monst *md;
    coord start, stop;
    boolean message_seen = FALSE;

    /* Try to find good starting and stopping places. */
    if (!md_start(&start) || !md_stop(&stop,&start)) goto give_up;

    /* Make the daemon.  Have it rush towards the hero. */
    if (!(md = makemon(&mons[PM_MAIL_DAEMON], start.x, start.y, NO_MM_FLAGS)))
        goto give_up;
    if (!md_rush(md, stop.x, stop.y)) goto go_back;

    message_seen = TRUE;
    verbalize("%s, %s!  %s.", Hello(md), plname, info->display_txt);

    if (info->message_typ) {
        struct obj *obj = mksobj(SCR_MAIL, FALSE, FALSE);
        if (info->message_typ == MSG_HINT) obj->spe = MAIL_HINT;
        if (distu(md->mx,md->my) > 2)
            verbalize("Catch!");
        display_nhwindow(WIN_MESSAGE, FALSE);
        if (info->object_nam) {
            obj = oname(obj, info->object_nam);
            if (info->response_cmd) {	/*(hide extension of the obj name)*/
                int namelth = info->response_cmd - info->object_nam - 1;
                if ( namelth <= 0 || namelth >= (int) obj->onamelth )
                    warning("mail delivery screwed up");
                else
                    *(ONAME(obj) + namelth) = '\0';
                /* Note: renaming object will discard the hidden command. */
            }
        }
        obj = hold_another_object(obj, "Oops!",
                                  (const char *)0, (const char *)0);
    }

    /* zip back to starting location */
go_back:
    (void) md_rush(md, start.x, start.y);
    mongone(md);
    /* deliver some classes of messages even if no daemon ever shows up */
give_up:
    if (!message_seen && info->message_typ == MSG_OTHER)
        pline("Hark!  \"%s.\"", info->display_txt);
}
Ejemplo n.º 10
0
/*
 *  wormhitu()
 *
 *  Check for mon->wormno before calling this function!
 *
 *  If the hero is near any part of the worm, the worm will try to attack.
 */
void wormhitu(struct monst *worm)
{
    int wnum = worm->wormno;
    struct wseg *seg;

/*  if (!wnum) return;  bullet proofing */

/*  This does not work right now because mattacku() thinks that the head is
 *  out of range of the player.  We might try to kludge, and bring the head
 *  within range for a tiny moment, but this needs a bit more looking at
 *  before we decide to do this.
 */
    for (seg = level->wtails[wnum]; seg; seg = seg->nseg)
	if (distu(seg->wx, seg->wy) < 3)
	    mattacku(worm);
}
Ejemplo n.º 11
0
/*
 * Try to find a dismount point adjacent to the steed's location.
 * If all else fails, try enexto().  Use enexto() as a last resort because
 * enexto() chooses its point randomly, possibly even outside the
 * room's walls, which is not what we want.
 * Adapted from mail daemon code.
 */
static boolean
landing_spot(coord * spot,      /* landing position (we fill it in) */
             int reason, int forceit)
{
    int i = 0, x, y, distance, min_distance = -1;
    boolean found = FALSE;
    struct trap *t;

    /* avoid known traps (i == 0) and boulders, but allow them as a backup */
    if (reason != DISMOUNT_BYCHOICE || Stunned || Confusion || Fumbling)
        i = 1;
    for (; !found && i < 2; ++i) {
        for (x = u.ux - 1; x <= u.ux + 1; x++)
            for (y = u.uy - 1; y <= u.uy + 1; y++) {
                if (!isok(x, y) || (x == u.ux && y == u.uy))
                    continue;

                if (ACCESSIBLE(level->locations[x][y].typ) &&
                    !MON_AT(level, x, y) && !closed_door(level, x, y)) {
                    distance = distu(x, y);
                    if (min_distance < 0 || distance < min_distance ||
                        (distance == min_distance && rn2(2))) {
                        if (i > 0 ||
                            (((t = t_at(level, x, y)) == 0 || !t->tseen) &&
                             (!sobj_at(BOULDER, level, x, y) ||
                              throws_rocks(youmonst.data)))) {
                            spot->x = x;
                            spot->y = y;
                            min_distance = distance;
                            found = TRUE;
                        }
                    }
                }
            }
    }

    /* If we didn't find a good spot and forceit is on, try enexto(). */
    if (forceit && min_distance < 0 &&
        !enexto(spot, level, u.ux, u.uy, youmonst.data))
        return FALSE;

    return found;
}
Ejemplo n.º 12
0
/* Calm nymphs in range. */
static void
calm_nymphs(int distance)
{
    struct monst *mtmp = level->monlist;

    while (mtmp) {
        if (!DEADMONSTER(mtmp) && mtmp->data->mlet == S_NYMPH && mtmp->mcanmove
            && distu(mtmp->mx, mtmp->my) < distance) {
            mtmp->msleeping = 0;
            msethostility(mtmp, FALSE, FALSE);
            mtmp->mavenge = 0;
            if (canseemon(mtmp))
                pline(msgc_actionok,
                      "%s listens cheerfully to the music, then seems quieter.",
                      Monnam(mtmp));
        }
        mtmp = mtmp->nmon;
    }
}
Ejemplo n.º 13
0
/* 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);
            }
        }
    }

}
Ejemplo n.º 14
0
/* Is a monster willing to fire with a compass beam in a given direction?

   Returns TRUE and sets *mdef to a monster if there's a monster it wants to
   target (and no monster it doesn't want to attack). *mdef can be &youmonst.

   If mdef is non-NULL, also set the tbx/tby globals for backwards compatibility
   (clobbered on a *mdef == NULL return, appropriately otherwise). TODO: get rid
   of these, they're really spaghetti.

   Returns TRUE and sets *mdef to NULL if there's no reason it wants to fire
   in that direction, but no reason it dislikes firing in that direction
   either.

   Returns FALSE if the monster refuses to fire in that direction. In this
   case, *mdef will be a monster that we don't want to target (possibly
   &youmonst).
   
   helpful determines whether or not a beam gives a positive effect */
boolean
m_beam_ok(struct monst *magr, int dx, int dy, struct monst **mdef, boolean helpful)
{
    int x = magr->mx;
    int y = magr->my;
    int i;
    struct monst *mat;

    if (mdef)
        *mdef = NULL;

    for (i = 0; i < BOLT_LIM; i++) {
        x += dx;
        y += dy;

        /* Will the beam stop at this point? As usual, assume that monsters have
           perfect knowledge of the level layout. */
        if (!isok(x, y) || !ZAP_POS(level->locations[x][y].typ) ||
            closed_door(level, x, y))
            break;

        /* Will the monster think that the beam will hit the player? Does it
           care? Hostiles like to attack the player; peacefuls don't want to.
           Pets have perfect knowledge of their master's location even if they
           can't sense their master. Confused monsters can't aim a beam at the
           player (or to avoid the player); no monster can hit an engulfed
           player with a beam. */
        if ((x == magr->mux && y == magr->muy && msensem(magr, &youmonst)) ||
            (magr->mtame && x == u.ux && y == u.uy)) {
            if (!Engulfed && !magr->mconf) {
                if (mdef) {
                    *mdef = &youmonst;
                    tbx = x - magr->mx;
                    tby = y - magr->my;
                }

                if (!Conflict) {
                    if ((!helpful && magr->mpeaceful) ||
                        (helpful && !magr->mpeaceful))
                    return FALSE;
                }
            }
        }

        mat = m_at(level, x, y);

        /* special case: make sure we don't hit the quest leader with stray
           beams, as it can make the game unwinnable; do this regardless of LOS
           or hostility or Conflict or confusion or anything like that */
        if (mat && mat->data->msound == MS_LEADER && !helpful) {
            if (mdef)
                *mdef = mat;
            return FALSE;
        }

        /* Confused monsters aren't trying to target anything in particular,
           because they don't have full control of their actions. Monsters won't
           intentionally aim at or to avoid a monster they can't see (apart from
           the above MS_LEADER case). */
        if (mat && (msensem(magr, mat) & ~MSENSE_ITEMMIMIC) && !magr->mconf) {
            /* Note: the couldsee() here is an LOE check and has nothing to
               do with vision; it determines conflict radius */
            if (Conflict && !resist(magr, RING_CLASS, 0, 0) &&
                couldsee(magr->mx, magr->my) &&
                distu(magr->mx, magr->my) <= BOLT_LIM * BOLT_LIM) {
                /* we're conflicted, anything is a valid target */
                if (mdef) {
                    *mdef = mat;
                    tbx = x - magr->mx;
                    tby = y - magr->my;
                }
            } else if (mm_aggression(magr, mat) & ALLOW_M && !helpful) {
                /* we want to target this monster */
                if (mdef) {
                    *mdef = mat;
                    tbx = x - magr->mx;
                    tby = y - magr->my;
                }
            } else if (!helpful && (magr->mpeaceful || mat->mpeaceful)) {
                /* we don't want to attack this monster; peacefuls (including
                   pets) should avoid collateral damage; also handles the
                   pet_attacks_up_to_difficulty checks; symmetrised so that
                   hostiles won't attack pets who won't attack them */
                if (mdef)
                    *mdef = mat;
                return FALSE;
            } else if (helpful &&
                       ((magr->mpeaceful && mat->mpeaceful) ||
                        (!magr->mpeaceful && !mat->mpeaceful))) {
                /* helpful beam, hostile-hostile or peaceful/tame-peaceful/tame
                   is OK; the peaceful checks aren't redundant with above since
                   pet_attacks_up_to_difficulty is a thing */
                if (mdef) {
                    *mdef = mat;
                    tbx = x - magr->mx;
                    tby = y - magr->my;
                }
            }
        }
    }

    return TRUE;
}
Ejemplo n.º 15
0
/* 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;
}
Ejemplo n.º 16
0
static void mon_vision_summary(const struct monst *mtmp, char *outbuf)
{
    int ways_seen = 0, normal = 0, xraydist;
    boolean useemon = (boolean) canseemon(mtmp);
    
    outbuf[0] = '\0';

    xraydist = (u.xray_range<0) ? -1 : u.xray_range * u.xray_range;
    /* normal vision */
    if ((mtmp->wormno ? worm_known(mtmp) : cansee(mtmp->mx, mtmp->my)) &&
	    mon_visible(mtmp) && !mtmp->minvis) {
	ways_seen++;
	normal++;
    }
    /* see invisible */
    if (useemon && mtmp->minvis)
	ways_seen++;
    /* infravision */
    if ((!mtmp->minvis || See_invisible) && see_with_infrared(mtmp))
	ways_seen++;
    /* telepathy */
    if (tp_sensemon(mtmp))
	ways_seen++;
    /* xray */
    if (useemon && xraydist > 0 &&
	    distu(mtmp->mx, mtmp->my) <= xraydist)
	ways_seen++;
    if (Detect_monsters)
	ways_seen++;
    if (MATCH_WARN_OF_MON(mtmp))
	ways_seen++;

    if (ways_seen > 1 || !normal) {
	if (normal) {
	    strcat(outbuf, "normal vision");
	    /* can't actually be 1 yet here */
	    if (ways_seen-- > 1) strcat(outbuf, ", ");
	}
	if (useemon && mtmp->minvis) {
	    strcat(outbuf, "see invisible");
	    if (ways_seen-- > 1) strcat(outbuf, ", ");
	}
	if ((!mtmp->minvis || See_invisible) &&
		see_with_infrared(mtmp)) {
	    strcat(outbuf, "infravision");
	    if (ways_seen-- > 1) strcat(outbuf, ", ");
	}
	if (tp_sensemon(mtmp)) {
	    strcat(outbuf, "telepathy");
	    if (ways_seen-- > 1) strcat(outbuf, ", ");
	}
	if (useemon && xraydist > 0 &&
		distu(mtmp->mx, mtmp->my) <= xraydist) {
	    /* Eyes of the Overworld */
	    strcat(outbuf, "astral vision");
	    if (ways_seen-- > 1) strcat(outbuf, ", ");
	}
	if (Detect_monsters) {
	    strcat(outbuf, "monster detection");
	    if (ways_seen-- > 1) strcat(outbuf, ", ");
	}
	if (MATCH_WARN_OF_MON(mtmp)) {
	    char wbuf[BUFSZ];
	    if (Hallucination)
		    strcat(outbuf, "paranoid delusion");
	    else {
		    sprintf(wbuf, "warned of %s",
			    makeplural(mtmp->data->mname));
		    strcat(outbuf, wbuf);
	    }
	    if (ways_seen-- > 1) strcat(outbuf, ", ");
	}
    }
}
Ejemplo n.º 17
0
/*
 * Pick coordinates for a starting position for the mail daemon.  Called
 * from newmail() and newphone().
 */
STATIC_OVL boolean
md_start(coord *startp)
{
    coord testcc;	/* scratch coordinates */
    int row;		/* current row we are checking */
    int lax;		/* if TRUE, pick a position in sight. */
    int dd;		/* distance to current point */
    int max_distance;	/* max distance found so far */

    /*
     * If blind and not telepathic, then it doesn't matter what we pick ---
     * the hero is not going to see it anyway.  So pick a nearby position.
     */
    if (Blind && !Blind_telepat) {
        if (!enexto(startp, u.ux, u.uy, (struct permonst *) 0))
            return FALSE;	/* no good posiitons */
        return TRUE;
    }

    /*
     * Arrive at an up or down stairwell if it is in line of sight from the
     * hero.
     */
    if (couldsee(upstair.sx, upstair.sy)) {
        startp->x = upstair.sx;
        startp->y = upstair.sy;
        return TRUE;
    }
    if (couldsee(dnstair.sx, dnstair.sy)) {
        startp->x = dnstair.sx;
        startp->y = dnstair.sy;
        return TRUE;
    }

    /*
     * Try to pick a location out of sight next to the farthest position away
     * from the hero.  If this fails, try again, just picking the farthest
     * position that could be seen.  What we really ought to be doing is
     * finding a path from a stairwell...
     *
     * The arrays viz_rmin[] and viz_rmax[] are set even when blind.  These
     * are the LOS limits for each row.
     */
    lax = 0;	/* be picky */
    max_distance = -1;
retry:
    for (row = 0; row < ROWNO; row++) {
        if (viz_rmin[row] < viz_rmax[row]) {
            /* There are valid positions on this row. */
            dd = distu(viz_rmin[row],row);
            if (dd > max_distance) {
                if (lax) {
                    max_distance = dd;
                    startp->y = row;
                    startp->x = viz_rmin[row];

                } else if (enexto(&testcc, (xchar)viz_rmin[row], row,
                                  (struct permonst *) 0) &&
                           !cansee(testcc.x, testcc.y) &&
                           couldsee(testcc.x, testcc.y)) {
                    max_distance = dd;
                    *startp = testcc;
                }
            }
            dd = distu(viz_rmax[row],row);
            if (dd > max_distance) {
                if (lax) {
                    max_distance = dd;
                    startp->y = row;
                    startp->x = viz_rmax[row];

                } else if (enexto(&testcc, (xchar)viz_rmax[row], row,
                                  (struct permonst *) 0) &&
                           !cansee(testcc.x,testcc.y) &&
                           couldsee(testcc.x, testcc.y)) {

                    max_distance = dd;
                    *startp = testcc;
                }
            }
        }
    }

    if (max_distance < 0) {
        if (!lax) {
            lax = 1;		/* just find a position */
            goto retry;
        }
        return FALSE;
    }

    return TRUE;
}