Esempio n. 1
0
/* the sounds of distressed pets */
void
whimper(struct monst *mtmp)
{
    const char *whimper_verb = 0;

    if (mtmp->msleeping || !mtmp->mcanmove || !mtmp->data->msound ||
        !canhear())
        return;

    /* presumably nearness checks have already been made */
    if (Hallucination)
        whimper_verb = h_sounds[rn2(SIZE(h_sounds))];
    else
        switch (mtmp->data->msound) {
        case MS_MEW:
        case MS_GROWL:
            whimper_verb = "whimper";
            break;
        case MS_BARK:
            whimper_verb = "whine";
            break;
        case MS_SQEEK:
            whimper_verb = "squeal";
            break;
        }
    if (whimper_verb) {
        pline("%s %s.", Monnam(mtmp), vtense(NULL, whimper_verb));
        action_interrupted();
        wake_nearto(mtmp->mx, mtmp->my, mtmp->data->mlevel * 6);
    }
}
Esempio n. 2
0
/*
 * Generates capitalized entity name, makes 2nd -> 3rd person conversion on
 * verb, where necessary.
 */
static const char *E_phrase(struct entity *etmp, const char *verb)
{
	static char wholebuf[80];

	strcpy(wholebuf, is_u(etmp) ? "You" : Monnam(etmp->emon));
	if (!*verb) return wholebuf;
	strcat(wholebuf, " ");
	if (is_u(etmp))
	    strcat(wholebuf, verb);
	else
	    strcat(wholebuf, vtense(NULL, verb));
	return wholebuf;
}
Esempio n. 3
0
/* the sounds of a seriously abused pet, including player attacking it */
void growl(struct monst *mtmp)
{
    const char *growl_verb = 0;

    if (mtmp->msleeping || !mtmp->mcanmove || !mtmp->data->msound)
	return;

    /* presumably nearness and soundok checks have already been made */
    if (Hallucination)
	growl_verb = h_sounds[rn2(SIZE(h_sounds))];
    else
	growl_verb = growl_sound(mtmp);
    if (growl_verb) {
	pline("%s %s!", Monnam(mtmp), vtense(NULL, growl_verb));
	if (flags.run) nomul(0, NULL);
	wake_nearto(mtmp->mx, mtmp->my, mtmp->data->mlevel * 18);
    }
}
Esempio n. 4
0
/* the sounds of mistreated pets */
void
yelp(struct monst *mtmp)
{
    const char *yelp_verb = 0;

    if (mtmp->msleeping || !mtmp->mcanmove || !mtmp->data->msound ||
        !canhear())
        return;

    /* presumably nearness checks have already been made */
    if (Hallucination)
        yelp_verb = h_sounds[rn2(SIZE(h_sounds))];
    else
        switch (mtmp->data->msound) {
        case MS_MEW:
            yelp_verb = "yowl";
            break;
        case MS_BARK:
        case MS_GROWL:
            yelp_verb = "yelp";
            break;
        case MS_ROAR:
            yelp_verb = "snarl";
            break;
        case MS_SQEEK:
            yelp_verb = "squeal";
            break;
        case MS_SQAWK:
            yelp_verb = "screak";
            break;
        case MS_WAIL:
            yelp_verb = "wail";
            break;
        }
    if (yelp_verb) {
        pline("%s %s!", Monnam(mtmp), vtense(NULL, yelp_verb));
        action_interrupted();
        wake_nearto(mtmp->mx, mtmp->my, mtmp->data->mlevel * 12);
    }
}
Esempio n. 5
0
static void break_armor(void)
{
    struct obj *otmp;

    if (breakarm(youmonst.data)) {
	if ((otmp = uarm) != 0) {
		if (donning(otmp)) cancel_don();
		pline("You break out of your armor!");
		exercise(A_STR, FALSE);
		Armor_gone();
		useup(otmp);
	}
	if ((otmp = uarmc) != 0) {
	    if (otmp->oartifact) {
		pline("Your %s falls off!", cloak_simple_name(otmp));
		Cloak_off();
		dropx(otmp);
	    } else {
		pline("Your %s tears apart!", cloak_simple_name(otmp));
		Cloak_off();
		useup(otmp);
	    }
	}
	if (uarmu) {
		pline("Your shirt rips to shreds!");
		useup(uarmu);
	}
    } else if (sliparm(youmonst.data)) {
	if (((otmp = uarm) != 0) && (racial_exception(&youmonst, otmp) < 1)) {
		if (donning(otmp)) cancel_don();
		pline("Your armor falls around you!");
		Armor_gone();
		dropx(otmp);
	}
	if ((otmp = uarmc) != 0) {
		if (is_whirly(youmonst.data))
			pline("Your %s falls, unsupported!", cloak_simple_name(otmp));
		else pline("You shrink out of your %s!", cloak_simple_name(otmp));
		Cloak_off();
		dropx(otmp);
	}
	if ((otmp = uarmu) != 0) {
		if (is_whirly(youmonst.data))
			pline("You seep right through your shirt!");
		else pline("You become much too small for your shirt!");
		setworn(NULL, otmp->owornmask & W_ARMU);
		dropx(otmp);
	}
    }
    if (has_horns(youmonst.data)) {
	if ((otmp = uarmh) != 0) {
	    if (is_flimsy(otmp) && !donning(otmp)) {
		char hornbuf[BUFSZ], yourbuf[BUFSZ];

		/* Future possiblities: This could damage/destroy helmet */
		sprintf(hornbuf, "horn%s", plur(num_horns(youmonst.data)));
		pline("Your %s %s through %s %s.", hornbuf, vtense(hornbuf, "pierce"),
		     shk_your(yourbuf, otmp), xname(otmp));
	    } else {
		if (donning(otmp)) cancel_don();
		pline("Your helmet falls to the %s!", surface(u.ux, u.uy));
		Helmet_off();
		dropx(otmp);
	    }
	}
    }
    if (nohands(youmonst.data) || verysmall(youmonst.data)) {
	if ((otmp = uarmg) != 0) {
	    if (donning(otmp)) cancel_don();
	    /* Drop weapon along with gloves */
	    pline("You drop your gloves%s!", uwep ? " and weapon" : "");
	    drop_weapon(0);
	    Gloves_off();
	    dropx(otmp);
	}
	if ((otmp = uarms) != 0) {
	    pline("You can no longer hold your shield!");
	    Shield_off();
	    dropx(otmp);
	}
	if ((otmp = uarmh) != 0) {
	    if (donning(otmp)) cancel_don();
	    pline("Your helmet falls to the %s!", surface(u.ux, u.uy));
	    Helmet_off();
	    dropx(otmp);
	}
    }
    if (nohands(youmonst.data) || verysmall(youmonst.data) ||
		slithy(youmonst.data) || youmonst.data->mlet == S_CENTAUR) {
	if ((otmp = uarmf) != 0) {
	    if (donning(otmp)) cancel_don();
	    if (is_whirly(youmonst.data))
		pline("Your boots fall away!");
	    else pline("Your boots %s off your feet!",
			verysmall(youmonst.data) ? "slide" : "are pushed");
	    Boots_off();
	    dropx(otmp);
	}
    }
}
Esempio n. 6
0
/* called when someone is being hit by Magicbane */
static boolean magicbane_hit(
    struct monst *magr,		/* attacker */
    struct monst *mdef,		/* defender */
    struct obj *mb,		/* Magicbane */
    int *dmgptr,		/* extra damage target will suffer */
    int dieroll,		/* d20 that has already scored a hit */
    boolean vis,		/* whether the action can be seen */
    char *hittee		/* target's name: "you" or mon_nam(mdef) */
    )
{
    const struct permonst *old_uasmon;
    const char *verb;
    boolean youattack = (magr == &youmonst),
	    youdefend = (mdef == &youmonst),
	    resisted = FALSE, do_stun, do_confuse, result;
    int attack_indx, scare_dieroll = MB_MAX_DIEROLL / 2;

    result = FALSE;		/* no message given yet */
    /* the most severe effects are less likely at higher enchantment */
    if (mb->spe >= 3)
	scare_dieroll /= (1 << (mb->spe / 3));
    /* if target successfully resisted the artifact damage bonus,
       reduce overall likelihood of the assorted special effects */
    if (!spec_dbon_applies) dieroll += 1;

    /* might stun even when attempting a more severe effect, but
       in that case it will only happen if the other effect fails;
       extra damage will apply regardless; 3.4.1: sometimes might
       just probe even when it hasn't been enchanted */
    do_stun = (max(mb->spe,0) < rn2(spec_dbon_applies ? 11 : 7));

    /* the special effects also boost physical damage; increments are
       generally cumulative, but since the stun effect is based on a
       different criterium its damage might not be included; the base
       damage is either 1d4 (athame) or 2d4 (athame+spec_dbon) depending
       on target's resistance check against AD_STUN (handled by caller)
       [note that a successful save against AD_STUN doesn't actually
       prevent the target from ending up stunned] */
    attack_indx = MB_INDEX_PROBE;
    *dmgptr += rnd(4);			/* (2..3)d4 */
    if (do_stun) {
	attack_indx = MB_INDEX_STUN;
	*dmgptr += rnd(4);		/* (3..4)d4 */
    }
    if (dieroll <= scare_dieroll) {
	attack_indx = MB_INDEX_SCARE;
	*dmgptr += rnd(4);		/* (3..5)d4 */
    }
    if (dieroll <= (scare_dieroll / 2)) {
	attack_indx = MB_INDEX_CANCEL;
	*dmgptr += rnd(4);		/* (4..6)d4 */
    }

    /* give the hit message prior to inflicting the effects */
    verb = mb_verb[!!Hallucination][attack_indx];
    if (youattack || youdefend || vis) {
	result = TRUE;
	pline("The magic-absorbing blade %s %s!",
		  vtense(NULL, verb), hittee);
	/* assume probing has some sort of noticeable feedback
	   even if it is being done by one monster to another */
	if (attack_indx == MB_INDEX_PROBE && !canspotmon(mdef))
	    map_invisible(mdef->mx, mdef->my);
    }

    /* now perform special effects */
    switch (attack_indx) {
    case MB_INDEX_CANCEL:
	old_uasmon = youmonst.data;
	/* No mdef->mcan check: even a cancelled monster can be polymorphed
	 * into a golem, and the "cancel" effect acts as if some magical
	 * energy remains in spellcasting defenders to be absorbed later.
	 */
	if (!cancel_monst(mdef, mb, youattack, FALSE, FALSE)) {
	    resisted = TRUE;
	} else {
	    do_stun = FALSE;
	    if (youdefend) {
		if (youmonst.data != old_uasmon)
		    *dmgptr = 0;    /* rehumanized, so no more damage */
		if (u.uenmax > 0) {
		    pline("You lose magical energy!");
		    u.uenmax--;
		    if (u.uen > 0) u.uen--;
		    iflags.botl = 1;
		}
	    } else {
		if (mdef->data == &mons[PM_CLAY_GOLEM])
		    mdef->mhp = 1;	/* cancelled clay golems will die */
		if (youattack && attacktype(mdef->data, AT_MAGC)) {
		    pline("You absorb magical energy!");
		    u.uenmax++;
		    u.uen++;
		    iflags.botl = 1;
		}
	    }
	}
	break;

    case MB_INDEX_SCARE:
	if (youdefend) {
	    if (Antimagic) {
		resisted = TRUE;
	    } else {
		nomul(-3, "being scared stiff");
		nomovemsg = "";
		if (magr && magr == u.ustuck && sticks(youmonst.data)) {
		    u.ustuck = NULL;
		    pline("You release %s!", mon_nam(magr));
		}
	    }
	} else {
	    if (rn2(2) && resist(mdef, WEAPON_CLASS, 0, NOTELL))
		resisted = TRUE;
	    else
		monflee(mdef, 3, FALSE, (mdef->mhp > *dmgptr));
	}
	if (!resisted) do_stun = FALSE;
	break;

    case MB_INDEX_STUN:
	do_stun = TRUE;		/* (this is redundant...) */
	break;

    case MB_INDEX_PROBE:
	if (youattack && (mb->spe == 0 || !rn2(3 * abs(mb->spe)))) {
	    pline("The %s is insightful.", verb);
	    /* pre-damage status */
	    probe_monster(mdef);
	}
	break;
    }
    /* stun if that was selected and a worse effect didn't occur */
    if (do_stun) {
	if (youdefend)
	    make_stunned((HStun + 3), FALSE);
	else
	    mdef->mstun = 1;
	/* avoid extra stun message below if we used mb_verb["stun"] above */
	if (attack_indx == MB_INDEX_STUN) do_stun = FALSE;
    }
    /* lastly, all this magic can be confusing... */
    do_confuse = !rn2(12);
    if (do_confuse) {
	if (youdefend)
	    make_confused(HConfusion + 4, FALSE);
	else
	    mdef->mconf = 1;
    }

    if (youattack || youdefend || vis) {
	upstart(hittee);	/* capitalize */
	if (resisted) {
	    pline("%s %s!", hittee, vtense(hittee, "resist"));
	    shieldeff(youdefend ? u.ux : mdef->mx,
		      youdefend ? u.uy : mdef->my);
	}
	if ((do_stun || do_confuse) && flags.verbose) {
	    char buf[BUFSZ];

	    buf[0] = '\0';
	    if (do_stun) strcat(buf, "stunned");
	    if (do_stun && do_confuse) strcat(buf, " and ");
	    if (do_confuse) strcat(buf, "confused");
	    pline("%s %s %s%c", hittee, vtense(hittee, "are"),
		  buf, (do_stun && do_confuse) ? '!' : '.');
	}
    }

    return result;
}