Ejemplo n.º 1
0
boolean
inside_gas_cloud(void *p1, void *p2)
{
    struct region *reg;
    struct monst *mtmp;
    long dam;

    reg = (struct region *)p1;
    dam = (long)reg->arg;
    if (p2 == NULL) {   /* This means *YOU* Bozo! */
        if (nonliving(youmonst.data) || u.uinvulnerable)
            return FALSE;
        /* If you will unblind next turn, extend the blindness so that you do
         * not get a "You can see again!" message immediately before being
         * blinded again. */
        if (!Blind || Blinded == 1)
            make_blinded(2L, FALSE);
        if (Breathless)
            return FALSE;
        if (!Poison_resistance) {
            pline("Something is burning your %s!", makeplural(body_part(LUNG)));
            pline("You cough and spit blood!");
            losehp(rnd(dam) + 5, killer_msg(DIED, "a gas cloud"));
            return FALSE;
        } else {
            pline("You cough!");
            return FALSE;
        }
    } else {    /* A monster is inside the cloud */
        mtmp = (struct monst *)p2;

        /* Non living and non breathing monsters are not concerned */
        if (!nonliving(mtmp->data) && !breathless(mtmp->data)) {
            if (cansee(mtmp->mx, mtmp->my))
                pline("%s coughs!", Monnam(mtmp));
            setmangry(mtmp);
            if (haseyes(mtmp->data) && mtmp->mcansee) {
                mtmp->mblinded = 1;
                mtmp->mcansee = 0;
            }
            if (resists_poison(mtmp))
                return FALSE;
            mtmp->mhp -= rnd(dam) + 5;
            if (mtmp->mhp <= 0) {
                if (heros_fault(reg))
                    killed(mtmp);
                else
                    monkilled(mtmp, "gas cloud", AD_DRST);
                if (DEADMONSTER(mtmp)) {   /* not lifesaved */
                    return TRUE;
                }
            }
        }
    }
    return FALSE;       /* Monster is still alive */
}
Ejemplo n.º 2
0
static void
chest_shatter_msg(struct obj *otmp)
{
    const char *disposition;
    const char *thing;
    long save_Blinded;

    if (otmp->oclass == POTION_CLASS) {
        pline(msgc_itemloss, "You %s %s shatter!", Blind ? "hear" : "see",
              an(bottlename()));
        if (!breathless(youmonst.data) || haseyes(youmonst.data))
            potionbreathe(&youmonst, otmp);
        return;
    }
    /* We have functions for distant and singular names, but not one
       which does _both_...
       TODO: fix this blindness kludge (it doesn't even work -- see eoto) */
    save_Blinded = property_timeout(&youmonst, BLINDED);
    set_property(&youmonst, BLINDED, 1, TRUE);
    thing = singular(otmp, xname);
    if (save_Blinded)
        set_property(&youmonst, BLINDED, save_Blinded, TRUE);

    switch (objects[otmp->otyp].oc_material) {
    case PAPER:
        disposition = "is torn to shreds";
        break;
    case WAX:
        disposition = "is crushed";
        break;
    case VEGGY:
        disposition = "is pulped";
        break;
    case FLESH:
        disposition = "is mashed";
        break;
    case GLASS:
        disposition = "shatters";
        break;
    case WOOD:
        disposition = "splinters to fragments";
        break;
    default:
        disposition = "is destroyed";
        break;
    }
    pline(msgc_itemloss, "%s %s!", An(thing), disposition);
}
Ejemplo n.º 3
0
void polyself(boolean forcecontrol)
{
	char buf[BUFSZ];
	int old_light, new_light;
	int mntmp = NON_PM;
	int tries=0;
	boolean draconian = (uarm &&
				uarm->otyp >= GRAY_DRAGON_SCALE_MAIL &&
				uarm->otyp <= YELLOW_DRAGON_SCALES);
	boolean iswere = (u.ulycn >= LOW_PM || is_were(youmonst.data));
	boolean isvamp = (youmonst.data->mlet == S_VAMPIRE || u.umonnum == PM_VAMPIRE_BAT);
	boolean was_floating = (Levitation || Flying);

        if (!Polymorph_control && !forcecontrol && !draconian && !iswere && !isvamp) {
	    if (rn2(20) > ACURR(A_CON)) {
		pline("You shudder for a moment.");
		losehp(rnd(30), "system shock", KILLED_BY_AN);
		exercise(A_CON, FALSE);
		return;
	    }
	}
	old_light = Upolyd ? emits_light(youmonst.data) : 0;

	if (Polymorph_control || forcecontrol) {
		do {
			getlin("Become what kind of monster? [type the name]",
				buf);
			mntmp = name_to_mon(buf);
			if (mntmp < LOW_PM)
				pline("I've never heard of such monsters.");
			/* Note:  humans are illegal as monsters, but an
			 * illegal monster forces newman(), which is what we
			 * want if they specified a human.... */
			else if (!polyok(&mons[mntmp]) && !your_race(&mons[mntmp]))
				pline("You cannot polymorph into that.");
			else break;
		} while (++tries < 5);
		if (tries==5) pline("That's enough tries!");
		/* allow skin merging, even when polymorph is controlled */
		if (draconian &&
		    (mntmp == armor_to_dragon(uarm->otyp) || tries == 5))
		    goto do_merge;
	} else if (draconian || iswere || isvamp) {
		/* special changes that don't require polyok() */
		if (draconian) {
		    do_merge:
			mntmp = armor_to_dragon(uarm->otyp);
			if (!(mvitals[mntmp].mvflags & G_GENOD)) {
				/* allow G_EXTINCT */
				pline("You merge with your scaly armor.");
				uskin = uarm;
				uarm = NULL;
				/* save/restore hack */
				uskin->owornmask |= I_SPECIAL;
			}
		} else if (iswere) {
			if (is_were(youmonst.data))
				mntmp = PM_HUMAN; /* Illegal; force newman() */
			else
				mntmp = u.ulycn;
		} else {
			if (youmonst.data->mlet == S_VAMPIRE)
				mntmp = PM_VAMPIRE_BAT;
			else
				mntmp = PM_VAMPIRE;
		}
		/* if polymon fails, "you feel" message has been given
		   so don't follow up with another polymon or newman */
		if (mntmp == PM_HUMAN) newman();	/* werecritter */
		else polymon(mntmp);
		goto made_change;    /* maybe not, but this is right anyway */
	}

	if (mntmp < LOW_PM) {
		tries = 0;
		do {
			/* randomly pick an "ordinary" monster */
			mntmp = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
		} while ((!polyok(&mons[mntmp]) || is_placeholder(&mons[mntmp]))
				&& tries++ < 200);
	}

	/* The below polyok() fails either if everything is genocided, or if
	 * we deliberately chose something illegal to force newman().
	 */
	if (!polyok(&mons[mntmp]) || !rn2(5) || your_race(&mons[mntmp]))
		newman();
	else if (!polymon(mntmp)) return;

	if (!uarmg) selftouch("No longer petrify-resistant, you");

 made_change:
	new_light = Upolyd ? emits_light(youmonst.data) : 0;
	if (old_light != new_light) {
	    if (old_light)
		del_light_source(level, LS_MONSTER, &youmonst);
	    if (new_light == 1) ++new_light;  /* otherwise it's undetectable */
	    if (new_light)
		new_light_source(level, u.ux, u.uy, new_light,
				 LS_MONSTER, &youmonst);
	}
	if (is_pool(level, u.ux,u.uy) && was_floating && !(Levitation || Flying) &&
		!breathless(youmonst.data) && !amphibious(youmonst.data) &&
		!Swimming) drown();
}