Example #1
0
long
bribe(struct monst *mtmp)
{
    const char *buf;
    long offer;
    long umoney = money_cnt(invent);

    buf = getlin("How much will you offer?", FALSE);
    if (sscanf(buf, "%ld", &offer) != 1)
        offer = 0L;

    /* Michael Paddon -- fix for negative offer to monster */
    /* JAR880815 - */
    if (offer < 0L) {
        pline("You try to shortchange %s, but fumble.", mon_nam(mtmp));
        return 0L;
    } else if (offer == 0L) {
        pline("You refuse.");
        return 0L;
    } else if (umoney == 0L) {
        pline("You open your purse, but realize you have no gold.");
        return 0L;
    } else if (offer >= umoney) {
        pline("You give %s all your gold.", mon_nam(mtmp));
        offer = umoney;
    } else {
        pline("You give %s %ld %s.", mon_nam(mtmp), offer, currency(offer));
    }
    money2mon(mtmp, offer);

    return offer;
}
Example #2
0
long
bribe(struct monst *mtmp)
{
    char buf[BUFSZ];
    long offer;
    long umoney = money_cnt(invent);

    getlin("How much will you offer?", buf);
    if (sscanf(buf, "%ld", &offer) != 1)
        offer = 0L;

    /* Michael Paddon -- fix for negative offer to monster */
    /* JAR880815 - */
    if (offer < 0L) {
        pline("You try to shortchange %s, but fumble.", mon_nam(mtmp));
        return 0L;
    } else if (offer == 0L) {
        pline("You refuse.");
        return 0L;
    } else if (offer >= umoney) {
        pline("You give %s all your gold.", mon_nam(mtmp));
        offer = umoney;
    } else {
        pline("You give %s %ld %s.", mon_nam(mtmp), offer, currency(offer));
    }
    money2mon(mtmp, offer);

    iflags.botl = 1;
    return offer;
}
Example #3
0
/*  cutoff()
*
*  Remove the tail of a worm and adjust the hp of the worm.
*/
static void cutoff(struct monst *worm, struct wseg *tail)
{
    if (flags.mon_moving)
	pline("Part of the tail of %s is cut off.", mon_nam(worm));
    else
	pline("You cut part of the tail off of %s.", mon_nam(worm));
    toss_wsegs(level, tail, TRUE);
    if (worm->mhp > 1)
	worm->mhp /= 2;
}
Example #4
0
static boolean artifact_hit_drainlife(struct monst *magr, struct monst *mdef,
				      struct obj *otmp, int *dmgptr)
{
    boolean youattack = (magr == &youmonst);
    boolean youdefend = (mdef == &youmonst);
    boolean vis = (!youattack && magr && cansee(magr->mx, magr->my))
	|| (!youdefend && cansee(mdef->mx, mdef->my))
	|| (youattack && u.uswallow && mdef == u.ustuck && !Blind);
	
    if (!youdefend) {
	    if (vis) {
		if (otmp->oartifact == ART_STORMBRINGER)
		    pline("The %s blade draws the life from %s!",
			    hcolor("black"),
			    mon_nam(mdef));
		else
		    pline("%s draws the life from %s!",
			    The(distant_name(otmp, xname)),
			    mon_nam(mdef));
	    }
	    if (mdef->m_lev == 0) {
		*dmgptr = 2 * mdef->mhp + FATAL_DAMAGE_MODIFIER;
	    } else {
		int drain = rnd(8);
		*dmgptr += drain;
		mdef->mhpmax -= drain;
		mdef->m_lev--;
		drain /= 2;
		if (drain) healup(drain, 0, FALSE, FALSE);
	    }
	    return vis;
    } else { /* youdefend */
	    int oldhpmax = u.uhpmax;

	    if (Blind)
		    pline("You feel an %s drain your life!",
			otmp->oartifact == ART_STORMBRINGER ?
			"unholy blade" : "object");
	    else if (otmp->oartifact == ART_STORMBRINGER)
		    pline("The %s blade drains your life!",
			    hcolor("black"));
	    else
		    pline("%s drains your life!",
			    The(distant_name(otmp, xname)));
	    losexp("life drainage");
	    if (magr && magr->mhp < magr->mhpmax) {
		magr->mhp += (oldhpmax - u.uhpmax)/2;
		if (magr->mhp > magr->mhpmax) magr->mhp = magr->mhpmax;
	    }
	    return TRUE;
    }
    return FALSE;
}
Example #5
0
char *Monnam(const struct monst *mtmp)
{
	char *bp = mon_nam(mtmp);

	*bp = highc(*bp);
	return bp;
}
Example #6
0
/* Assign a name to a monster, taken from a list of possible names.
   Note that shopkeepers are special and use nameshk instead, partly
   because it contains additional logic peculiar to them and also
   because their name is stored in ESHK because of reasons. */
static void
namemonsterfromlist(struct monst *mon, const char *const *nlist,
                    struct level *lev, boolean unique)
{
    int names_avail, tryct;
    const char *ourname;
    struct monst *mtmp;
    if (!mon) {
        if (wizard)
            impossible("Cannot name a non-existent monster.");
        return;
    }
    if (!nlist[0]) {
        if (wizard)
            impossible("No names available for the %s.", mon_nam(mon));
        return;
    }
    for (names_avail = 0; nlist[names_avail]; names_avail++)
        ;
    for (tryct = 0; tryct < 500; tryct++) {
        ourname = nlist[rn2(names_avail)];
        if (!unique) {
            christen_monst(mon, ourname);
            return;
        }
        for (mtmp = lev->monlist; mtmp; mtmp = mtmp->nmon) {
            if (DEADMONSTER(mtmp) || (mtmp == mon) ||
                !(mtmp->data->mlet == mon->data->mlet))
                continue;
            if (strcmp(NAME_MUTABLE(mtmp), ourname) != 0)
                continue;
            break;
        }
        if (!mtmp) {
            christen_monst(mon, ourname);
            return;
        } 
    }
    /* We're not going to name this monster. */
    if (wizard)
        pline("Failed to find %s name for the %s.",
              (unique ? "an unused" : "a"), mon_nam(mon));
}
Example #7
0
boolean tele_restrict(struct monst *mon)
{
	if (level->flags.noteleport) {
		if (canseemon(mon))
		    pline("A mysterious force prevents %s from teleporting!",
			mon_nam(mon));
		return TRUE;
	}
	return FALSE;
}
int
tele_impl(boolean wizard_tele, boolean run_next_to_u)
{
    coord cc;

    /* Disable teleportation in stronghold && Vlad's Tower */
    if (level->flags.noteleport) {
        if (!wizard_tele) {
            pline("A mysterious force prevents you from teleporting!");
            return 1;
        }
    }

    /* don't show trap if "Sorry..." */
    if (!Blinded)
        make_blinded(0L, FALSE);

    /* when it happens at all, happens too often to be worth a custom RNG */
    if ((Uhave_amulet || On_W_tower_level(&u.uz)) && !rn2(3)) {
        pline("You feel disoriented for a moment.");
        return 1;
    }
    if ((Teleport_control && !Stunned) || wizard_tele) {
        if (u_helpless(hm_unconscious)) {
            pline("Being unconscious, you cannot control your teleport.");
        } else {
            pline("To what position do you%s want to be teleported?",
                  u.usteed ? msgcat(" and ", mon_nam(u.usteed)) : "");
            cc.x = u.ux;
            cc.y = u.uy;
            if (getpos(&cc, FALSE, "the desired position", FALSE)
                == NHCR_CLIENT_CANCEL)
                return 0; /* abort */

            if (run_next_to_u) {
                if (!next_to_u()) {
                    pline("You shudder for a moment.");
                    return 1;
                }
            }

            /* possible extensions: introduce a small error if magic power is
               low; allow transfer to solid rock */
            if (u_teleok(cc.x, cc.y, FALSE, wizard_tele)) {
                teleds(cc.x, cc.y, FALSE);
                return 1;
            }
            pline("Sorry...");
        }
    }

    safe_teleds(FALSE);
    return 1;
}
Example #9
0
void
tele(void)
{
    coord cc;

    /* Disable teleportation in stronghold && Vlad's Tower */
    if (level->flags.noteleport) {
        if (!wizard) {
            pline("A mysterious force prevents you from teleporting!");
            return;
        }
    }

    /* don't show trap if "Sorry..." */
    if (!Blinded)
        make_blinded(0L, FALSE);

    if ((u.uhave.amulet || On_W_tower_level(&u.uz)) && !rn2(3)) {
        pline("You feel disoriented for a moment.");
        return;
    }
    if ((Teleport_control && !Stunned) || wizard) {
        if (unconscious()) {
            pline("Being unconscious, you cannot control your teleport.");
        } else {
            char buf[BUFSZ];

            if (u.usteed)
                sprintf(buf, " and %s", mon_nam(u.usteed));
            pline("To what position do you%s want to be teleported?",
                  u.usteed ? buf : "");
            cc.x = u.ux;
            cc.y = u.uy;
            if (getpos(&cc, TRUE, "the desired position") < 0)
                return; /* abort */
            /* possible extensions: introduce a small error if magic power is
               low; allow transfer to solid rock */
            if (teleok(cc.x, cc.y, FALSE)) {
                teleds(cc.x, cc.y, FALSE);
                return;
            }
            pline("Sorry...");
        }
    }

    safe_teleds(FALSE);
}
Example #10
0
void
quest_chat(struct monst *mtmp)
{
    if (mtmp->m_id == Qstat(leader_m_id)) {
        chat_with_leader();
        return;
    }
    switch (mtmp->data->msound) {
    case MS_NEMESIS:
        chat_with_nemesis();
        break;
    case MS_GUARDIAN:
        chat_with_guardian();
        break;
    default:
        impossible("quest_chat: Unknown quest character %s.", mon_nam(mtmp));
    }
}
Example #11
0
/* you teleport a monster (via wand, spell, or poly'd q.mechanic attack);
   return false iff the attempt fails */
boolean u_teleport_mon(struct monst *mtmp, boolean give_feedback)
{
	coord cc;

	if (mtmp->ispriest && *in_rooms(level, mtmp->mx, mtmp->my, TEMPLE)) {
	    if (give_feedback)
		pline("%s resists your magic!", Monnam(mtmp));
	    return FALSE;
	} else if (level->flags.noteleport && u.uswallow && mtmp == u.ustuck) {
	    if (give_feedback)
		pline("You are no longer inside %s!", mon_nam(mtmp));
	    unstuck(mtmp);
	    rloc(mtmp, FALSE);
	} else if (is_rider(mtmp->data) && rn2(13) &&
		   enexto(&cc, level, u.ux, u.uy, mtmp->data))
	    rloc_to(mtmp, cc.x, cc.y);
	else
	    rloc(mtmp, FALSE);
	return TRUE;
}
Example #12
0
int
spitmq(struct monst *mtmp, int xdef, int ydef, const struct attack *mattk)
{
    struct obj *otmp;

    if (mtmp->mcan) {
        if (canhear())
            pline("A dry rattle comes from %s throat.",
                  s_suffix(mon_nam(mtmp)));
        return 0;
    }
    boolean linedup = qlined_up(mtmp, xdef, ydef, FALSE, FALSE);
    if (linedup && ai_use_at_range(
            BOLT_LIM - distmin(mtmp->mx, mtmp->my, xdef, ydef))) {
        switch (mattk->adtyp) {
        case AD_BLND:
        case AD_DRST:
            otmp = mktemp_sobj(level, BLINDING_VENOM);
            break;
        case AD_DRLI:
            otmp = mktemp_sobj(level, VAMPIRE_BLOOD);
            break;
        default:
            impossible("bad attack type in spitm");
            /* fall through */
        case AD_ACID:
            otmp = mktemp_sobj(level, ACID_VENOM);
            break;
        }

        if (mon_visible(mtmp)) {
            pline("%s spits venom!", Monnam(mtmp));
            action_interrupted();
        }
        m_throw(mtmp, mtmp->mx, mtmp->my, sgn(tbx), sgn(tby),
                distmin(mtmp->mx, mtmp->my, xdef, ydef), otmp,
                FALSE);
        return 1;
    }
    return 0;
}
Example #13
0
/*
 * pri_move: return 1: moved  0: didn't  -1: let m_move do it  -2: died
 */
int
pri_move(struct monst *priest)
{
    xchar gx, gy, omx, omy;
    schar temple;
    boolean avoid = TRUE;

    omx = priest->mx;
    omy = priest->my;

    if (!histemple_at(priest, omx, omy))
        return -1;

    temple = CONST_EPRI(priest)->shroom;

    gx = CONST_EPRI(priest)->shrpos.x;
    gy = CONST_EPRI(priest)->shrpos.y;

    gx += rn1(3, -1);   /* mill around the altar */
    gy += rn1(3, -1);

    if (!priest->mpeaceful || (Conflict && !resist(priest, RING_CLASS, 0, 0))) {
        if (monnear(priest, u.ux, u.uy)) {
            if (Displaced)
                pline("Your displaced image doesn't fool %s!", mon_nam(priest));
            mattacku(priest);
            return 0;
        } else if (strchr(u.urooms, temple)) {
            /* chase player if inside temple & can sense him */
            if (m_cansenseu(priest)) {
                gx = u.ux;
                gy = u.uy;
            }
            avoid = FALSE;
        }
    } else if (Invis)
        avoid = FALSE;

    return move_special(priest, FALSE, TRUE, FALSE, avoid, omx, omy, gx, gy);
}
Example #14
0
int domindblast(void)
{
	struct monst *mtmp, *nmon;

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

	pline("You concentrate.");
	pline("A wave of psychic energy pours out.");
	for (mtmp=level->monlist; 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)) {
			pline("You lock in on %s %s.", 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;
}
Example #15
0
/* returns 1 if polymorph successful */
int polymon(int mntmp)
{
	boolean sticky = sticks(youmonst.data) && u.ustuck && !u.uswallow,
		was_blind = !!Blind, dochange = FALSE;
	boolean could_pass_walls = Passes_walls;
	int mlvl;

	if (mvitals[mntmp].mvflags & G_GENOD) {	/* allow G_EXTINCT */
		pline("You feel rather %s-ish.",mons[mntmp].mname);
		exercise(A_WIS, TRUE);
		return 0;
	}

	/* KMH, conduct */
	u.uconduct.polyselfs++;

	if (!Upolyd) {
		/* Human to monster; save human stats */
		u.macurr = u.acurr;
		u.mamax = u.amax;
		u.mfemale = flags.female;
	} else {
		/* Monster to monster; restore human stats, to be
		 * immediately changed to provide stats for the new monster
		 */
		u.acurr = u.macurr;
		u.amax = u.mamax;
		flags.female = u.mfemale;
	}

	if (youmonst.m_ap_type) {
	    /* stop mimicking immediately */
	    if (multi < 0) unmul("");
	} else if (mons[mntmp].mlet != S_MIMIC) {
	    /* as in polyman() */
	    youmonst.m_ap_type = M_AP_NOTHING;
	}
	if (is_male(&mons[mntmp])) {
		if (flags.female) dochange = TRUE;
	} else if (is_female(&mons[mntmp])) {
		if (!flags.female) dochange = TRUE;
	} else if (!is_neuter(&mons[mntmp]) && mntmp != u.ulycn) {
		if (!rn2(10)) dochange = TRUE;
	}
	if (dochange) {
		flags.female = !flags.female;
		pline("You %s %s%s!",
		    (u.umonnum != mntmp) ? "turn into a" : "feel like a new",
		    (is_male(&mons[mntmp]) || is_female(&mons[mntmp])) ? "" :
			flags.female ? "female " : "male ",
		    mons[mntmp].mname);
	} else {
		if (u.umonnum != mntmp)
			pline("You turn into %s!", an(mons[mntmp].mname));
		else
			pline("You feel like a new %s!", mons[mntmp].mname);
	}
	if (Stoned && poly_when_stoned(&mons[mntmp])) {
		/* poly_when_stoned already checked stone golem genocide */
		pline("You turn to stone!");
		mntmp = PM_STONE_GOLEM;
		Stoned = 0;
		delayed_killer = 0;
	}

	u.mtimedone = rn1(500, 500);
	u.umonnum = mntmp;
	set_uasmon();

	/* New stats for monster, to last only as long as polymorphed.
	 * Currently only strength gets changed.
	 */
	if (strongmonst(&mons[mntmp])) ABASE(A_STR) = AMAX(A_STR) = STR18(100);

	if (Stone_resistance && Stoned) { /* [email protected] */
		Stoned = 0;
		delayed_killer = 0;
		pline("You no longer seem to be petrifying.");
	}
	if (Sick_resistance && Sick) {
		make_sick(0L, NULL, FALSE, SICK_ALL);
		pline("You no longer feel sick.");
	}
	if (Slimed) {
	    if (flaming(youmonst.data)) {
		pline("The slime burns away!");
		Slimed = 0L;
		iflags.botl = 1;
	    } else if (mntmp == PM_GREEN_SLIME) {
		/* do it silently */
		Slimed = 0L;
		iflags.botl = 1;
	    }
	}
	if (nohands(youmonst.data)) Glib = 0;

	/*
	mlvl = adj_lev(&mons[mntmp]);
	 * We can't do the above, since there's no such thing as an
	 * "experience level of you as a monster" for a polymorphed character.
	 */
	mlvl = (int)mons[mntmp].mlevel;
	if (youmonst.data->mlet == S_DRAGON && mntmp >= PM_GRAY_DRAGON) {
		u.mhmax = In_endgame(&u.uz) ? (8*mlvl) : (4*mlvl + dice(mlvl,4));
	} else if (is_golem(youmonst.data)) {
		u.mhmax = golemhp(mntmp);
	} else {
		if (!mlvl) u.mhmax = rnd(4);
		else u.mhmax = dice(mlvl, 8);
		if (is_home_elemental(&u.uz, &mons[mntmp])) u.mhmax *= 3;
	}
	u.mh = u.mhmax;

	if (u.ulevel < mlvl) {
	/* Low level characters can't become high level monsters for long */
		u.mtimedone = u.mtimedone * u.ulevel / mlvl;
	}

	if (uskin && mntmp != armor_to_dragon(uskin->otyp))
		skinback(FALSE);
	break_armor();
	drop_weapon(1);
	if (hides_under(youmonst.data))
		u.uundetected = OBJ_AT(u.ux, u.uy);
	else if (youmonst.data->mlet == S_EEL)
		u.uundetected = is_pool(level, u.ux, u.uy);
	else
		u.uundetected = 0;

	if (u.utraptype == TT_PIT) {
	    if (could_pass_walls && !Passes_walls) {
		u.utrap = rn1(6,2);
	    } else if (!could_pass_walls && Passes_walls) {
		u.utrap = 0;
	    }
	}
	if (was_blind && !Blind) {	/* previous form was eyeless */
	    Blinded = 1L;
	    make_blinded(0L, TRUE);	/* remove blindness */
	}
	newsym(u.ux,u.uy);		/* Change symbol */

	if (!sticky && !u.uswallow && u.ustuck && sticks(youmonst.data)) u.ustuck = 0;
	else if (sticky && !sticks(youmonst.data)) uunstick();
	if (u.usteed) {
	    if (touch_petrifies(u.usteed->data) &&
	    		!Stone_resistance && rnl(3)) {
	    	char buf[BUFSZ];

	    	pline("No longer petrifying-resistant, you touch %s.",
	    			mon_nam(u.usteed));
	    	sprintf(buf, "riding %s", an(u.usteed->data->mname));
	    	instapetrify(buf);
 	    }
	    if (!can_ride(u.usteed)) dismount_steed(DISMOUNT_POLY);
	}

	if (flags.verbose) {
	    static const char use_thec[] = "Use the command #%s to %s.";
	    static const char monsterc[] = "monster";
	    if (can_breathe(youmonst.data))
		pline(use_thec,monsterc,"use your breath weapon");
	    if (attacktype(youmonst.data, AT_SPIT))
		pline(use_thec,monsterc,"spit venom");
	    if (youmonst.data->mlet == S_NYMPH)
		pline(use_thec,monsterc,"remove an iron ball");
	    if (attacktype(youmonst.data, AT_GAZE))
		pline(use_thec,monsterc,"gaze at monsters");
	    if (is_hider(youmonst.data))
		pline(use_thec,monsterc,"hide");
	    if (is_were(youmonst.data))
		pline(use_thec,monsterc,"summon help");
	    if (webmaker(youmonst.data))
		pline(use_thec,monsterc,"spin a web");
	    if (u.umonnum == PM_GREMLIN)
		pline(use_thec,monsterc,"multiply in a fountain");
	    if (is_unicorn(youmonst.data))
		pline(use_thec,monsterc,"use your horn");
	    if (is_mind_flayer(youmonst.data))
		pline(use_thec,monsterc,"emit a mental blast");
	    if (youmonst.data->msound == MS_SHRIEK) /* worthless, actually */
		pline(use_thec,monsterc,"shriek");
	    if (lays_eggs(youmonst.data) && flags.female)
		pline(use_thec,"sit","lay an egg");
	}
	/* you now know what an egg of your type looks like */
	if (lays_eggs(youmonst.data)) {
	    learn_egg_type(u.umonnum);
	    /* make queen bees recognize killer bee eggs */
	    learn_egg_type(egg_type_from_parent(u.umonnum, TRUE));
	}
	find_ac();
	if ((!Levitation && !u.ustuck && !Flying &&
	    (is_pool(level, u.ux,u.uy) || is_lava(level, u.ux,u.uy))) ||
	   (Underwater && !Swimming))
	    spoteffects(TRUE);
	if (Passes_walls && u.utrap && u.utraptype == TT_INFLOOR) {
	    u.utrap = 0;
	    pline("The rock seems to no longer trap you.");
	} else if (likes_lava(youmonst.data) && u.utrap && u.utraptype == TT_LAVA) {
	    u.utrap = 0;
	    pline("The lava now feels soothing.");
	}
	if (amorphous(youmonst.data) || is_whirly(youmonst.data) || unsolid(youmonst.data)) {
	    if (Punished) {
		pline("You slip out of the iron chain.");
		unpunish();
	    }
	}
	if (u.utrap && (u.utraptype == TT_WEB || u.utraptype == TT_BEARTRAP) &&
		(amorphous(youmonst.data) || is_whirly(youmonst.data) || unsolid(youmonst.data) ||
		  (youmonst.data->msize <= MZ_SMALL && u.utraptype == TT_BEARTRAP))) {
	    pline("You are no longer stuck in the %s.",
		    u.utraptype == TT_WEB ? "web" : "bear trap");
	    /* probably should burn webs too if PM_FIRE_ELEMENTAL */
	    u.utrap = 0;
	}
	if (webmaker(youmonst.data) && u.utrap && u.utraptype == TT_WEB) {
	    pline("You orient yourself on the web.");
	    u.utrap = 0;
	}
	iflags.botl = 1;
	vision_full_recalc = 1;
	see_monsters();
	exercise(A_CON, FALSE);
	exercise(A_WIS, TRUE);
	encumber_msg();
	return 1;
}
Example #16
0
/* #sit command */
int
dosit()
{
/*JP
    static const char sit_message[] = "sit on the %s.";
*/
    static const char sit_message[] = "%sに座った.";
    register struct trap *trap = t_at(u.ux, u.uy);
    register int typ = levl[u.ux][u.uy].typ;

    if (u.usteed) {
/*JP
        You("are already sitting on %s.", mon_nam(u.usteed));
*/
        You("もう%sに座っている.", mon_nam(u.usteed));
        return 0;
    }
    if (u.uundetected && is_hider(youmonst.data) && u.umonnum != PM_TRAPPER)
        u.uundetected = 0; /* no longer on the ceiling */

    if (!can_reach_floor(FALSE)) {
        if (u.uswallow)
/*JP
            There("are no seats in here!");
*/
            pline("ここには椅子がない!");
        else if (Levitation)
/*JP
            You("tumble in place.");
*/
            You("その場で宙返りした.");
        else
/*JP
            You("are sitting on air.");
*/
            You("空中に座った.");
        return 0;
    } else if (u.ustuck && !sticks(youmonst.data)) {
        /* holding monster is next to hero rather than beneath, but
           hero is in no condition to actually sit at has/her own spot */
        if (humanoid(u.ustuck->data))
/*JP
            pline("%s won't offer %s lap.", Monnam(u.ustuck), mhis(u.ustuck));
*/
            pline("%sはひざを出さなかった.", Monnam(u.ustuck));
        else
/*JP
            pline("%s has no lap.", Monnam(u.ustuck));
*/
            pline("%sにはひざがない.", Monnam(u.ustuck));
        return 0;
    } else if (is_pool(u.ux, u.uy) && !Underwater) { /* water walking */
        goto in_water;
    }

    if (OBJ_AT(u.ux, u.uy)
        /* ensure we're not standing on the precipice */
        && !uteetering_at_seen_pit(trap)) {
        register struct obj *obj;

        obj = level.objects[u.ux][u.uy];
        if (youmonst.data->mlet == S_DRAGON && obj->oclass == COIN_CLASS) {
#if 0 /*JP*/
            You("coil up around your %shoard.",
                (obj->quan + money_cnt(invent) < u.ulevel * 1000) ? "meager "
                                                                  : "");
#else
            You("%sお宝のまわりでとぐろを巻いた.",
                (obj->quan + money_cnt(invent) < u.ulevel * 1000) ? "わずかな"
                                                                  : "");
#endif
        } else {
/*JP
            You("sit on %s.", the(xname(obj)));
*/
            You("%sに座った.", the(xname(obj)));
            if (!(Is_box(obj) || objects[obj->otyp].oc_material == CLOTH))
/*JP
                pline("It's not very comfortable...");
*/
                pline("あまり座りごこちがよくない...");
        }
    } else if (trap != 0 || (u.utrap && (u.utraptype >= TT_LAVA))) {
        if (u.utrap) {
            exercise(A_WIS, FALSE); /* you're getting stuck longer */
            if (u.utraptype == TT_BEARTRAP) {
/*JP
                You_cant("sit down with your %s in the bear trap.",
*/
                pline("%sが熊の罠にはさまっているので座れない.",
                         body_part(FOOT));
                u.utrap++;
            } else if (u.utraptype == TT_PIT) {
                if (trap && trap->ttyp == SPIKED_PIT) {
/*JP
                    You("sit down on a spike.  Ouch!");
*/
                    You("トゲの上に座った.いてっ!");
                    losehp(Half_physical_damage ? rn2(2) : 1,
/*JP
                           "sitting on an iron spike", KILLED_BY);
*/
                           "鉄のトゲの上に座って", KILLED_BY);
                    exercise(A_STR, FALSE);
                } else
/*JP
                    You("sit down in the pit.");
*/
                    You("落し穴の中で座った.");
                u.utrap += rn2(5);
            } else if (u.utraptype == TT_WEB) {
/*JP
                You("sit in the spider web and get entangled further!");
*/
                You("くもの巣の中で座ったら,ますます絡まった!");
                u.utrap += rn1(10, 5);
            } else if (u.utraptype == TT_LAVA) {
                /* Must have fire resistance or they'd be dead already */
/*JP
                You("sit in the lava!");
*/
                You("溶岩の中に座った!");
                if (Slimed)
                    burn_away_slime();
                u.utrap += rnd(4);
/*JP
                losehp(d(2, 10), "sitting in lava",
*/
                losehp(d(2, 10), "溶岩の中に座って",
                       KILLED_BY); /* lava damage */
            } else if (u.utraptype == TT_INFLOOR
                       || u.utraptype == TT_BURIEDBALL) {
/*JP
                You_cant("maneuver to sit!");
*/
                You("座るような動作ができない!");
                u.utrap++;
            }
        } else {
/*JP
            You("sit down.");
*/
            You("座った.");
            dotrap(trap, 0);
        }
    } else if (Underwater || Is_waterlevel(&u.uz)) {
        if (Is_waterlevel(&u.uz))
/*JP
            There("are no cushions floating nearby.");
*/
            pline("近くに浮いているクッションはない.");
        else
/*JP
            You("sit down on the muddy bottom.");
*/
            You("どろどろした底に座った.");
    } else if (is_pool(u.ux, u.uy)) {
    in_water:
/*JP
        You("sit in the water.");
*/
        You("水の中で座った.");
        if (!rn2(10) && uarm)
/*JP
            (void) water_damage(uarm, "armor", TRUE);
*/
            (void) water_damage(uarm, "鎧", TRUE);
        if (!rn2(10) && uarmf && uarmf->otyp != WATER_WALKING_BOOTS)
/*JP
            (void) water_damage(uarm, "armor", TRUE);
*/
            (void) water_damage(uarm, "鎧", TRUE);
    } else if (IS_SINK(typ)) {
        You(sit_message, defsyms[S_sink].explanation);
/*JP
        Your("%s gets wet.", humanoid(youmonst.data) ? "rump" : "underside");
*/
        Your("%sは濡れた.", humanoid(youmonst.data) ? "尻" : "下部");
    } else if (IS_ALTAR(typ)) {
        You(sit_message, defsyms[S_altar].explanation);
        altar_wrath(u.ux, u.uy);
    } else if (IS_GRAVE(typ)) {
        You(sit_message, defsyms[S_grave].explanation);
    } else if (typ == STAIRS) {
/*JP
        You(sit_message, "stairs");
*/
        You(sit_message, "階段");
    } else if (typ == LADDER) {
/*JP
        You(sit_message, "ladder");
*/
        You(sit_message, "はしご");
    } else if (is_lava(u.ux, u.uy)) {
        /* must be WWalking */
/*JP
        You(sit_message, "lava");
*/
        You(sit_message, "溶岩");
        burn_away_slime();
        if (likes_lava(youmonst.data)) {
/*JP
            pline_The("lava feels warm.");
*/
            pline("溶岩は暖かい.");
            return 1;
        }
/*JP
        pline_The("lava burns you!");
*/
        You("溶岩で燃えた!");
        losehp(d((Fire_resistance ? 2 : 10), 10), /* lava damage */
/*JP
               "sitting on lava", KILLED_BY);
*/
               "溶岩に座って", KILLED_BY);
    } else if (is_ice(u.ux, u.uy)) {
        You(sit_message, defsyms[S_ice].explanation);
        if (!Cold_resistance)
/*JP
            pline_The("ice feels cold.");
*/
            pline("氷は冷たく感じた.");
    } else if (typ == DRAWBRIDGE_DOWN) {
/*JP
        You(sit_message, "drawbridge");
*/
        You(sit_message, "跳ね橋");
    } else if (IS_THRONE(typ)) {
        You(sit_message, defsyms[S_throne].explanation);
        if (rnd(6) > 4) {
            switch (rnd(13)) {
            case 1:
                (void) adjattrib(rn2(A_MAX), -rn1(4, 3), FALSE);
/*JP
                losehp(rnd(10), "cursed throne", KILLED_BY_AN);
*/
                losehp(rnd(10), "呪われた玉座で", KILLED_BY_AN);
                break;
            case 2:
                (void) adjattrib(rn2(A_MAX), 1, FALSE);
                break;
            case 3:
#if 0 /*JP*/
                pline("A%s electric shock shoots through your body!",
                      (Shock_resistance) ? "n" : " massive");
#else
                pline("%s電気があなたの体を走り抜けた!",
                      (Shock_resistance) ? "" : "激しい");
#endif
/*JP
                losehp(Shock_resistance ? rnd(6) : rnd(30), "electric chair",
*/
                losehp(Shock_resistance ? rnd(6) : rnd(30), "電気椅子で",
                       KILLED_BY_AN);
                exercise(A_CON, FALSE);
                break;
            case 4:
/*JP
                You_feel("much, much better!");
*/
                You_feel("とても,とても元気になったような気がした!");
                if (Upolyd) {
                    if (u.mh >= (u.mhmax - 5))
                        u.mhmax += 4;
                    u.mh = u.mhmax;
                }
                if (u.uhp >= (u.uhpmax - 5))
                    u.uhpmax += 4;
                u.uhp = u.uhpmax;
                make_blinded(0L, TRUE);
                make_sick(0L, (char *) 0, FALSE, SICK_ALL);
                heal_legs();
                context.botl = 1;
                break;
            case 5:
                take_gold();
                break;
            case 6:
                if (u.uluck + rn2(5) < 0) {
/*JP
                    You_feel("your luck is changing.");
*/
                    pline("運が向いてきた気がする.");
                    change_luck(1);
                } else
                    makewish();
                break;
            case 7:
              {
                int cnt = rnd(10);

                /* Magical voice not affected by deafness */
/*JP
                pline("A voice echoes:");
*/
                pline("声が響いた:");
#if 0 /*JP*/
                verbalize("Thy audience hath been summoned, %s!",
                          flags.female ? "Dame" : "Sire");
#else
                verbalize("%sよ!汝の聴衆召喚されし.",
                          flags.female ? "女" : "男");
#endif
                while (cnt--)
                    (void) makemon(courtmon(), u.ux, u.uy, NO_MM_FLAGS);
                break;
              }
            case 8:
                /* Magical voice not affected by deafness */
/*JP
                pline("A voice echoes:");
*/
                pline("声が響いた:");
#if 0 /*JP*/
                verbalize("By thine Imperious order, %s...",
                          flags.female ? "Dame" : "Sire");
#else
                verbalize("%sよ!汝の傲慢聞きいれようぞ.",
                          flags.female ? "女" : "男");
#endif
                do_genocide(5); /* REALLY|ONTHRONE, see do_genocide() */
                break;
            case 9:
                /* Magical voice not affected by deafness */
/*JP
                pline("A voice echoes:");
*/
                pline("声が響いた:");
                verbalize(
/*JP
                 "A curse upon thee for sitting upon this most holy throne!");
*/
                 "聖なる玉座に座りし汝に呪いあれ!");
                if (Luck > 0) {
                    make_blinded(Blinded + rn1(100, 250), TRUE);
                } else
                    rndcurse();
                break;
            case 10:
                if (Luck < 0 || (HSee_invisible & INTRINSIC)) {
                    if (level.flags.nommap) {
/*JP
                        pline("A terrible drone fills your head!");
*/
                        pline("恐しいブンブンという音が頭に響いた!");
                        make_confused((HConfusion & TIMEOUT) + (long) rnd(30),
                                      FALSE);
                    } else {
/*JP
                        pline("An image forms in your mind.");
*/
                        pline("あるイメージが頭に浮んだ.");
                        do_mapping();
                    }
                } else {
/*JP
                    Your("vision becomes clear.");
*/
                    Your("視界は冴え渡った.");
                    HSee_invisible |= FROMOUTSIDE;
                    newsym(u.ux, u.uy);
                }
                break;
            case 11:
                if (Luck < 0) {
/*JP
                    You_feel("threatened.");
*/
                    You("脅迫されているような気がした.");
                    aggravate();
                } else {
/*JP
                    You_feel("a wrenching sensation.");
*/
                    You("ねじられたような感覚を感じた.");
                    tele(); /* teleport him */
                }
                break;
            case 12:
/*JP
                You("are granted an insight!");
*/
                You("洞察力を得た!");
                if (invent) {
                    /* rn2(5) agrees w/seffects() */
                    identify_pack(rn2(5), FALSE);
                }
                break;
            case 13:
/*JP
                Your("mind turns into a pretzel!");
*/
                Your("心はクネクネになった!");
                make_confused((HConfusion & TIMEOUT) + (long) rn1(7, 16),
                              FALSE);
                break;
            default:
                impossible("throne effect");
                break;
            }
        } else {
            if (is_prince(youmonst.data))
/*JP
                You_feel("very comfortable here.");
*/
                You("ここはとても落ち着く.");
            else
/*JP
                You_feel("somehow out of place...");
*/
                You("何か場違いの気がした...");
        }

        if (!rn2(3) && IS_THRONE(levl[u.ux][u.uy].typ)) {
            /* may have teleported */
            levl[u.ux][u.uy].typ = ROOM;
/*JP
            pline_The("throne vanishes in a puff of logic.");
*/
            pline("玉座はふっと消えた.");
            newsym(u.ux, u.uy);
        }
    } else if (lays_eggs(youmonst.data)) {
        struct obj *uegg;

        if (!flags.female) {
#if 0 /*JP*/
            pline("%s can't lay eggs!",
                  Hallucination
                      ? "You may think you are a platypus, but a male still"
                      : "Males");
#else
            pline("%s雄は卵を産めない!",
                  Hallucination
                      ? "あなたは自分がカモノハシだと思っているかもしれないが,やっぱり"
                      : "");
#endif
            return 0;
        } else if (u.uhunger < (int) objects[EGG].oc_nutrition) {
/*JP
            You("don't have enough energy to lay an egg.");
*/
            You("卵を産むだけのエネルギーがない.");
            return 0;
        }

        uegg = mksobj(EGG, FALSE, FALSE);
        uegg->spe = 1;
        uegg->quan = 1L;
        uegg->owt = weight(uegg);
        /* this sets hatch timers if appropriate */
        set_corpsenm(uegg, egg_type_from_parent(u.umonnum, FALSE));
        uegg->known = uegg->dknown = 1;
/*JP
        You("lay an egg.");
*/
        You("卵を産んだ.");
        dropy(uegg);
        stackobj(uegg);
        morehungry((int) objects[EGG].oc_nutrition);
    } else {
/*JP
        pline("Having fun sitting on the %s?", surface(u.ux, u.uy));
*/
        pline("%sに座って楽しいかい?", surface(u.ux,u.uy));
    }
    return 1;
}
/* return 0 if still on level, 3 if not */
int
mlevel_tele_trap(struct monst *mtmp, struct trap *trap, boolean force_it,
                 int in_sight)
{
    int tt = trap->ttyp;
    const struct permonst *mptr = mtmp->data;

    if (mtmp == u.ustuck)       /* probably a vortex */
        return 0;       /* temporary? kludge */
    if (teleport_pet(mtmp, force_it)) {
        d_level tolevel;
        int migrate_typ = MIGR_RANDOM;

        if ((tt == HOLE || tt == TRAPDOOR)) {
            if (Is_stronghold(&u.uz)) {
                assign_level(&tolevel, &valley_level);
            } else if (Is_botlevel(&u.uz)) {
                if (in_sight && trap->tseen)
                    pline("%s avoids the %s.", Monnam(mtmp),
                          (tt == HOLE) ? "hole" : "trap");
                return 0;
            } else {
                get_level(&tolevel, depth(&u.uz) + 1);
            }
        } else if (tt == MAGIC_PORTAL) {
            if (In_endgame(&u.uz) &&
                (mon_has_amulet(mtmp) ||
                 is_home_elemental(&mtmp->dlevel->z, mptr))) {
                if (in_sight && mptr->mlet != S_ELEMENTAL) {
                    pline("%s seems to shimmer for a moment.", Monnam(mtmp));
                    seetrap(trap);
                }
                return 0;
            } else {
                assign_level(&tolevel, &trap->dst);
                migrate_typ = MIGR_PORTAL;
            }
        } else {        /* (tt == LEVEL_TELEP) */
            int nlev;

            if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) {
                if (in_sight)
                    pline("%s seems very disoriented for a moment.",
                          Monnam(mtmp));
                return 0;
            }
            nlev = random_teleport_level();
            if (nlev == depth(&u.uz)) {
                if (in_sight)
                    pline("%s shudders for a moment.", Monnam(mtmp));
                return 0;
            }
            get_level(&tolevel, nlev);
        }

        if (in_sight) {
            pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp));
            seetrap(trap);
        }
        migrate_to_level(mtmp, ledger_no(&tolevel), migrate_typ, NULL);
        return 3;       /* no longer on this level */
    }
    return 0;
}
Example #18
0
int
dosit()
{
	static const char sit_message[] = "sit on the %s.";
	register struct trap *trap;
	register int typ = levl[u.ux][u.uy].typ;


#ifdef STEED
	if (u.usteed) {
	    You("are already sitting on %s.", mon_nam(u.usteed));
	    return (0);
	}
#endif

	if(!can_reach_floor())	{
	    if (Levitation)
		You("tumble in place.");
	    else
		You("are sitting on air.");
	    return 0;
	} else if (is_pool(u.ux, u.uy) && !Underwater) {  /* water walking */
	    goto in_water;
	}

	if(OBJ_AT(u.ux, u.uy)) {
	    register struct obj *obj;

	    obj = level.objects[u.ux][u.uy];
	    You("sit on %s.", the(xname(obj)));
	    if (!(Is_box(obj) || objects[obj->otyp].oc_material == CLOTH))
		pline("It's not very comfortable...");

	} else if ((trap = t_at(u.ux, u.uy)) != 0 ||
		   (u.utrap && (u.utraptype >= TT_LAVA))) {

	    if (u.utrap) {
		exercise(A_WIS, FALSE);	/* you're getting stuck longer */
		if(u.utraptype == TT_BEARTRAP) {
		    You_cant("sit down with your %s in the bear trap.", body_part(FOOT));
		    u.utrap++;
	        } else if(u.utraptype == TT_PIT) {
		    if(trap->ttyp == SPIKED_PIT) {
			You("sit down on a spike.  Ouch!");
			losehp(1, "sitting on an iron spike", KILLED_BY);
			exercise(A_STR, FALSE);
		    } else
			You("sit down in the pit.");
		    u.utrap += rn2(5);
		} else if(u.utraptype == TT_WEB) {
		    You("sit in the spider web and get entangled further!");
		    u.utrap += rn1(10, 5);
		} else if(u.utraptype == TT_LAVA) {
		    /* Must have fire resistance or they'd be dead already */
		    You("sit in the lava!");
		    u.utrap += rnd(4);
		    losehp(d(2,10), "sitting in lava", KILLED_BY);
		} else if(u.utraptype == TT_INFLOOR) {
		    You_cant("maneuver to sit!");
		    u.utrap++;
		}
	    } else {
	        You("sit down.");
		dotrap(trap, 0);
	    }
	} else if(Underwater || Is_waterlevel(&u.uz)) {
	    if (Is_waterlevel(&u.uz))
		There("are no cushions floating nearby.");
	    else
		You("sit down on the muddy bottom.");
	} else if(is_pool(u.ux, u.uy)) {
 in_water:
	    You("sit in the water.");
	    if (!rn2(10) && uarm)
		(void) rust_dmg(uarm, "armor", 1, TRUE, &youmonst);
	    if (!rn2(10) && uarmf && uarmf->otyp != WATER_WALKING_BOOTS)
		(void) rust_dmg(uarm, "armor", 1, TRUE, &youmonst);
#ifdef SINKS
	} else if(IS_SINK(typ)) {

	    You(sit_message, defsyms[S_sink].explanation);
	    Your("%s gets wet.", humanoid(youmonst.data) ? "rump" : "underside");
#endif
	} else if(IS_ALTAR(typ)) {

	    You(sit_message, defsyms[S_altar].explanation);
	    altar_wrath(u.ux, u.uy);

	} else if(IS_GRAVE(typ)) {

	    You(sit_message, defsyms[S_grave].explanation);

	} else if(typ == STAIRS) {

	    You(sit_message, "stairs");

	} else if(typ == LADDER) {

	    You(sit_message, "ladder");

	} else if (is_lava(u.ux, u.uy)) {

	    /* must be WWalking */
	    You(sit_message, "lava");
	    burn_away_slime();
	    if (likes_lava(youmonst.data)) {
		pline_The("lava feels warm.");
		return 1;
	    }
	    pline_The("lava burns you!");
	    losehp(d((Fire_resistance ? 2 : 10), 10),
		   "sitting on lava", KILLED_BY);

	} else if (is_ice(u.ux, u.uy)) {

	    You(sit_message, defsyms[S_ice].explanation);
	    if (!Cold_resistance) pline_The("ice feels cold.");

	} else if (typ == DRAWBRIDGE_DOWN) {

	    You(sit_message, "drawbridge");

	} else if(IS_THRONE(typ)) {

	    You(sit_message, defsyms[S_throne].explanation);
	    if (rnd(6) > 4)  {
		switch (rnd(13))  {
		    case 1:
			(void) adjattrib(rn2(A_MAX), -rn1(4,3), FALSE);
			losehp(rnd(10), "cursed throne", KILLED_BY_AN);
			break;
		    case 2:
			(void) adjattrib(rn2(A_MAX), 1, FALSE);
			break;
		    case 3:
			pline("A%s electric shock shoots through your body!",
			      (Shock_resistance) ? "n" : " massive");
			losehp(Shock_resistance ? rnd(6) : rnd(30),
			       "electric chair", KILLED_BY_AN);
			exercise(A_CON, FALSE);
			break;
		    case 4:
			You_feel("much, much better!");
			if (Upolyd) {
			    if (u.mh >= (u.mhmax - 5))  u.mhmax += 4;
			    u.mh = u.mhmax;
			}
			if(u.uhp >= (u.uhpmax - 5))  u.uhpmax += 4;
			u.uhp = u.uhpmax;
			make_blinded(0L,TRUE);
			make_sick(0L, (char *) 0, FALSE, SICK_ALL);
			heal_legs();
			flags.botl = 1;
			break;
		    case 5:
			take_gold();
			break;
		    case 6:
			if(u.uluck + rn2(5) < 0) {
			    You_feel("your luck is changing.");
			    change_luck(1);
			} else	    makewish();
			break;
		    case 7:
			{
			register int cnt = rnd(10);

			pline("A voice echoes:");
			verbalize("Thy audience hath been summoned, %s!",
				  flags.female ? "Dame" : "Sire");
			while(cnt--)
			    (void) makemon(courtmon(), u.ux, u.uy, NO_MM_FLAGS);
			break;
			}
		    case 8:
			pline("A voice echoes:");
			verbalize("By thy Imperious order, %s...",
				  flags.female ? "Dame" : "Sire");
			do_genocide(5);	/* REALLY|ONTHRONE, see do_genocide() */
			break;
		    case 9:
			pline("A voice echoes:");
	verbalize("A curse upon thee for sitting upon this most holy throne!");
			if (Luck > 0)  {
			    make_blinded(Blinded + rn1(100,250),TRUE);
			} else	    rndcurse();
			break;
		    case 10:
			if (Luck < 0 || (HSee_invisible & INTRINSIC))  {
				if (level.flags.nommap) {
					pline(
					"A terrible drone fills your head!");
					make_confused(HConfusion + rnd(30),
									FALSE);
				} else {
					pline("An image forms in your mind.");
					do_mapping();
				}
			} else  {
				Your("vision becomes clear.");
				HSee_invisible |= FROMOUTSIDE;
				newsym(u.ux, u.uy);
			}
			break;
		    case 11:
			if (Luck < 0)  {
			    You_feel("threatened.");
			    aggravate();
			} else  {

			    You_feel("a wrenching sensation.");
			    tele();		/* teleport him */
			}
			break;
		    case 12:
			You("are granted an insight!");
			if (invent) {
			    /* rn2(5) agrees w/seffects() */
			    identify_pack(rn2(5));
			}
			break;
		    case 13:
			Your("mind turns into a pretzel!");
			make_confused(HConfusion + rn1(7,16),FALSE);
			break;
		    default:	impossible("throne effect");
				break;
		}
	    } else {
		if (is_prince(youmonst.data))
		    You_feel("very comfortable here.");
		else
		    You_feel("somehow out of place...");
	    }

	    if (!rn2(3) && IS_THRONE(levl[u.ux][u.uy].typ)) {
		/* may have teleported */
		levl[u.ux][u.uy].typ = ROOM;
		pline_The("throne vanishes in a puff of logic.");
		newsym(u.ux,u.uy);
	    }

	} else if (lays_eggs(youmonst.data)) {
		struct obj *uegg;

		if (!flags.female) {
			pline("Males can't lay eggs!");
			return 0;
		}

		if (u.uhunger < (int)objects[EGG].oc_nutrition) {
			You("don't have enough energy to lay an egg.");
			return 0;
		}

		uegg = mksobj(EGG, FALSE, FALSE);
		uegg->spe = 1;
		uegg->quan = 1;
		uegg->owt = weight(uegg);
		uegg->corpsenm = egg_type_from_parent(u.umonnum, FALSE);
		uegg->known = uegg->dknown = 1;
		attach_egg_hatch_timeout(uegg);
		You("lay an egg.");
		dropy(uegg);
		stackobj(uegg);
		morehungry((int)objects[EGG].oc_nutrition);
	} else if (u.uswallow)
		There("are no seats in here!");
	else
		pline("Having fun sitting on the %s?", surface(u.ux,u.uy));
	return(1);
}
Example #19
0
/*  cutworm()
 *
 *  Check for mon->wormno before calling this function!
 *
 *  When hitting a worm (worm) at position x, y, with a weapon (weap),
 *  there is a chance that the worm will be cut in half, and a chance
 *  that both halves will survive.
 */
void
cutworm(struct monst *worm, xchar x, xchar y, struct obj *weap)
{
    struct wseg *curr, *new_tail;
    struct monst *new_worm;
    int wnum = worm->wormno;
    int cut_chance, new_wnum;

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

    if (x == worm->mx && y == worm->my)
        return; /* hit on head */

    /* cutting goes best with a bladed weapon */
    cut_chance = rnd(20);       /* Normally 1-16 does not cut */
    /* Normally 17-20 does */

    if (weap && objects[weap->otyp].oc_dir & SLASH)
        cut_chance += 10;       /* With a slashing weapon 1- 6 does not cut */
    /* 7-20 does */

    if (cut_chance < 17)
        return; /* not good enough */

    /* Find the segment that was attacked. */
    curr = level->wtails[wnum];

    while ((curr->wx != x) || (curr->wy != y)) {
        curr = curr->nseg;
        if (!curr) {
            impossible("cutworm: no segment at (%d,%d)", (int)x, (int)y);
            return;
        }
    }

    /* If this is the tail segment, then the worm just loses it. */
    if (curr == level->wtails[wnum]) {
        shrink_worm(wnum);
        return;
    }

    /* 
     *  Split the worm.  The tail for the new worm is the old worm's tail.
     *  The tail for the old worm is the segment that follows "curr",
     *  and "curr" becomes the dummy segment under the new head.
     */
    new_tail = level->wtails[wnum];
    level->wtails[wnum] = curr->nseg;
    curr->nseg = NULL;  /* split the worm */

    /* 
     *  At this point, the old worm is correct.  Any new worm will have
     *  it's head at "curr" and its tail at "new_tail".
     */

    /* Sometimes the tail end dies. */
    if (rn2(3) || !(new_wnum = get_wormno(level)) || !worm->m_lev) {
        cutoff(worm, new_tail);
        return;
    }

    remove_monster(level, x, y);        /* clone_mon puts new head here */
    if (!(new_worm = clone_mon(worm, x, y))) {
        cutoff(worm, new_tail);
        return;
    }
    new_worm->wormno = new_wnum;        /* affix new worm number */

    /* Devalue the monster level of both halves of the worm. */
    worm->m_lev =
        ((unsigned)worm->m_lev <=
         3) ? (unsigned)worm->m_lev : max((unsigned)worm->m_lev - 2, 3);
    new_worm->m_lev = worm->m_lev;

    /* Calculate the mhp on the new_worm for the (lower) monster level. */
    new_worm->mhpmax = new_worm->mhp = dice((int)new_worm->m_lev, 8);

    /* Calculate the mhp on the old worm for the (lower) monster level. */
    if (worm->m_lev > 3) {
        worm->mhpmax = dice((int)worm->m_lev, 8);
        if (worm->mhpmax < worm->mhp)
            worm->mhp = worm->mhpmax;
    }

    level->wtails[new_wnum] = new_tail; /* We've got all the info right now */
    level->wheads[new_wnum] = curr;     /* so we can do this faster than */
    level->wgrowtime[new_wnum] = 0L;    /* trying to call initworm().  */

    /* Place the new monster at all the segment locations. */
    place_wsegs(new_worm);

    if (flags.mon_moving)
        pline(msgc_monneutral, "%s is cut in half.", Monnam(worm));
    else
        pline(msgc_combatgood, "You cut %s in half.", mon_nam(worm));
}
Example #20
0
File: worn.c Project: mbi/NitroHack
static void m_dowear_type(struct monst *mon, long flag, boolean creation,
			  boolean racialexception)
{
	struct obj *old, *best, *obj;
	int m_delay = 0;
	int unseen = !canseemon(mon);
	char nambuf[BUFSZ];

	if (mon->mfrozen) return; /* probably putting previous item on */

	/* Get a copy of monster's name before altering its visibility */
	strcpy(nambuf, See_invisible ? Monnam(mon) : mon_nam(mon));

	old = which_armor(mon, flag);
	if (old && old->cursed) return;
	if (old && flag == W_AMUL) return; /* no such thing as better amulets */
	best = old;

	for (obj = mon->minvent; obj; obj = obj->nobj) {
	    switch(flag) {
		case W_AMUL:
		    if (obj->oclass != AMULET_CLASS ||
			    (obj->otyp != AMULET_OF_LIFE_SAVING &&
				obj->otyp != AMULET_OF_REFLECTION))
			continue;
		    best = obj;
		    goto outer_break; /* no such thing as better amulets */
		case W_ARMU:
		    if (!is_shirt(obj)) continue;
		    break;
		case W_ARMC:
		    if (!is_cloak(obj)) continue;
		    break;
		case W_ARMH:
		    if (!is_helmet(obj)) continue;
		    /* (flimsy exception matches polyself handling) */
		    if (has_horns(mon->data) && !is_flimsy(obj)) continue;
		    break;
		case W_ARMS:
		    if (!is_shield(obj)) continue;
		    break;
		case W_ARMG:
		    if (!is_gloves(obj)) continue;
		    break;
		case W_ARMF:
		    if (!is_boots(obj)) continue;
		    break;
		case W_ARM:
		    if (!is_suit(obj)) continue;
		    if (racialexception && (racial_exception(mon, obj) < 1)) continue;
		    break;
	    }
	    if (obj->owornmask) continue;
	    /* I'd like to define a VISIBLE_ARM_BONUS which doesn't assume the
	     * monster knows obj->spe, but if I did that, a monster would keep
	     * switching forever between two -2 caps since when it took off one
	     * it would forget spe and once again think the object is better
	     * than what it already has.
	     */
	    if (best && (ARM_BONUS(best) + extra_pref(mon,best) >= ARM_BONUS(obj) + extra_pref(mon,obj)))
		continue;
	    best = obj;
	}
outer_break:
	if (!best || best == old) return;

	/* if wearing a cloak, account for the time spent removing
	   and re-wearing it when putting on a suit or shirt */
	if ((flag == W_ARM || flag == W_ARMU) && (mon->misc_worn_check & W_ARMC))
	    m_delay += 2;
	/* when upgrading a piece of armor, account for time spent
	   taking off current one */
	if (old)
	    m_delay += objects[old->otyp].oc_delay;

	if (old) /* do this first to avoid "(being worn)" */
	    old->owornmask = 0L;
	if (!creation) {
	    if (canseemon(mon)) {
		char buf[BUFSZ];

		if (old)
		    sprintf(buf, " removes %s and", distant_name(old, doname));
		else
		    buf[0] = '\0';
		pline("%s%s puts on %s.", Monnam(mon),
		      buf, distant_name(best,doname));
	    } /* can see it */
	    m_delay += objects[best->otyp].oc_delay;
	    mon->mfrozen = m_delay;
	    if (mon->mfrozen) mon->mcanmove = 0;
	}
	if (old)
	    update_mon_intrinsics(mon, old, FALSE, creation);
	mon->misc_worn_check |= flag;
	best->owornmask |= flag;
	update_mon_intrinsics(mon, best, TRUE, creation);
	/* if couldn't see it but now can, or vice versa, */
	if (!creation && (unseen ^ !canseemon(mon))) {
		if (mon->minvis && !See_invisible) {
			pline("Suddenly you cannot see %s.", nambuf);
			makeknown(best->otyp);
		} /* else if (!mon->minvis) pline("%s suddenly appears!", Amonnam(mon)); */
	}
}
Example #21
0
File: worn.c Project: mbi/NitroHack
void mon_break_armor(struct monst *mon, boolean polyspot)
{
	struct obj *otmp;
	const struct permonst *mdat = mon->data;
	boolean vis = cansee(mon->mx, mon->my);
	boolean handless_or_tiny = (nohands(mdat) || verysmall(mdat));
	const char *pronoun = mhim(mon),
			*ppronoun = mhis(mon);

	if (breakarm(mdat)) {
	    if ((otmp = which_armor(mon, W_ARM)) != 0) {
		if ((Is_dragon_scales(otmp) &&
			mdat == Dragon_scales_to_pm(otmp)) ||
		    (Is_dragon_mail(otmp) && mdat == Dragon_mail_to_pm(otmp)))
		    ;	/* no message here;
			   "the dragon merges with his scaly armor" is odd
			   and the monster's previous form is already gone */
		else if (vis)
		    pline("%s breaks out of %s armor!", Monnam(mon), ppronoun);
		else
		    You_hear("a cracking sound.");
		m_useup(mon, otmp);
	    }
	    if ((otmp = which_armor(mon, W_ARMC)) != 0) {
		if (otmp->oartifact) {
		    if (vis)
			pline("%s %s falls off!", s_suffix(Monnam(mon)),
				cloak_simple_name(otmp));
		    if (polyspot) bypass_obj(otmp);
		    m_lose_armor(mon, otmp);
		} else {
		    if (vis)
			pline("%s %s tears apart!", s_suffix(Monnam(mon)),
				cloak_simple_name(otmp));
		    else
			You_hear("a ripping sound.");
		    m_useup(mon, otmp);
		}
	    }
	    if ((otmp = which_armor(mon, W_ARMU)) != 0) {
		if (vis)
		    pline("%s shirt rips to shreds!", s_suffix(Monnam(mon)));
		else
		    You_hear("a ripping sound.");
		m_useup(mon, otmp);
	    }
	} else if (sliparm(mdat)) {
	    if ((otmp = which_armor(mon, W_ARM)) != 0) {
		if (vis)
		    pline("%s armor falls around %s!",
				 s_suffix(Monnam(mon)), pronoun);
		else
		    You_hear("a thud.");
		if (polyspot) bypass_obj(otmp);
		m_lose_armor(mon, otmp);
	    }
	    if ((otmp = which_armor(mon, W_ARMC)) != 0) {
		if (vis) {
		    if (is_whirly(mon->data))
			pline("%s %s falls, unsupported!",
				     s_suffix(Monnam(mon)), cloak_simple_name(otmp));
		    else
			pline("%s shrinks out of %s %s!", Monnam(mon),
						ppronoun, cloak_simple_name(otmp));
		}
		if (polyspot) bypass_obj(otmp);
		m_lose_armor(mon, otmp);
	    }
	    if ((otmp = which_armor(mon, W_ARMU)) != 0) {
		if (vis) {
		    if (sliparm(mon->data))
			pline("%s seeps right through %s shirt!",
					Monnam(mon), ppronoun);
		    else
			pline("%s becomes much too small for %s shirt!",
					Monnam(mon), ppronoun);
		}
		if (polyspot) bypass_obj(otmp);
		m_lose_armor(mon, otmp);
	    }
	}
	if (handless_or_tiny) {
	    /* [caller needs to handle weapon checks] */
	    if ((otmp = which_armor(mon, W_ARMG)) != 0) {
		if (vis)
		    pline("%s drops %s gloves%s!", Monnam(mon), ppronoun,
					MON_WEP(mon) ? " and weapon" : "");
		if (polyspot) bypass_obj(otmp);
		m_lose_armor(mon, otmp);
	    }
	    if ((otmp = which_armor(mon, W_ARMS)) != 0) {
		if (vis)
		    pline("%s can no longer hold %s shield!", Monnam(mon),
								ppronoun);
		else
		    You_hear("a clank.");
		if (polyspot) bypass_obj(otmp);
		m_lose_armor(mon, otmp);
	    }
	}
	if (handless_or_tiny || has_horns(mdat)) {
	    if ((otmp = which_armor(mon, W_ARMH)) != 0 &&
		    /* flimsy test for horns matches polyself handling */
		    (handless_or_tiny || !is_flimsy(otmp))) {
		if (vis)
		    pline("%s helmet falls to the %s!",
			  s_suffix(Monnam(mon)), surface(mon->mx, mon->my));
		else
		    You_hear("a clank.");
		if (polyspot) bypass_obj(otmp);
		m_lose_armor(mon, otmp);
	    }
	}
	if (handless_or_tiny || slithy(mdat) || mdat->mlet == S_CENTAUR) {
	    if ((otmp = which_armor(mon, W_ARMF)) != 0) {
		if (vis) {
		    if (is_whirly(mon->data))
			pline("%s boots fall away!",
				       s_suffix(Monnam(mon)));
		    else pline("%s boots %s off %s feet!",
			s_suffix(Monnam(mon)),
			verysmall(mdat) ? "slide" : "are pushed", ppronoun);
		}
		if (polyspot) bypass_obj(otmp);
		m_lose_armor(mon, otmp);
	    }
	}
	if (!can_saddle(mon)) {
	    if ((otmp = which_armor(mon, W_SADDLE)) != 0) {
		if (polyspot) bypass_obj(otmp);
		m_lose_armor(mon, otmp);
		if (vis)
		    pline("%s saddle falls off.", s_suffix(Monnam(mon)));
	    }
	    if (mon == u.usteed)
		goto noride;
	} else if (mon == u.usteed && !can_ride(mon)) {
	noride:
	    pline("You can no longer ride %s.", mon_nam(mon));
	    if (touch_petrifies(u.usteed->data) &&
			!Stone_resistance && rnl(3)) {
		char buf[BUFSZ];

		pline("You touch %s.", mon_nam(u.usteed));
		sprintf(buf, "falling off %s",
				an(u.usteed->data->mname));
		instapetrify(buf);
	    }
	    dismount_steed(DISMOUNT_FELL);
	}
	return;
}
Example #22
0
int dogaze(void)
{
	struct monst *mtmp;
	int looked = 0;
	char qbuf[QBUFSZ];
	int i;
	uchar adtyp = 0;

	for (i = 0; i < NATTK; i++) {
	    if (youmonst.data->mattk[i].aatyp == AT_GAZE) {
		adtyp = youmonst.data->mattk[i].adtyp;
		break;
	    }
	}
	if (adtyp != AD_CONF && adtyp != AD_FIRE) {
	    impossible("gaze attack %d?", adtyp);
	    return 0;
	}


	if (Blind) {
	    pline("You can't see anything to gaze at.");
	    return 0;
	}
	if (u.uen < 15) {
	    pline("You lack the energy to use your special gaze!");
	    return 0;
	}
	u.uen -= 15;
	iflags.botl = 1;

	for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
	    if (DEADMONSTER(mtmp)) continue;
	    if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my)) {
		looked++;
		if (Invis && !perceives(mtmp->data))
		    pline("%s seems not to notice your gaze.", Monnam(mtmp));
		else if (mtmp->minvis && !See_invisible)
		    pline("You can't see where to gaze at %s.", Monnam(mtmp));
		else if (mtmp->m_ap_type == M_AP_FURNITURE
			|| mtmp->m_ap_type == M_AP_OBJECT) {
		    looked--;
		    continue;
		} else if (flags.safe_dog && !Confusion && !Hallucination
		  && mtmp->mtame) {
		    pline("You avoid gazing at %s.", y_monnam(mtmp));
		} else {
		    if (flags.confirm && mtmp->mpeaceful && !Confusion
							&& !Hallucination) {
			sprintf(qbuf, "Really %s %s?",
			    (adtyp == AD_CONF) ? "confuse" : "attack",
			    mon_nam(mtmp));
			if (yn(qbuf) != 'y') continue;
			setmangry(mtmp);
		    }
		    if (!mtmp->mcanmove || mtmp->mstun || mtmp->msleeping ||
				    !mtmp->mcansee || !haseyes(mtmp->data)) {
			looked--;
			continue;
		    }
		    /* No reflection check for consistency with when a monster
		     * gazes at *you*--only medusa gaze gets reflected then.
		     */
		    if (adtyp == AD_CONF) {
			if (!mtmp->mconf)
			    pline("Your gaze confuses %s!", mon_nam(mtmp));
			else
			    pline("%s is getting more and more confused.",
							Monnam(mtmp));
			mtmp->mconf = 1;
		    } else if (adtyp == AD_FIRE) {
			int dmg = dice(2,6);
			pline("You attack %s with a fiery gaze!", mon_nam(mtmp));
			if (resists_fire(mtmp)) {
			    pline("The fire doesn't burn %s!", mon_nam(mtmp));
			    dmg = 0;
			}
			if ((int) u.ulevel > rn2(20))
			    destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
			if ((int) u.ulevel > rn2(20))
			    destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
			if ((int) u.ulevel > rn2(25))
			    destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
			if (dmg && !DEADMONSTER(mtmp)) mtmp->mhp -= dmg;
			if (mtmp->mhp <= 0) killed(mtmp);
		    }
		    /* For consistency with passive() in uhitm.c, this only
		     * affects you if the monster is still alive.
		     */
		    if (!DEADMONSTER(mtmp) &&
			  (mtmp->data==&mons[PM_FLOATING_EYE]) && !mtmp->mcan) {
			if (!Free_action) {
			    pline("You are frozen by %s gaze!",
					     s_suffix(mon_nam(mtmp)));
			    nomul((u.ulevel > 6 || rn2(4)) ?
				    -dice((int)mtmp->m_lev+1,
					    (int)mtmp->data->mattk[0].damd)
				    : -200, "frozen by a monster's gaze");
			    return 1;
			} else
			    pline("You stiffen momentarily under %s gaze.",
				    s_suffix(mon_nam(mtmp)));
		    }
		    /* Technically this one shouldn't affect you at all because
		     * the Medusa gaze is an active monster attack that only
		     * works on the monster's turn, but for it to *not* have an
		     * effect would be too weird.
		     */
		    if (!DEADMONSTER(mtmp) &&
			    (mtmp->data == &mons[PM_MEDUSA]) && !mtmp->mcan) {
			pline(
			 "Gazing at the awake %s is not a very good idea.",
			    l_monnam(mtmp));
			/* as if gazing at a sleeping anything is fruitful... */
			pline("You turn to stone...");
			killer_format = KILLED_BY;
			killer = "deliberately meeting Medusa's gaze";
			done(STONING);
		    }
		}
	    }
	}
	if (!looked) pline("You gaze at no place in particular.");
	return 1;
}
Example #23
0
/* Check all object lists for consistency. */
void
obj_sanity_check(void)
{
    int x, y;
    struct obj *obj;
    struct monst *mon;
    const char *mesg;
    char obj_address[20], mon_address[20];  /* room for formatted pointers */

    mesg = "fobj sanity";
    for (obj = fobj; obj; obj = obj->nobj) {
        if (obj->where != OBJ_FLOOR) {
            pline("%s obj %s %s@(%d,%d): %s\n", mesg,
                  fmt_ptr((genericptr_t)obj, obj_address),
                  where_name(obj->where),
                  obj->ox, obj->oy, doname(obj));
        }
        check_contained(obj, mesg);
    }

    mesg = "location sanity";
    for (x = 0; x < COLNO; x++)
        for (y = 0; y < ROWNO; y++)
            for (obj = level.objects[x][y]; obj; obj = obj->nexthere)
                if (obj->where != OBJ_FLOOR) {
                    pline("%s obj %s %s@(%d,%d): %s\n", mesg,
                          fmt_ptr((genericptr_t)obj, obj_address),
                          where_name(obj->where),
                          obj->ox, obj->oy, doname(obj));
                }

    mesg = "invent sanity";
    for (obj = invent; obj; obj = obj->nobj) {
        if (obj->where != OBJ_INVENT) {
            pline("%s obj %s %s: %s\n", mesg,
                  fmt_ptr((genericptr_t)obj, obj_address),
                  where_name(obj->where), doname(obj));
        }
        check_contained(obj, mesg);
    }

    mesg = "migrating sanity";
    for (obj = migrating_objs; obj; obj = obj->nobj) {
        if (obj->where != OBJ_MIGRATING) {
            pline("%s obj %s %s: %s\n", mesg,
                  fmt_ptr((genericptr_t)obj, obj_address),
                  where_name(obj->where), doname(obj));
        }
        check_contained(obj, mesg);
    }

    mesg = "buried sanity";
    for (obj = level.buriedobjlist; obj; obj = obj->nobj) {
        if (obj->where != OBJ_BURIED) {
            pline("%s obj %s %s: %s\n", mesg,
                  fmt_ptr((genericptr_t)obj, obj_address),
                  where_name(obj->where), doname(obj));
        }
        check_contained(obj, mesg);
    }

    mesg = "bill sanity";
    for (obj = billobjs; obj; obj = obj->nobj) {
        if (obj->where != OBJ_ONBILL) {
            pline("%s obj %s %s: %s\n", mesg,
                  fmt_ptr((genericptr_t)obj, obj_address),
                  where_name(obj->where), doname(obj));
        }
        /* shouldn't be a full container on the bill */
        if (obj->cobj) {
            pline("%s obj %s contains %s! %s\n", mesg,
                  fmt_ptr((genericptr_t)obj, obj_address),
                  something, doname(obj));
        }
    }

    mesg = "minvent sanity";
    for (mon = fmon; mon; mon = mon->nmon)
        for (obj = mon->minvent; obj; obj = obj->nobj) {
            if (obj->where != OBJ_MINVENT) {
                pline("%s obj %s %s: %s\n", mesg,
                      fmt_ptr((genericptr_t)obj, obj_address),
                      where_name(obj->where), doname(obj));
            }
            if (obj->ocarry != mon) {
                pline("%s obj %s (%s) not held by mon %s (%s)\n", mesg,
                      fmt_ptr((genericptr_t)obj, obj_address),
                      doname(obj),
                      fmt_ptr((genericptr_t)mon, mon_address),
                      mon_nam(mon));
            }
            check_contained(obj, mesg);
        }
}
Example #24
0
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;
}
Example #25
0
/* return 1 if action took 1 (or more) moves, 0 if error or aborted */
int doengrave(struct obj *otmp)
{
	boolean dengr = FALSE;	/* TRUE if we wipe out the current engraving */
	boolean doblind = FALSE;/* TRUE if engraving blinds the player */
	boolean doknown = FALSE;/* TRUE if we identify the stylus */
	boolean eow = FALSE;	/* TRUE if we are overwriting oep */
	boolean jello = FALSE;	/* TRUE if we are engraving in slime */
	boolean ptext = TRUE;	/* TRUE if we must prompt for engrave text */
	boolean teleengr =FALSE;/* TRUE if we move the old engraving */
	boolean zapwand = FALSE;/* TRUE if we remove a wand charge */
	xchar type = DUST;	/* Type of engraving made */
	char buf[BUFSZ];	/* Buffer for final/poly engraving text */
	char ebuf[BUFSZ];	/* Buffer for initial engraving text */
	char qbuf[QBUFSZ];	/* Buffer for query text */
	char post_engr_text[BUFSZ]; /* Text displayed after engraving prompt */
	const char *everb;	/* Present tense of engraving type */
	const char *eloc;	/* Where the engraving is (ie dust/floor/...) */
	char *sp;		/* Place holder for space count of engr text */
	int len;		/* # of nonspace chars of new engraving text */
	int maxelen;		/* Max allowable length of engraving text */
	struct engr *oep = engr_at(level, u.ux,u.uy);
				/* The current engraving */
	char *writer;

	multi = 0;		/* moves consumed */
	nomovemsg = NULL;	/* occupation end message */

	buf[0] = (char)0;
	ebuf[0] = (char)0;
	post_engr_text[0] = (char)0;
	maxelen = BUFSZ - 1;
	if (is_demon(youmonst.data) || youmonst.data->mlet == S_VAMPIRE)
	    type = ENGR_BLOOD;

	/* Can the adventurer engrave at all? */

	if (u.uswallow) {
		if (is_animal(u.ustuck->data)) {
			pline("What would you write?  \"Jonah was here\"?");
			return 0;
		} else if (is_whirly(u.ustuck->data)) {
			pline("You can't reach the %s.", surface(u.ux,u.uy));
                        return 0;
		} else
			jello = TRUE;
	} else if (is_lava(level, u.ux, u.uy)) {
		pline("You can't write on the lava!");
		return 0;
	} else if (Underwater) {
		pline("You can't write underwater!");
		return 0;
	} else if (is_pool(level, u.ux,u.uy) || IS_FOUNTAIN(level->locations[u.ux][u.uy].typ)) {
		pline("You can't write on the water!");
		return 0;
	}
	if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)/* in bubble */) {
		pline("You can't write in thin air!");
		return 0;
	}
	if (cantwield(youmonst.data)) {
		pline("You can't even hold anything!");
		return 0;
	}
	if (check_capacity(NULL)) return 0;

	/* One may write with finger, or weapon, or wand, or..., or...
	 * Edited by GAN 10/20/86 so as not to change weapon wielded.
	 */

	if (otmp && !validate_object(otmp, styluses, "write with"))
		return 0;
	else if (!otmp)
		otmp = getobj(styluses, "write with");
	if (!otmp) return 0;		/* otmp == zeroobj if fingers */

	if (otmp == &zeroobj) writer = makeplural(body_part(FINGER));
	else writer = xname(otmp);

	/* There's no reason you should be able to write with a wand
	 * while both your hands are tied up.
	 */
	if (!freehand() && otmp != uwep && !otmp->owornmask) {
		pline("You have no free %s to write with!", body_part(HAND));
		return 0;
	}

	if (jello) {
		pline("You tickle %s with your %s.", mon_nam(u.ustuck), writer);
		pline("Your message dissolves...");
		return 0;
	}
	if (otmp->oclass != WAND_CLASS && !can_reach_floor()) {
		pline("You can't reach the %s!", surface(u.ux,u.uy));
                return 0;
	}
	if (IS_ALTAR(level->locations[u.ux][u.uy].typ)) {
		pline("You make a motion towards the altar with your %s.", writer);
		altar_wrath(u.ux, u.uy);
		return 0;
	}
	if (IS_GRAVE(level->locations[u.ux][u.uy].typ)) {
	    if (otmp == &zeroobj) { /* using only finger */
		pline("You would only make a small smudge on the %s.",
			surface(u.ux, u.uy));
		return 0;
	    } else if (!level->locations[u.ux][u.uy].disturbed) {
		pline("You disturb the undead!");
		level->locations[u.ux][u.uy].disturbed = 1;
		makemon(&mons[PM_GHOUL], level, u.ux, u.uy, NO_MM_FLAGS);
		exercise(A_WIS, FALSE);
		return 1;
	    }
	}

	/* SPFX for items */

	switch (otmp->oclass) {
	    default:
	    case AMULET_CLASS:
	    case CHAIN_CLASS:
	    case POTION_CLASS:
	    case COIN_CLASS:
		break;

	    case RING_CLASS:
		/* "diamond" rings and others should work */
	    case GEM_CLASS:
		/* diamonds & other hard gems should work */
		if (objects[otmp->otyp].oc_tough) {
			type = ENGRAVE;
			break;
		}
		break;

	    case ARMOR_CLASS:
		if (is_boots(otmp)) {
			type = DUST;
			break;
		}
		/* fall through */
	    /* Objects too large to engrave with */
	    case BALL_CLASS:
	    case ROCK_CLASS:
		pline("You can't engrave with such a large object!");
		ptext = FALSE;
		break;

	    /* Objects too silly to engrave with */
	    case FOOD_CLASS:
	    case SCROLL_CLASS:
	    case SPBOOK_CLASS:
		pline("Your %s would get %s.", xname(otmp),
			is_ice(level, u.ux, u.uy) ? "all frosty" : "too dirty");
		ptext = FALSE;
		break;

	    case RANDOM_CLASS:	/* This should mean fingers */
		break;

	    /* The charge is removed from the wand before prompting for
	     * the engraving text, because all kinds of setup decisions
	     * and pre-engraving messages are based upon knowing what type
	     * of engraving the wand is going to do.  Also, the player
	     * will have potentially seen "You wrest .." message, and
	     * therefore will know they are using a charge.
	     */
	    case WAND_CLASS:
		if (zappable(otmp)) {
		    check_unpaid(otmp);
		    zapwand = TRUE;
		    if (Levitation) ptext = FALSE;

		    switch (otmp->otyp) {
		    /* DUST wands */
		    default:
			break;

			/* NODIR wands */
		    case WAN_LIGHT:
		    case WAN_SECRET_DOOR_DETECTION:
		    case WAN_CREATE_MONSTER:
		    case WAN_WISHING:
		    case WAN_ENLIGHTENMENT:
			zapnodir(otmp);
			break;

			/* IMMEDIATE wands */
			/* If wand is "IMMEDIATE", remember to affect the
			 * previous engraving even if turning to dust.
			 */
		    case WAN_STRIKING:
			strcpy(post_engr_text,
			"The wand unsuccessfully fights your attempt to write!"
			);
			break;
		    case WAN_SLOW_MONSTER:
			if (!Blind) {
			   sprintf(post_engr_text,
				   "The bugs on the %s slow down!",
				   surface(u.ux, u.uy));
			}
			break;
		    case WAN_SPEED_MONSTER:
			if (!Blind) {
			   sprintf(post_engr_text,
				   "The bugs on the %s speed up!",
				   surface(u.ux, u.uy));
			}
			break;
		    case WAN_POLYMORPH:
			if (oep)  {
			    if (!Blind) {
				type = (xchar)0;	/* random */
				random_engraving(buf);
			    }
			    dengr = TRUE;
			}
			break;
		    case WAN_NOTHING:
		    case WAN_UNDEAD_TURNING:
		    case WAN_OPENING:
		    case WAN_LOCKING:
		    case WAN_PROBING:
			break;

			/* RAY wands */
		    case WAN_MAGIC_MISSILE:
			ptext = TRUE;
			if (!Blind) {
			   sprintf(post_engr_text,
				   "The %s is riddled by bullet holes!",
				   surface(u.ux, u.uy));
			}
			break;

		    /* can't tell sleep from death - Eric Backus */
		    case WAN_SLEEP:
		    case WAN_DEATH:
			if (!Blind) {
			   sprintf(post_engr_text,
				   "The bugs on the %s stop moving!",
				   surface(u.ux, u.uy));
			}
			break;

		    case WAN_COLD:
			if (!Blind)
			    strcpy(post_engr_text,
				"A few ice cubes drop from the wand.");
			if (!oep || (oep->engr_type != BURN))
			    break;
		    case WAN_CANCELLATION:
		    case WAN_MAKE_INVISIBLE:
			if (oep && oep->engr_type != HEADSTONE) {
			    if (!Blind)
				pline("The engraving on the %s vanishes!",
					surface(u.ux,u.uy));
			    dengr = TRUE;
			}
			break;
		    case WAN_TELEPORTATION:
			if (oep && oep->engr_type != HEADSTONE) {
			    if (!Blind)
				pline("The engraving on the %s vanishes!",
					surface(u.ux,u.uy));
			    teleengr = TRUE;
			}
			break;

		    /* type = ENGRAVE wands */
		    case WAN_DIGGING:
			ptext = TRUE;
			type  = ENGRAVE;
			if (!objects[otmp->otyp].oc_name_known) {
			    if (flags.verbose)
				pline("This %s is a wand of digging!",
				xname(otmp));
			    doknown = TRUE;
			}
			if (!Blind)
			    strcpy(post_engr_text,
				IS_GRAVE(level->locations[u.ux][u.uy].typ) ?
				"Chips fly out from the headstone." :
				is_ice(level, u.ux, u.uy) ?
				"Ice chips fly up from the ice surface!" :
				"Gravel flies up from the floor.");
			else
			    strcpy(post_engr_text, "You hear drilling!");
			break;

		    /* type = BURN wands */
		    case WAN_FIRE:
			ptext = TRUE;
			type  = BURN;
			if (!objects[otmp->otyp].oc_name_known) {
			if (flags.verbose)
			    pline("This %s is a wand of fire!", xname(otmp));
			    doknown = TRUE;
			}
			strcpy(post_engr_text,
				Blind ? "You feel the wand heat up." :
					"Flames fly from the wand.");
			break;
		    case WAN_LIGHTNING:
			ptext = TRUE;
			type  = BURN;
			if (!objects[otmp->otyp].oc_name_known) {
			    if (flags.verbose)
				pline("This %s is a wand of lightning!",
					xname(otmp));
			    doknown = TRUE;
			}
			if (!Blind) {
			    strcpy(post_engr_text,
				    "Lightning arcs from the wand.");
			    doblind = TRUE;
			} else
			    strcpy(post_engr_text, "You hear crackling!");
			break;

		    /* type = MARK wands */
		    /* type = ENGR_BLOOD wands */
		    }
		} else /* end if zappable */
		    if (!can_reach_floor()) {
			pline("You can't reach the %s!", surface(u.ux,u.uy));
			/* If it's a wrestable wand, the player wasted a
			   turn trying. */
			if (wrestable(otmp))
			    return 1;
			else
			    return 0;
		    }
		break;

	    case WEAPON_CLASS:
		if (is_blade(otmp)) {
		    if ((int)otmp->spe > -3)
			type = ENGRAVE;
		    else
			pline("Your %s too dull for engraving.", aobjnam(otmp,"are"));
		}
		break;

	    case TOOL_CLASS:
		if (otmp == ublindf) {
		    pline(
		"That is a bit difficult to engrave with, don't you think?");
		    return 0;
		}
		switch (otmp->otyp)  {
		    case MAGIC_MARKER:
			if (otmp->spe <= 0)
			    pline("Your marker has dried out.");
			else
			    type = MARK;
			break;
		    case TOWEL:
			/* Can't really engrave with a towel */
			ptext = FALSE;
			if (oep)
			    if ((oep->engr_type == DUST ) ||
				(oep->engr_type == ENGR_BLOOD) ||
				(oep->engr_type == MARK )) {
				if (!Blind)
				    pline("You wipe out the message here.");
				else
				    pline("Your %s %s %s.", xname(otmp),
					 otense(otmp, "get"),
					 is_ice(level, u.ux, u.uy) ?
					 "frosty" : "dusty");
				dengr = TRUE;
			    } else
				pline("Your %s can't wipe out this engraving.",
				     xname(otmp));
			else
			    pline("Your %s %s %s.", xname(otmp), otense(otmp, "get"),
				  is_ice(level, u.ux, u.uy) ? "frosty" : "dusty");
			break;
		    default:
			break;
		}
		break;

	    case VENOM_CLASS:
		if (wizard) {
		    pline("Writing a poison pen letter??");
		    break;
		}
	    case ILLOBJ_CLASS:
		impossible("You're engraving with an illegal object!");
		break;
	}

	if (IS_GRAVE(level->locations[u.ux][u.uy].typ)) {
	    if (type == ENGRAVE || type == 0)
		type = HEADSTONE;
	    else {
		/* ensures the "cannot wipe out" case */
		type = DUST;
		dengr = FALSE;
		teleengr = FALSE;
		buf[0] = (char)0;
	    }
	}

	/* End of implement setup */

	/* Identify stylus */
	if (doknown) {
	    makeknown(otmp->otyp);
	    more_experienced(0,10);
	}

	if (teleengr) {
	    rloc_engr(oep);
	    oep = NULL;
	}

	if (dengr) {
	    del_engr(oep, level);
	    oep = NULL;
	}

	/* Something has changed the engraving here */
	if (*buf) {
	    make_engr_at(level, u.ux, u.uy, buf, moves, type);
	    pline("The engraving now reads: \"%s\".", buf);
	    ptext = FALSE;
	}

	if (zapwand && (otmp->spe < 0)) {
	    pline("%s %sturns to dust.",
		  The(xname(otmp)), Blind ? "" : "glows violently, then ");
	    if (!IS_GRAVE(level->locations[u.ux][u.uy].typ))
		pline("You are not going to get anywhere trying to write in the %s with your dust.",
		    is_ice(level, u.ux, u.uy) ? "frost" : "dust");
	    useup(otmp);
	    ptext = FALSE;
	}

	if (!ptext) {		/* Early exit for some implements. */
	    if (otmp->oclass == WAND_CLASS && !can_reach_floor())
		pline("You can't reach the %s!", surface(u.ux,u.uy));
	    return 1;
	}

	/* Special effects should have deleted the current engraving (if
	 * possible) by now.
	 */

	if (oep) {
	    char c = 'n';

	    /* Give player the choice to add to engraving. */

	    if (type == HEADSTONE) {
		/* no choice, only append */
		c = 'y';
	    } else if ( (type == oep->engr_type) && (!Blind ||
		 (oep->engr_type == BURN) || (oep->engr_type == ENGRAVE)) ) {
		c = yn_function("Do you want to add to the current engraving?",
				ynqchars, 'y');
		if (c == 'q') {
		    pline("Never mind.");
		    return 0;
		}
	    }

	    if (c == 'n' || Blind) {

		if ( (oep->engr_type == DUST) || (oep->engr_type == ENGR_BLOOD) ||
		    (oep->engr_type == MARK) ) {
		    if (!Blind) {
			pline("You wipe out the message that was %s here.",
			    ((oep->engr_type == DUST)  ? "written in the dust" :
			    ((oep->engr_type == ENGR_BLOOD) ? "scrawled in blood"   :
							 "written")));
			del_engr(oep, level);
			oep = NULL;
		    } else
		   /* Don't delete engr until after we *know* we're engraving */
			eow = TRUE;
		} else
		    if ( (type == DUST) || (type == MARK) || (type == ENGR_BLOOD) ) {
			pline(
			 "You cannot wipe out the message that is %s the %s here.",
			 oep->engr_type == BURN ?
			   (is_ice(level, u.ux, u.uy) ? "melted into" : "burned into") :
			   "engraved in", surface(u.ux,u.uy));
			return 1;
		    } else
			if ( (type != oep->engr_type) || (c == 'n') ) {
			    if (!Blind || can_reach_floor())
				pline("You will overwrite the current message.");
			    eow = TRUE;
			}
	    }
	}

	eloc = surface(u.ux,u.uy);
	switch(type){
	    default:
		everb = (oep && !eow ? "add to the weird writing on" :
				       "write strangely on");
		break;
	    case DUST:
		everb = (oep && !eow ? "add to the writing in" :
				       "write in");
		eloc = is_ice(level, u.ux, u.uy) ? "frost" : "dust";
		break;
	    case HEADSTONE:
		everb = (oep && !eow ? "add to the epitaph on" :
				       "engrave on");
		break;
	    case ENGRAVE:
		everb = (oep && !eow ? "add to the engraving in" :
				       "engrave in");
		break;
	    case BURN:
		everb = (oep && !eow ?
			( is_ice(level, u.ux,u.uy) ? "add to the text melted into" :
					      "add to the text burned into") :
			( is_ice(level, u.ux,u.uy) ? "melt into" : "burn into"));
		break;
	    case MARK:
		everb = (oep && !eow ? "add to the graffiti on" :
				       "scribble on");
		break;
	    case ENGR_BLOOD:
		everb = (oep && !eow ? "add to the scrawl on" :
				       "scrawl on");
		break;
	}

	/* Tell adventurer what is going on */
	if (otmp != &zeroobj)
	    pline("You %s the %s with %s.", everb, eloc, doname(otmp));
	else
	    pline("You %s the %s with your %s.", everb, eloc,
		makeplural(body_part(FINGER)));

	/* Prompt for engraving! */
	sprintf(qbuf,"What do you want to %s the %s here?", everb, eloc);
	getlin(qbuf, ebuf);

	/* Count the actual # of chars engraved not including spaces */
	len = strlen(ebuf);
	for (sp = ebuf; *sp; sp++) if (isspace(*sp)) len -= 1;

	if (len == 0 || strchr(ebuf, '\033')) {
	    if (zapwand) {
		if (!Blind)
		    pline("%s, then %s.",
			  Tobjnam(otmp, "glow"), otense(otmp, "fade"));
		return 1;
	    } else {
		pline("Never mind.");
                if (otmp && otmp->oclass == WAND_CLASS && wrestable(otmp))
                    return 1; /* disallow zero turn wrest */
                else
                    return 0;
	    }
	}

	/* A single `x' is the traditional signature of an illiterate person */
	if (len != 1 || (!strchr(ebuf, 'x') && !strchr(ebuf, 'X')))
	    u.uconduct.literate++;

	/* Mix up engraving if surface or state of mind is unsound.
	   Note: this won't add or remove any spaces. */
	for (sp = ebuf; *sp; sp++) {
	    if (isspace(*sp)) continue;
	    if (((type == DUST || type == ENGR_BLOOD) && !rn2(25)) ||
		    (Blind && !rn2(11)) || (Confusion && !rn2(7)) ||
		    (Stunned && !rn2(4)) || (Hallucination && !rn2(2)))
		*sp = ' ' + rnd(96 - 2);	/* ASCII '!' thru '~'
						   (excludes ' ' and DEL) */
	}

	/* Previous engraving is overwritten */
	if (eow) {
	    del_engr(oep, level);
	    oep = NULL;
	}

	/* Figure out how long it took to engrave, and if player has
	 * engraved too much.
	 */
	switch(type){
	    default:
		multi = -(len/10);
		if (multi) nomovemsg = "You finish your weird engraving.";
		break;
	    case DUST:
		multi = -(len/10);
		if (multi) nomovemsg = "You finish writing in the dust.";
		break;
	    case HEADSTONE:
	    case ENGRAVE:
		multi = -(len/10);
		if ((otmp->oclass == WEAPON_CLASS) &&
		    ((otmp->otyp != ATHAME) || otmp->cursed)) {
		    multi = -len;
		    maxelen = ((otmp->spe + 3) * 2) + 1;
			/* -2 = 3, -1 = 5, 0 = 7, +1 = 9, +2 = 11
			 * Note: this does not allow a +0 anything (except
			 *	 an athame) to engrave "Elbereth" all at once.
			 *	 However, you could now engrave "Elb", then
			 *	 "ere", then "th".
			 */
		    pline("Your %s dull.", aobjnam(otmp, "get"));
		    if (otmp->unpaid) {
			struct monst *shkp = shop_keeper(level, *u.ushops);
			if (shkp) {
			    pline("You damage it, you pay for it!");
			    bill_dummy_object(otmp);
			}
		    }
		    if (len > maxelen) {
			multi = -maxelen;
			otmp->spe = -3;
		    } else if (len > 1)
			otmp->spe -= len >> 1;
		    else otmp->spe -= 1; /* Prevent infinite engraving */
		} else
Example #26
0
int
dosit()
{
	static const char sit_message[] = "VERB_SITZEN auf OBJECT KASUS_DATIV ARTIKEL_BESTIMMTER %s."; /* EN static const char sit_message[] = "sit on the %s."; */
	register struct trap *trap;
	register int typ = levl[u.ux][u.uy].typ;


#ifdef STEED
	if (u.usteed) {
	    You("VERB_SITZEN bereits auf KASUS_DATIV %s.", mon_nam(u.usteed)); /* EN You("are already sitting on %s.", mon_nam(u.usteed)); */
	    return (0);
	}
#endif

	if(!can_reach_floor())	{
	    if (Levitation)
		You("VERB_SCHLAGEN Purzelbäume."); /* EN You("tumble in place."); */
	    else
		You("VERB_SITZEN auf Luft."); /* EN You("are sitting on air."); */
	    return 0;
	} else if (is_pool(u.ux, u.uy) && !Underwater) {  /* water walking */
	    goto in_water;
	}

	if(OBJ_AT(u.ux, u.uy)) {
	    register struct obj *obj;

	    obj = level.objects[u.ux][u.uy];
	    You("VERB_SITZEN auf OBJECT KASUS_DATIV %s.", the(xname(obj))); /* EN You("sit on %s.", the(xname(obj))); */
	    if (!(Is_box(obj) || objects[obj->otyp].oc_material == CLOTH))
		pline("Das ist nicht sehr bequem ..."); /* EN pline("It's not very comfortable..."); */

	} else if ((trap = t_at(u.ux, u.uy)) != 0 ||
		   (u.utrap && (u.utraptype >= TT_LAVA))) {

	    if (u.utrap) {
		exercise(A_WIS, FALSE);	/* you're getting stuck longer */
		if(u.utraptype == TT_BEARTRAP) {
		    pline("Mit KASUS_DATIV PRONOMEN_POSSESSIV %s in KASUS_DATIV ARTIKEL_BESTIMMTER NOUN_BEARTRAP SUBJECT_IM_SATZ VERB_KOENNEN PRONOMEN_PERSONAL OBJECT PRONOMEN_PERSONAL nicht hinsetzen.", body_part(FOOT)); /* EN You_cant("sit down with your %s in the bear trap.", body_part(FOOT)); */
		    u.utrap++;
	        } else if(u.utraptype == TT_PIT) {
		    if(trap->ttyp == SPIKED_PIT) {
			You("VERB_SETZEN OBJECT PRONOMEN_PERSONAL auf einen Stachel.  Aua!"); /* EN You("sit down on a spike.  Ouch!"); */
			losehp(1, "durch Sitzen auf einen Eisenstachel", KILLED_WITHOUT_PREPOSITION); /* EN losehp(1, "sitting on an iron spike", KILLED_BY); */
			exercise(A_STR, FALSE);
		    } else
			You("VERB_SETZEN OBJECT PRONOMEN_PERSONAL in die Grube."); /* EN You("sit down in the pit."); */
		    u.utrap += rn2(5);
		} else if(u.utraptype == TT_WEB) {
		    You("VERB_SETZEN OBJECT PRONOMEN_PERSONAL ins Spinnenetz und VERB_VERHEDDERN OBJECT PRONOMEN_PERSONAL noch mehr!"); /* EN You("sit in the spider web and get entangled further!"); */
		    u.utrap += rn1(10, 5);
		} else if(u.utraptype == TT_LAVA) {
		    /* Must have fire resistance or they'd be dead already */
		    You("VERB_SETZEN OBJECT PRONOMEN_PERSONAL in die Lava!"); /* EN You("sit in the lava!"); */
		    u.utrap += rnd(4);
		    losehp(d(2,10), "durch Sitzen in Lava", KILLED_WITHOUT_PREPOSITION); /* EN losehp(d(2,10), "sitting in lava", KILLED_BY); */
		} else if(u.utraptype == TT_INFLOOR) {
		    You("VERB_CAN OBJECT PRONOMEN_PERSONAL nicht richtig hinsetzen!"); /* EN You_cant("maneuver to sit!"); */
		    u.utrap++;
		}
	    } else {
	        You("VERB_SETZEN OBJECT PRONOMEN_PERSONAL hin."); /* EN You("sit down."); */
		dotrap(trap, 0);
	    }
	} else if(Underwater || Is_waterlevel(&u.uz)) {
	    if (Is_waterlevel(&u.uz))
		pline("Hier gibt es keine Sitzkissen."); /* EN There("are no cushions floating nearby."); */
	    else
		You("VERB_SETZEN OBJECT PRONOMEN_PERSONAL auf den schlammigen Untergrund."); /* EN You("sit down on the muddy bottom."); */
	} else if(is_pool(u.ux, u.uy)) {
 in_water:
	    You("VERB_SITZEN im Wasser."); /* EN You("sit in the water."); */
	    if (!rn2(10) && uarm)
		(void) rust_dmg(uarm, "NOUN_ARMOR", 1, TRUE, &youmonst); /* EN (void) rust_dmg(uarm, "armor", 1, TRUE, &youmonst); */
	    if (!rn2(10) && uarmf && uarmf->otyp != WATER_WALKING_BOOTS)
		(void) rust_dmg(uarm, "NOUN_ARMOR", 1, TRUE, &youmonst); /* EN (void) rust_dmg(uarm, "armor", 1, TRUE, &youmonst); */
#ifdef SINKS
	} else if(IS_SINK(typ)) {

	    You(sit_message, defsyms[S_sink].explanation);
	    Your("%s VERB_WERDEN nass.", humanoid(youmonst.data) ? "NOUN_HINTERTEIL" : "NOUN_UNTERSEITE"); /* EN Your("%s gets wet.", humanoid(youmonst.data) ? "rump" : "underside"); */
#endif
	} else if(IS_ALTAR(typ)) {

	    You(sit_message, defsyms[S_altar].explanation);
	    altar_wrath(u.ux, u.uy);

	} else if(IS_GRAVE(typ)) {

	    You(sit_message, defsyms[S_grave].explanation);

	} else if(typ == STAIRS) {

	    You(sit_message, "NOUN_STUFEs"); /* EN You(sit_message, "stairs"); */

	} else if(typ == LADDER) {

	    You(sit_message, "NOUN_LADDER"); /* EN You(sit_message, "ladder"); */

	} else if (is_lava(u.ux, u.uy)) {

	    /* must be WWalking */
	    You(sit_message, "NOUN_LAVA"); /* EN You(sit_message, "lava"); */
	    burn_away_slime();
	    if (likes_lava(youmonst.data)) {
		pline_The("NOUN_LAVA fühlt sich warm an."); /* EN pline_The("lava feels warm."); */
		return 1;
	    }
	    pline_The("NOUN_LAVA VERB_VERBRENNEN OBJECT PRONOMEN_PERSONAL!"); /* EN pline_The("lava burns you!"); */
	    losehp(d((Fire_resistance ? 2 : 10), 10),
		   "durch Sitzen auf Lava", KILLED_WITHOUT_PREPOSITION); /* EN "sitting on lava", KILLED_BY); */

	} else if (is_ice(u.ux, u.uy)) {

	    You(sit_message, defsyms[S_ice].explanation);
	    if (!Cold_resistance) pline_The("NOUN_ICE fühlt sich kalt an."); /* EN if (!Cold_resistance) pline_The("ice feels cold."); */

	} else if (typ == DRAWBRIDGE_DOWN) {

	    You(sit_message, "NOUN_DRAWBRIDGE"); /* EN You(sit_message, "drawbridge"); */

	} else if(IS_THRONE(typ)) {

	    You(sit_message, defsyms[S_throne].explanation);
	    if (rnd(6) > 4)  {
		switch (rnd(13))  {
		    case 1:
			(void) adjattrib(rn2(A_MAX), -rn1(4,3), FALSE);
			losehp(rnd(10), "ADJEKTIV_CURSED NOUN_THRON", KILLED_BY_AN); /* EN losehp(rnd(10), "cursed throne", KILLED_BY_AN); */
			break;
		    case 2:
			(void) adjattrib(rn2(A_MAX), 1, FALSE);
			break;
		    case 3:
			pline("SUBJECT ARTIKEL_UNBESTIMMTER%s elektrischer NOUN_SCHLAG VERB_SCHIESSEN OBJECT durch PRONOMEN_POSSESSIV NOUN_BODY!", /* EN pline("A%s electric shock shoots through your body!", */
			      (Shock_resistance) ? "" : " massiver"); /* EN (Shock_resistance) ? "n" : " massive"); */
			losehp(Shock_resistance ? rnd(6) : rnd(30),
			       "ADJEKTIV_ELEKTRISCH NOUN_STUHL", KILLED_BY_AN); /* EN "electric chair", KILLED_BY_AN); */
			exercise(A_CON, FALSE);
			break;
		    case 4:
			Du_fuehlst_dich("viel, viel besser!"); /* EN You_feel("much, much better!"); */
			if (Upolyd) {
			    if (u.mh >= (u.mhmax - 5))  u.mhmax += 4;
			    u.mh = u.mhmax;
			}
			if(u.uhp >= (u.uhpmax - 5))  u.uhpmax += 4;
			u.uhp = u.uhpmax;
			make_blinded(0L,TRUE);
			make_sick(0L, (char *) 0, FALSE, SICK_ALL);
			heal_legs();
			flags.botl = 1;
			break;
		    case 5:
			take_gold();
			break;
		    case 6:
			if(u.uluck + rn2(5) < 0) {
			    You("VERB_FUEHLEN, NEUER_SATZ SUBJECT_IM_SATZ wie PRONOMEN_POSSESSIV NOUN_LUCK sich ändert."); /* EN You_feel("your luck is changing."); */
			    change_luck(1);
			} else	    makewish();
			break;
		    case 7:
			{
			register int cnt = rnd(10);

			pline("Eine Stimme ertönt:"); /* EN pline("A voice echoes:"); */
			verbalize("Euer Auditorium erwartet Euch bereits, %s!", /* EN verbalize("Thy audience hath been summoned, %s!", */
				  flags.female ? "Gebieterin" : "Gebieter"); /* EN flags.female ? "Dame" : "Sire"); */
			while(cnt--)
			    (void) makemon(courtmon(), u.ux, u.uy, NO_MM_FLAGS);
			break;
			}
		    case 8:
			pline("Eine Stimme ertönt:"); /* EN pline("A voice echoes:"); */
			verbalize("Wie es Euch beliebt, %s...", /* EN verbalize("By thy Imperious order, %s...", */
				  flags.female ? "Gebieterin" : "Gebieter"); /* EN flags.female ? "Dame" : "Sire"); */
			do_genocide(5);	/* REALLY|ONTHRONE, see do_genocide() */
			break;
		    case 9:
			pline("Eine Stimme ertönt:"); /* EN pline("A voice echoes:"); */
	verbalize("SATZBEGINN MODIFIER_VERB_IMPERATIV VERB_SEIN verflucht dafür, NEUER_SATZ dass SUBJECT_IM_SATZ PRONOMEN_PERSONAL OBJECT PRONOMEN_PERSONAL auf diesem allerheiligsten Thron niedergelassen VERB_HABEN!"); /* EN verbalize("A curse upon thee for sitting upon this most holy throne!"); */
			if (Luck > 0)  {
			    make_blinded(Blinded + rn1(100,250),TRUE);
			} else	    rndcurse();
			break;
		    case 10:
			if (Luck < 0 || (HSee_invisible & INTRINSIC))  {
				if (level.flags.nommap) {
					pline(
					"Ein schreckliches Dröhnen erfüllt KASUS_AKKUSATIV PRONOMEN_POSSESSIV NOUN_KOPF!"); /* EN "A terrible drone fills your head!"); */
					make_confused(HConfusion + rnd(30),
									FALSE);
				} else {
					pline("Ein Bild formt sich in KASUS_DATIV PRONOMEN_POSSESSIV NOUN_GEDANKEs."); /* EN pline("An image forms in your mind."); */
					do_mapping();
				}
			} else  {
				Your("NOUN_BLICK klärt sich."); /* EN Your("vision becomes clear."); */
				HSee_invisible |= FROMOUTSIDE;
				newsym(u.ux, u.uy);
			}
			break;
		    case 11:
			if (Luck < 0)  {
			    Du_fuehlst_dich("bedroht."); /* EN You_feel("threatened."); */
			    aggravate();
			} else  {
			    Du_spuerst("einen reißenden Schmerz."); /* EN You_feel("a wrenching sensation."); */
			    tele();		/* teleport him */
			}
			break;
		    case 12:
			Dir_wird("eine Einsicht gewährt!"); /* EN You("are granted an insight!"); */
			if (invent) {
			    /* rn2(5) agrees w/seffects() */
			    identify_pack(rn2(5));
			}
			break;
		    case 13:
			Your("NOUN_VERSTAND verknotet sich zu einer Bretzel!"); /* EN Your("mind turns into a pretzel!"); */
			make_confused(HConfusion + rn1(7,16),FALSE);
			break;
		    default:	impossible("throne effect");
				break;
		}
	    } else {
		if (is_prince(youmonst.data))
		    Du_fuehlst_dich("hier sehr wohl."); /* EN You_feel("very comfortable here."); */
		else
		    Du_fuehlst_dich("irgendwie fehl am Platz ..."); /* EN You_feel("somehow out of place..."); */
	    }

	    if (!rn2(3) && IS_THRONE(levl[u.ux][u.uy].typ)) {
		/* may have teleported */
		levl[u.ux][u.uy].typ = ROOM;
		pline_The("NOUN_THRON VERB_AUFLOESEN sich in ein Logikwölkchen SATZKLAMMER."); /* EN pline_The("throne vanishes in a puff of logic."); */
		newsym(u.ux,u.uy);
	    }

	} else if (lays_eggs(youmonst.data)) {
		struct obj *uegg;

		if (!flags.female) {
			pline("Männchen können keine Eier legen!"); /* EN pline("Males can't lay eggs!"); */
			return 0;
		}

		if (u.uhunger < (int)objects[EGG].oc_nutrition) {
			You("VERB_HAVE nicht genug Energie um ein Ei zu legen."); /* EN You("don't have enough energy to lay an egg."); */
			return 0;
		}

		uegg = mksobj(EGG, FALSE, FALSE);
		uegg->spe = 1;
		uegg->quan = 1;
		uegg->owt = weight(uegg);
		uegg->corpsenm = egg_type_from_parent(u.umonnum, FALSE);
		uegg->known = uegg->dknown = 1;
		attach_egg_hatch_timeout(uegg);
		You("VERB_LEGEN ein Ei."); /* EN You("lay an egg."); */
		dropy(uegg);
		stackobj(uegg);
		morehungry((int)objects[EGG].oc_nutrition);
	} else if (u.uswallow)
		pline("Hier gibt es keine Sitzmöglichkeiten!"); /* EN There("are no seats in here!"); */
	else
		pline("Spaß daran, %s zu sitzen?", auf_dem_Boden(u.ux,u.uy)); /* EN pline("Having fun sitting on the %s?", surface(u.ux,u.uy)); */
	return(1);
}
Example #27
0
/* the tsurugi of muramasa or vorpal blade hit someone */
static boolean artifact_hit_behead(struct monst *magr, struct monst *mdef,
			           struct obj *otmp, int *dmgptr, int dieroll)
{
    boolean youattack = (magr == &youmonst);
    boolean youdefend = (mdef == &youmonst);
    boolean vis = (!youattack && magr && cansee(magr->mx, magr->my))
	|| (!youdefend && cansee(mdef->mx, mdef->my))
	|| (youattack && u.uswallow && mdef == u.ustuck && !Blind);
    const char *wepdesc;
    char hittee[BUFSZ];

    strcpy(hittee, youdefend ? "you" : mon_nam(mdef));
    
    /* We really want "on a natural 20" but Nethack does it in reverse from AD&D. */
    if (otmp->oartifact == ART_TSURUGI_OF_MURAMASA && dieroll == 1) {
	wepdesc = "The razor-sharp blade";
	/* not really beheading, but so close, why add another SPFX */
	if (youattack && u.uswallow && mdef == u.ustuck) {
	    pline("You slice %s wide open!", mon_nam(mdef));
	    *dmgptr = 2 * mdef->mhp + FATAL_DAMAGE_MODIFIER;
	    return TRUE;
	}
	if (!youdefend) {
		/* allow normal cutworm() call to add extra damage */
		if (notonhead)
		    return FALSE;

		if (bigmonst(mdef->data)) {
			if (youattack)
				pline("You slice deeply into %s!",
					mon_nam(mdef));
			else if (vis)
				pline("%s cuts deeply into %s!",
					Monnam(magr), hittee);
			*dmgptr *= 2;
			return TRUE;
		}
		*dmgptr = 2 * mdef->mhp + FATAL_DAMAGE_MODIFIER;
		pline("%s cuts %s in half!", wepdesc, mon_nam(mdef));
		otmp->dknown = TRUE;
		return TRUE;
	} else {
		if (bigmonst(youmonst.data)) {
			pline("%s cuts deeply into you!",
				magr ? Monnam(magr) : wepdesc);
			*dmgptr *= 2;
			return TRUE;
		}

		/* Players with negative AC's take less damage instead
		    * of just not getting hit.  We must add a large enough
		    * value to the damage so that this reduction in
		    * damage does not prevent death.
		    */
		*dmgptr = 2 * (Upolyd ? u.mh : u.uhp) + FATAL_DAMAGE_MODIFIER;
		pline("%s cuts you in half!", wepdesc);
		otmp->dknown = TRUE;
		return TRUE;
	}
    } else if (otmp->oartifact == ART_VORPAL_BLADE &&
		(dieroll == 1 || mdef->data == &mons[PM_JABBERWOCK])) {
	static const char * const behead_msg[2] = {
		"%s beheads %s!",
		"%s decapitates %s!"
	};

	if (youattack && u.uswallow && mdef == u.ustuck)
		return FALSE;
	wepdesc = artilist[ART_VORPAL_BLADE].name;
	if (!youdefend) {
		if (!has_head(mdef->data) || notonhead || u.uswallow) {
			if (youattack)
				pline("Somehow, you miss %s wildly.",
					mon_nam(mdef));
			else if (vis)
				pline("Somehow, %s misses wildly.",
					mon_nam(magr));
			*dmgptr = 0;
			return (boolean)(youattack || vis);
		}
		if (noncorporeal(mdef->data) || amorphous(mdef->data)) {
			pline("%s slices through %s %s.", wepdesc,
				s_suffix(mon_nam(mdef)),
				mbodypart(mdef,NECK));
			return TRUE;
		}
		*dmgptr = 2 * mdef->mhp + FATAL_DAMAGE_MODIFIER;
		pline(behead_msg[rn2(SIZE(behead_msg))],
			wepdesc, mon_nam(mdef));
		otmp->dknown = TRUE;
		return TRUE;
	} else {
		if (!has_head(youmonst.data)) {
			pline("Somehow, %s misses you wildly.",
				magr ? mon_nam(magr) : wepdesc);
			*dmgptr = 0;
			return TRUE;
		}
		if (noncorporeal(youmonst.data) || amorphous(youmonst.data)) {
			pline("%s slices through your %s.",
				wepdesc, body_part(NECK));
			return TRUE;
		}
		*dmgptr = 2 * (Upolyd ? u.mh : u.uhp)
			    + FATAL_DAMAGE_MODIFIER;
		pline(behead_msg[rn2(SIZE(behead_msg))],
			wepdesc, "you");
		otmp->dknown = TRUE;
		/* Should amulets fall off? */
		return TRUE;
	}
    }
    return FALSE;
}
Example #28
0
/* pick a lock on a chest or door with a given object */
int
pick_lock(struct obj *pick, const struct nh_cmd_arg *arg)
{
    int picktyp, c;
    coord cc;
    schar dx, dy, dz;
    struct rm *door;
    struct obj *otmp;
    const char *qbuf;

    if (!getargdir(arg, NULL, &dx, &dy, &dz))
        return 0;
    cc.x = youmonst.mx + dx;
    cc.y = youmonst.my + dy;
    if (!isok(cc.x, cc.y))
        return 0;

    picktyp = pick->otyp;
    pick->lastused = moves;

    /* Check whether we're resuming an interrupted previous attempt.  For a
       floor pick, we have u.utracked[tos_lock] as a non-zeroobj and dx and dy
       as 0.  For a door, we have u.utracked_location[tl_lock] specifying the
       location and u.utracked[tos_lock] as &zeroobj. */
    if (u.uoccupation_progress[tos_lock] &&
        ((u.utracked_location[tl_lock].x == cc.x &&
          u.utracked_location[tl_lock].y == cc.y &&
          u.utracked[tos_lock] == &zeroobj) ||
         (dx == 0 && dy == 0 && u.utracked[tos_lock] != &zeroobj))) {
        static const char no_longer[] =
            "Unfortunately, you can no longer %s %s.";

        if (nohands(youmonst.data)) {
            const char *what = (picktyp == LOCK_PICK) ? "pick" : "key";

            if (picktyp == CREDIT_CARD)
                what = "card";
            pline(msgc_interrupted, no_longer, "hold the", what);
            return reset_pick();
        } else if (u.utracked[tos_lock] != &zeroobj && !can_reach_floor()) {
            pline(msgc_interrupted, no_longer, "reach the", "lock");
            return reset_pick();
        } else {
            const char *action = lock_action();

            if (turnstate.continue_message)
                pline(msgc_occstart, "You resume your attempt at %s.", action);

            one_occupation_turn(picklock, "picking the lock", occ_lock);
            return 1;
        }
    }

    if (nohands(youmonst.data)) {
        pline(msgc_cancelled, "You can't hold %s -- you have no hands!",
              doname(pick));
        return 0;
    }

    if ((picktyp != LOCK_PICK && picktyp != CREDIT_CARD &&
         picktyp != SKELETON_KEY)) {
        impossible("picking lock with object %d?", picktyp);
        return 0;
    }

    if (!dx && !dy) { /* pick lock on a container */
        const char *verb;
        boolean it;
        int count;

        if (dz < 0) {
            pline(msgc_cancelled, "There isn't any sort of lock up %s.",
                  Levitation ? "here" : "there");
            return 0;
        } else if (is_lava(level, youmonst.mx, youmonst.my)) {
            pline(msgc_cancelled, "Doing that would probably melt your %s.",
                  xname(pick));
            return 0;
        } else if (is_pool(level, youmonst.mx, youmonst.my) && !Underwater) {
            /* better YAFM - AIS */
            pline(msgc_cancelled,
                  "Canals might have locks, but this water doesn't.");
            return 0;
        }

        count = 0;
        c = 'n';        /* in case there are no boxes here */
        for (otmp = level->objects[cc.x][cc.y]; otmp; otmp = otmp->nexthere)
            if (Is_box(otmp)) {
                ++count;
                if (!can_reach_floor()) {
                    pline(msgc_cancelled, "You can't reach %s from up here.",
                          the(xname(otmp)));
                    return 0;
                }
                it = 0;
                if (otmp->obroken)
                    verb = "fix";
                else if (!otmp->olocked)
                    verb = "lock", it = 1;
                else if (picktyp != LOCK_PICK)
                    verb = "unlock", it = 1;
                else
                    verb = "pick";
                qbuf = msgprintf(
                    "There is %s here, %s %s?",
                    safe_qbuf("",
                              sizeof ("There is  here, unlock its lock?"),
                              doname(otmp), an(simple_typename(otmp->otyp)),
                              "a box"), verb, it ? "it" : "its lock");

                c = ynq(qbuf);
                if (c == 'q')
                    return 0;
                if (c == 'n')
                    continue;

                if (otmp->obroken) {
                    pline(msgc_cancelled,
                          "You can't fix its broken lock with %s.",
                          doname(pick));
                    return 0;
                } else if (picktyp == CREDIT_CARD && !otmp->olocked) {
                    /* credit cards are only good for unlocking */
                    pline(msgc_cancelled, "You can't do that with %s.",
                          doname(pick));
                    return 0;
                }

                u.utracked[tos_lock] = otmp;
                u.uoccupation_progress[tos_lock] = 0;
                break;
            }
        if (c != 'y') {
            if (!count)
                pline(msgc_cancelled,
                      "There doesn't seem to be any sort of lock here.");
            return 0;   /* decided against all boxes */
        }
    } else {    /* pick the lock in a door */
        struct monst *mtmp;

        if (u.utrap && u.utraptype == TT_PIT) {
            pline(msgc_cancelled,
                  "You can't reach over the edge of the pit.");
            return 0;
        }

        door = &level->locations[cc.x][cc.y];
        if ((mtmp = m_at(level, cc.x, cc.y)) && canseemon(mtmp)) {
            if (picktyp == CREDIT_CARD &&
                (mx_eshk(mtmp) || mtmp->data == &mons[PM_ORACLE]))
                verbalize(msgc_npcvoice, "No checks, no credit, no problem.");
            else
                pline(msgc_mispaste, "I don't think %s would appreciate that.",
                      mon_nam(mtmp));
            return 0;
        }
        if (mtmp && (mtmp->m_ap_type == M_AP_FURNITURE) &&
            (mtmp->mappearance == S_hcdoor || mtmp->mappearance == S_vcdoor) &&
            !Protection_from_shape_changers) {
            stumble_onto_mimic(mtmp, dx, dy);
            return 1;
        }
        if (!IS_DOOR(door->typ)) {
            if (is_drawbridge_wall(cc.x, cc.y) >= 0)
                pline(msgc_cancelled, "You %s no lock on the drawbridge.",
                      Blind ? "feel" : "see");
            else
                pline(msgc_mispaste, "You %s no door there.",
                      Blind ? "feel" : "see");
            return 0;
        }
        switch (door->doormask) {
        case D_NODOOR:
            pline(msgc_cancelled, "This doorway has no door.");
            return 0;
        case D_ISOPEN:
            pline(msgc_cancelled, "You cannot lock an open door.");
            return 0;
        case D_BROKEN:
            pline(msgc_cancelled, "This door is broken.");
            return 0;
        default:
            /* credit cards are only good for unlocking */
            if (picktyp == CREDIT_CARD && !(door->doormask & D_LOCKED)) {
                pline(msgc_cancelled,
                      "You can't lock a door with a credit card.");
                return 0;
            }

            /* At this point, the player knows that the door is a door, and
               whether it's locked, but not whether it's trapped; to do this,
               we set the mem_door_l flag and call map_background, which will
               clear it if necessary (i.e. not a door after all). */
            level->locations[cc.x][cc.y].mem_door_l = 1;
            map_background(cc.x, cc.y, TRUE);

            u.utracked[tos_lock] = &zeroobj;
            u.utracked_location[tl_lock] = cc;
            u.uoccupation_progress[tos_lock] = 0;
        }
    }

    one_occupation_turn(picklock, "picking the lock", occ_lock);
    return 1;
}
Example #29
0
static const char *e_nam(struct entity *etmp)
{
	return is_u(etmp)? "you" : mon_nam(etmp->emon);
}
Example #30
0
STATIC_OVL const char *
e_nam(struct entity *etmp)
{
    return(is_u(etmp)? "you" : mon_nam(etmp->emon));
}