예제 #1
0
void
curse(register struct obj *otmp)
{
#ifdef GOLDOBJ
    if (otmp->oclass == COIN_CLASS) return;
#endif
    otmp->blessed = 0;
    otmp->cursed = 1;
    /* welded two-handed weapon interferes with some armor removal */
    if (otmp == uwep && bimanual(uwep)) reset_remarm();
    /* rules at top of wield.c state that twoweapon cannot be done
       with cursed alternate weapon */
    if (otmp == uswapwep && u.twoweap)
        drop_uswapwep();
    /* some cursed items need immediate updating */
    if (carried(otmp) && confers_luck(otmp))
        set_moreluck();
    else if (otmp->otyp == BAG_OF_HOLDING)
        otmp->owt = weight(otmp);
    else if (otmp->otyp == FIGURINE) {
        if (otmp->corpsenm != NON_PM
                && !dead_species(otmp->corpsenm,TRUE)
                && (carried(otmp) || mcarried(otmp)))
            attach_fig_transform_timeout(otmp);
    }
    return;
}
예제 #2
0
파일: eat.c 프로젝트: msharov/bsd-games
int opentin(void)
{
    if (!carried(tin.tin))     // perhaps it was stolen?
	return 0;	       // %% probably we should use tinoid
    if (tin.usedtime++ >= 50) {
	pline("You give up your attempt to open the tin.");
	return 0;
    }
    if (tin.usedtime < tin.reqtime)
	return 1;	       // still busy

    pline("You succeed in opening the tin.");
    useup(tin.tin);
    unsigned r = rn2(2 * ArraySize(c_tintxts));
    if (r < ArraySize(c_tintxts)) {
	pline(c_tintxts[r].txt);
	lesshungry(c_tintxts[r].nut);
	if (r == 1) {	       // SALMON
	    Glib = rnd(15);
	    pline("Eating salmon made your fingers very slippery.");
	}
    } else {
	pline("It contains spinach - this makes you feel like Popeye!");
	lesshungry(600);
	if (_u.ustr < 118)
	    _u.ustr += rnd(((_u.ustr < 17) ? 19 : 118) - _u.ustr);
	if (_u.ustr > _u.ustrmax)
	    _u.ustrmax = _u.ustr;
	_wflags.botl = 1;
    }
    return 0;
}
예제 #3
0
void
ballfall(void)
{
    boolean gets_hit;

    gets_hit = (((uball->ox != u.ux) || (uball->oy != u.uy)) &&
                ((uwep == uball) ? FALSE : (boolean) rn2(5)));
    if (carried(uball)) {
        pline("Startled, you drop the iron ball.");
        unwield_silently(uball);
        if (uwep != uball)
            freeinv(uball);
    }
    if (gets_hit) {
        int dmg = rn1(7, 25);

        pline("The iron ball falls on your %s.", body_part(HEAD));
        if (uarmh) {
            if (is_metallic(uarmh)) {
                pline("Fortunately, you are wearing a hard helmet.");
                dmg = 3;
            } else if (flags.verbose)
                pline("Your %s does not protect you.", xname(uarmh));
        }
        losehp(dmg, "crunched in the head by an iron ball");
    }
}
예제 #4
0
opentin(){
	register int r;

	if(!carried(tin.tin))		/* perhaps it was stolen? */
		return(0);		/* %% probably we should use tinoid */
	if(tin.usedtime++ >= 50) {
		pline("You give up your attempt to open the tin.");
		return(0);
	}
	if(tin.usedtime < tin.reqtime)
		return(1);		/* still busy */

	pline("You succeed in opening the tin.");
	useup(tin.tin);
	r = rn2(2*TTSZ);
	if(r < TTSZ){
	    pline(tintxts[r].txt);
	    lesshungry(tintxts[r].nut);
	    if(r == 1)	/* SALMON */ {
		Glib = rnd(15);
		pline("Eating salmon made your fingers very slippery.");
	    }
	} else {
	    pline("It contains spinach - this makes you feel like Popeye!");
	    lesshungry(600);
	    if(u.ustr < 118)
		u.ustr += rnd( ((u.ustr < 17) ? 19 : 118) - u.ustr);
	    if(u.ustr > u.ustrmax) u.ustrmax = u.ustr;
	    flags.botl = 1;
	}
	return(0);
}
예제 #5
0
파일: do_name.c 프로젝트: DanielT/NitroHack
struct obj *oname(struct obj *obj, const char *name)
{
	int lth;
	char buf[PL_PSIZ];

	lth = *name ? (int)(strlen(name) + 1) : 0;
	if (lth > PL_PSIZ) {
		lth = PL_PSIZ;
		name = strncpy(buf, name, PL_PSIZ - 1);
		buf[PL_PSIZ - 1] = '\0';
	}
	/* If named artifact exists in the game, do not create another.
	 * Also trying to create an artifact shouldn't de-artifact
	 * it (e.g. Excalibur from prayer). In this case the object
	 * will retain its current name. */
	if (obj->oartifact || (lth && exist_artifact(obj->otyp, name)))
		return obj;

	if (lth == obj->onamelth) {
		/* no need to replace entire object */
		if (lth) strcpy(ONAME(obj), name);
	} else {
		obj = realloc_obj(obj, obj->oxlth,
			      obj->oextra, lth, name);
	}
	if (lth) artifact_exists(obj, name, TRUE);
	if (obj->oartifact) {
	    /* can't dual-wield with artifact as secondary weapon */
	    if (obj == uswapwep) untwoweapon();
	    /* activate warning if you've just named your weapon "Sting" */
	    if (obj == uwep) set_artifact_intrinsic(obj, TRUE, W_WEP);
	}
	if (carried(obj)) update_inventory();
	return obj;
}
예제 #6
0
파일: ball.c 프로젝트: Arc0re/acehack
void
ballfall()
{
	boolean gets_hit;

	gets_hit = (((uball->ox != u.ux) || (uball->oy != u.uy)) &&
		    ((uwep == uball)? FALSE : (boolean)rn2(5)));
	if (carried(uball)) {
		pline("Startled, you drop the iron ball.");
		if (uwep == uball)
			setuwep((struct obj *)0);
		if (uswapwep == uball)
			setuswapwep((struct obj *)0);
		if (uquiver == uball)
			setuqwep((struct obj *)0);;
		if (uwep != uball)
			freeinv(uball);
	}
	if(gets_hit){
		int dmg = rn1(7,25);
		pline_The("iron ball falls on your %s.",
			body_part(HEAD));
		if (uarmh) {
		    if(is_metallic(uarmh)) {
			pline("Fortunately, you are wearing a hard helmet.");
			dmg = 3;
		    } else if (flags.verbose)
			Your("%s does not protect you.", xname(uarmh));
		}
		losehp(dmg, "crunched in the head by an iron ball",
			NO_KILLER_PREFIX);
	}
}
예제 #7
0
파일: ball.c 프로젝트: Arc0re/acehack
/*
 *  Place the ball & chain under the hero.  Make sure that the ball & chain
 *  variables are set (actually only needed when blind, but what the heck).
 *  It is assumed that when this is called, the ball and chain are NOT
 *  attached to the object list.
 *
 *  Should not be called while swallowed.
 */
void
placebc()
{
    if (!uchain || !uball) {
	impossible("Where are your ball and chain?");
	return;
    }

    (void) flooreffects(uchain, u.ux, u.uy, "");	/* chain might rust */

    if (carried(uball))		/* the ball is carried */
	u.bc_order = BCPOS_DIFFER;
    else {
	/* ball might rust -- already checked when carried */
	(void) flooreffects(uball, u.ux, u.uy, "");
	place_object(uball, u.ux, u.uy);
	u.bc_order = BCPOS_CHAIN;
    }

    place_object(uchain, u.ux, u.uy);

    u.bglyph = u.cglyph = levl[u.ux][u.uy].glyph;   /* pick up glyph */

    newsym(u.ux,u.uy);
}
예제 #8
0
파일: mkobj.c 프로젝트: DanielT/NitroHack
void unbless(struct obj *otmp)
{
	otmp->blessed = 0;
	if (carried(otmp) && confers_luck(otmp))
	    set_moreluck();
	else if (otmp->otyp == BAG_OF_HOLDING)
	    otmp->owt = weight(otmp);
}
예제 #9
0
void unplacebc()
{
  if (!carried(uball)) {
    unlink_obj(uball);
    unpobj(uball);
  }
  unlink_obj(uchain);
  unpobj(uchain);
}
예제 #10
0
파일: mkobj.c 프로젝트: DanielT/NitroHack
void uncurse(struct obj *otmp)
{
	otmp->cursed = 0;
	if (carried(otmp) && confers_luck(otmp))
	    set_moreluck();
	else if (otmp->otyp == BAG_OF_HOLDING)
	    otmp->owt = weight(otmp);
	else if (otmp->otyp == FIGURINE && otmp->timed)
	    stop_timer(otmp->olev, FIG_TRANSFORM, otmp);
	return;
}
예제 #11
0
void
drag_down(void)
{
    boolean forward;
    uchar dragchance = 3;

    /* 
     *      Assume that the ball falls forward if:
     *
     *      a) the character is wielding it, or
     *      b) the character has both hands available to hold it (i.e. is
     *         not wielding any weapon), or
     *      c) (perhaps) it falls forward out of his non-weapon hand
     */

    forward = carried(uball) && (uwep == uball || !uwep || !rn2(3));

    if (carried(uball))
        pline("You lose your grip on the iron ball.");

    if (forward) {
        if (rn2(6)) {
            pline("The iron ball drags you downstairs!");
            losehp(rnd(6), "dragged downstairs by an iron ball");
            litter();
        }
    } else {
        if (rn2(2)) {
            pline("The iron ball smacks into you!");
            losehp(rnd(20), killer_msg(DIED, "an iron ball collision"));
            exercise(A_STR, FALSE);
            dragchance -= 2;
        }
        if ((int)dragchance >= rnd(6)) {
            pline("The iron ball drags you downstairs!");
            losehp(rnd(3), "dragged downstairs by an iron ball");
            exercise(A_STR, FALSE);
            litter();
        }
    }
}
예제 #12
0
파일: mkobj.c 프로젝트: DanielT/NitroHack
void bless(struct obj *otmp)
{
	if (otmp->oclass == COIN_CLASS) return;
	otmp->cursed = 0;
	otmp->blessed = 1;
	if (carried(otmp) && confers_luck(otmp))
	    set_moreluck();
	else if (otmp->otyp == BAG_OF_HOLDING)
	    otmp->owt = weight(otmp);
	else if (otmp->otyp == FIGURINE && otmp->timed)
		stop_timer(otmp->olev, FIG_TRANSFORM, otmp);
	return;
}
예제 #13
0
void
bless(register struct obj *otmp)
{
#ifdef GOLDOBJ
    if (otmp->oclass == COIN_CLASS) return;
#endif
    otmp->cursed = 0;
    otmp->blessed = 1;
    if (carried(otmp) && confers_luck(otmp))
        set_moreluck();
    else if (otmp->otyp == BAG_OF_HOLDING)
        otmp->owt = weight(otmp);
    else if (otmp->otyp == FIGURINE && otmp->timed)
        (void) stop_timer(FIG_TRANSFORM, (genericptr_t) otmp);
    return;
}
예제 #14
0
파일: ball.c 프로젝트: Arc0re/acehack
/*
 *  Return the stacking of the hero's ball & chain.  This assumes that the
 *  hero is being punished.
 */
STATIC_OVL int
bc_order()
{
    struct obj *obj;

    if (uchain->ox != uball->ox || uchain->oy != uball->oy || carried(uball)
		|| u.uswallow)
	return BCPOS_DIFFER;

    for (obj = level.objects[uball->ox][uball->oy]; obj; obj = obj->nexthere) {
	if (obj == uchain) return BCPOS_CHAIN;
	if (obj == uball) return BCPOS_BALL;
    }
    impossible("bc_order:  ball&chain not in same location!");
    return BCPOS_DIFFER;
}
예제 #15
0
/*
 *  set_bc()
 *
 *  The hero is either about to go blind or already blind and just punished.
 *  Set up the ball and chain variables so that the ball and chain are "felt".
 */
void
set_bc(int already_blind)
{
    int ball_on_floor = !carried(uball);

    u.bc_order = bc_order();    /* get the order */
    u.bc_felt = ball_on_floor ? BC_BALL | BC_CHAIN : BC_CHAIN;  /* felt */

    if (already_blind || Engulfed) {
        u.cglyph = u.bglyph = level->locations[u.ux][u.uy].mem_obj;
        return;
    }

    /* 
     *  Since we can still see, remove the ball&chain and get the glyph that
     *  would be beneath them.  Then put the ball&chain back.  This is pretty
     *  disgusting, but it will work.
     */
    remove_object(uchain);
    if (ball_on_floor)
        remove_object(uball);

    newsym(uchain->ox, uchain->oy);
    u.cglyph = level->locations[uchain->ox][uchain->oy].mem_obj;

    if (u.bc_order == BCPOS_DIFFER) {   /* different locations */
        place_object(uchain, level, uchain->ox, uchain->oy);
        newsym(uchain->ox, uchain->oy);
        if (ball_on_floor) {
            newsym(uball->ox, uball->oy);       /* see under ball */
            u.bglyph = level->locations[uball->ox][uball->oy].mem_obj;
            place_object(uball, level, uball->ox, uball->oy);
            newsym(uball->ox, uball->oy);       /* restore ball */
        }
    } else {
        u.bglyph = u.cglyph;
        if (u.bc_order == BCPOS_CHAIN) {
            place_object(uball, level, uball->ox, uball->oy);
            place_object(uchain, level, uchain->ox, uchain->oy);
        } else {
            place_object(uchain, level, uchain->ox, uchain->oy);
            place_object(uball, level, uball->ox, uball->oy);
        }
        newsym(uball->ox, uball->oy);
    }
}
예제 #16
0
void placebc(Boolean attach)
{
  if (!uchain || !uball) {
    message("BUG: Where are your chain and ball??");
    return;
  }
  uball->ox = uchain->ox = you.ux;
  uball->oy = uchain->oy = you.uy;
  if (attach) {
    uchain->nobj = fobj;
    fobj = uchain;
    if (!carried(uball)) {
      uball->nobj = fobj;
      fobj = uball;
    }
  }
}
예제 #17
0
void
unplacebc(void)
{
    if (!carried(uball)) {
        obj_extract_self(uball);
        if (Blind && (u.bc_felt & BC_BALL))     /* drop glyph */
            level->locations[uball->ox][uball->oy].mem_obj = u.bglyph;

        newsym(uball->ox, uball->oy);
    }
    obj_extract_self(uchain);
    if (Blind && (u.bc_felt & BC_CHAIN))        /* drop glyph */
        level->locations[uchain->ox][uchain->oy].mem_obj = u.cglyph;

    newsym(uchain->ox, uchain->oy);
    u.bc_felt = 0;      /* feel nothing */
}
예제 #18
0
파일: ball.c 프로젝트: Arc0re/acehack
void
unplacebc()
{
    if (u.uswallow) return;	/* ball&chain not placed while swallowed */

    if (!carried(uball)) {
	obj_extract_self(uball);
	if (Blind && (u.bc_felt & BC_BALL))		/* drop glyph */
	    levl[uball->ox][uball->oy].glyph = u.bglyph;

	newsym(uball->ox,uball->oy);
    }
    obj_extract_self(uchain);
    if (Blind && (u.bc_felt & BC_CHAIN))		/* drop glyph */
	levl[uchain->ox][uchain->oy].glyph = u.cglyph;

    newsym(uchain->ox,uchain->oy);
    u.bc_felt = 0;					/* feel nothing */
}
예제 #19
0
파일: do_name.c 프로젝트: FredrIQ/fiqhack
struct obj *
oname(struct obj *obj, const char *name)
{
    int lth;
    lth = *name ? (int)(strlen(name) + 1) : 0;

    /* If named artifact exists in the game, do not create another. Also trying 
       to create an artifact shouldn't de-artifact it (e.g. Excalibur from
       prayer). In this case the object will retain its current name. */
    if (obj->oartifact || (lth && exist_artifact(obj->otyp, name)))
        return obj;

    christen_obj(obj, name);
    if (lth)
        artifact_exists(obj, name, TRUE);
    if (obj->oartifact) {
        /* can't dual-wield with artifact as secondary weapon */
        if (obj == uswapwep)
            untwoweapon();
    }
    if (carried(obj))
        update_inventory();
    return obj;
}
예제 #20
0
static bool clear_fcorr(struct monst *grd, bool forceshow) {
    int fcx, fcy, fcbeg;
    struct monst *mtmp;

    if (!on_level(&(EGD(grd)->gdlevel), &u.uz))
        return true;

    while ((fcbeg = EGD(grd)->fcbeg) < EGD(grd)->fcend) {
        fcx = EGD(grd)->fakecorr[fcbeg].fx;
        fcy = EGD(grd)->fakecorr[fcbeg].fy;
        if ((grd->mhp <= 0 || !in_fcorridor(grd, u.ux, u.uy)) &&
        EGD(grd)->gddone)
            forceshow = true;
        if ((u.ux == fcx && u.uy == fcy && grd->mhp > 0) || (!forceshow && couldsee(fcx, fcy)) || (Punished && !carried(uball) && uball->ox == fcx && uball->oy == fcy))
            return false;

        if ((mtmp = m_at(fcx, fcy)) != 0) {
            if (mtmp->isgd)
                return (false);
            else if (!in_fcorridor(grd, u.ux, u.uy)) {
                if (mtmp->mtame)
                    yelp(mtmp);
                (void)rloc(mtmp, false);
            }
        }
        levl[fcx][fcy].typ = EGD(grd)->fakecorr[fcbeg].ftyp;
        map_location(fcx, fcy, 1); /* bypass vision */
        if (!ACCESSIBLE(levl[fcx][fcy].typ))
            block_point(fcx, fcy);
        EGD(grd)->fcbeg++;
    }
    if (grd->mhp <= 0) {
        pline_The("corridor disappears.");
        if (IS_ROCK(levl[u.ux][u.uy].typ))
            You("are encased in rock.");
    }
    return (true);
}
예제 #21
0
파일: wield.c 프로젝트: DanielT/NitroHack
/* Maybe rust object, or corrode it if acid damage is called for */
void erode_obj(struct obj *target, /* object (e.g. weapon or armor) to erode */
	       boolean acid_dmg,
	       boolean fade_scrolls)
{
	int erosion;
	struct monst *victim;
	boolean vismon;
	boolean visobj;

	if (!target)
	    return;
	victim = carried(target) ? &youmonst :
	    mcarried(target) ? target->ocarry : NULL;
	vismon = victim && (victim != &youmonst) && canseemon(victim);
	visobj = !victim && cansee(bhitpos.x, bhitpos.y); /* assume thrown */

	erosion = acid_dmg ? target->oeroded2 : target->oeroded;

	if (target->greased) {
	    grease_protect(target,NULL,victim);
	} else if (target->oclass == SCROLL_CLASS) {
	    if (fade_scrolls && target->otyp != SCR_BLANK_PAPER)
	    {
		if (!Blind) {
		    if (victim == &youmonst)
			pline("Your %s.", aobjnam(target, "fade"));
		    else if (vismon)
			pline("%s's %s.", Monnam(victim),
			      aobjnam(target, "fade"));
		    else if (visobj)
			pline("The %s.", aobjnam(target, "fade"));
		}
		target->otyp = SCR_BLANK_PAPER;
		target->spe = 0;
	    }
	} else if (target->oerodeproof ||
		(acid_dmg ? !is_corrodeable(target) : !is_rustprone(target))) {
	    if (flags.verbose || !(target->oerodeproof && target->rknown)) {
		if (victim == &youmonst)
		    pline("Your %s not affected.", aobjnam(target, "are"));
		else if (vismon)
		    pline("%s's %s not affected.", Monnam(victim),
			aobjnam(target, "are"));
		/* no message if not carried */
	    }
	    if (target->oerodeproof) target->rknown = TRUE;
	} else if (erosion < MAX_ERODE) {
	    if (victim == &youmonst)
		pline("Your %s%s!", aobjnam(target, acid_dmg ? "corrode" : "rust"),
		    erosion+1 == MAX_ERODE ? " completely" :
		    erosion ? " further" : "");
	    else if (vismon)
		pline("%s's %s%s!", Monnam(victim),
		    aobjnam(target, acid_dmg ? "corrode" : "rust"),
		    erosion+1 == MAX_ERODE ? " completely" :
		    erosion ? " further" : "");
	    else if (visobj)
		pline("The %s%s!",
		    aobjnam(target, acid_dmg ? "corrode" : "rust"),
		    erosion+1 == MAX_ERODE ? " completely" :
		    erosion ? " further" : "");
	    if (acid_dmg)
		target->oeroded2++;
	    else
		target->oeroded++;
	} else {
	    if (flags.verbose) {
		if (victim == &youmonst)
		    pline("Your %s completely %s.",
			aobjnam(target, Blind ? "feel" : "look"),
			acid_dmg ? "corroded" : "rusty");
		else if (vismon)
		    pline("%s's %s completely %s.", Monnam(victim),
			aobjnam(target, "look"),
			acid_dmg ? "corroded" : "rusty");
		else if (visobj)
		    pline("The %s completely %s.",
			aobjnam(target, "look"),
			acid_dmg ? "corroded" : "rusty");
	    }
	}
}
예제 #22
0
void
teleds(int nux, int nuy, boolean allow_drag)
{
    boolean ball_active = (Punished &&
                           uball->where != OBJ_FREE), ball_still_in_range =
        FALSE;

    /* If they have to move the ball, then drag if allow_drag is true;
       otherwise they are teleporting, so unplacebc(). If they don't have to
       move the ball, then always "drag" whether or not allow_drag is true,
       because we are calling that function, not to drag, but to move the
       chain.  *However* there are some dumb special cases: 0 0 _X move east
       -----> X_ @ @ These are permissible if teleporting, but not if dragging.
       As a result, drag_ball() needs to know about allow_drag and might end up
       dragging the ball anyway.  Also, drag_ball() might find that dragging
       the ball is completely impossible (ball in range but there's rock in the
       way), in which case it teleports the ball on its own. */
    if (ball_active) {
        if (!carried(uball) && distmin(nux, nuy, uball->ox, uball->oy) <= 2)
            ball_still_in_range = TRUE; /* don't have to move the ball */
        else {
            /* have to move the ball */
            if (!allow_drag || distmin(u.ux, u.uy, nux, nuy) > 1) {
                /* we should not have dist > 1 and allow_drag at the same time,
                   but just in case, we must then revert to teleport. */
                allow_drag = FALSE;
                unplacebc();
            }
        }
    }
    u.utrap = 0;
    u.ustuck = 0;
    u.ux0 = u.ux;
    u.uy0 = u.uy;

    if (hides_under(youmonst.data))
        u.uundetected = OBJ_AT(nux, nuy);
    else if (youmonst.data->mlet == S_EEL)
        u.uundetected = is_pool(level, nux, nuy);
    else {
        u.uundetected = 0;
        /* mimics stop being unnoticed */
        if (youmonst.data->mlet == S_MIMIC)
            youmonst.m_ap_type = M_AP_NOTHING;
    }

    if (Engulfed) {
        u.uswldtim = Engulfed = 0;
        if (Punished && !ball_active) {
            /* ensure ball placement, like unstuck */
            ball_active = TRUE;
            allow_drag = FALSE;
        }
        doredraw();
    }
    if (ball_active) {
        if (ball_still_in_range || allow_drag) {
            int bc_control;
            xchar ballx, bally, chainx, chainy;
            boolean cause_delay;

            if (drag_ball
                (nux, nuy, &bc_control, &ballx, &bally, &chainx, &chainy,
                 &cause_delay, allow_drag))
                move_bc(0, bc_control, ballx, bally, chainx, chainy);
        }
    }
    /* must set u.ux, u.uy after drag_ball(), which may need to know the old
       position if allow_drag is true... */
    u.ux = nux;
    u.uy = nuy;
    fill_pit(level, u.ux0, u.uy0);
    if (ball_active) {
        if (!ball_still_in_range && !allow_drag)
            placebc();
    }
    initrack(); /* teleports mess up tracking monsters without this */
    update_player_regions(level);
    /* Move your steed, too */
    if (u.usteed) {
        u.usteed->mx = nux;
        u.usteed->my = nuy;
    }

    /*
     *  Make sure the hero disappears from the old location.  This will
     *  not happen if she is teleported within sight of her previous
     *  location.  Force a full vision recalculation because the hero
     *  is now in a new location.
     */
    newsym(u.ux0, u.uy0);
    see_monsters(FALSE);
    turnstate.vision_full_recalc = TRUE;
    action_interrupted();
    vision_recalc(0);   /* vision before effects */
    spoteffects(TRUE);
    invocation_message();
}
예제 #23
0
static int arti_invoke(struct obj *obj)
{
    const struct artifact *oart = get_artifact(obj);

    if (!oart || !oart->inv_prop) {
        if (obj->oclass == WAND_CLASS)
            return do_break_wand(obj);
        else if (obj->oclass == GEM_CLASS || obj->oclass == TOOL_CLASS)
            return dorub(obj);
	else if (obj->otyp == CRYSTAL_BALL)
	    use_crystal_ball(obj);
	else
	    pline("Nothing happens.");
	return 1;
    }

    if (oart->inv_prop > LAST_PROP) {
	/* It's a special power, not "just" a property */
	if (obj->age > moves) {
	    /* the artifact is tired :-) */
	    pline("You feel that %s %s ignoring you.",
		     the(xname(obj)), otense(obj, "are"));
	    /* and just got more so; patience is essential... */
	    obj->age += (long) dice(3,10);
	    return 1;
	}
	obj->age = moves + rnz(100);

	switch(oart->inv_prop) {
	case TAMING: {
	    struct obj pseudo;
	    boolean unused_known;

	    pseudo = zeroobj;	/* neither cursed nor blessed */
	    pseudo.otyp = SCR_TAMING;
	    seffects(&pseudo, &unused_known);
	    break;
	  }
	case HEALING: {
	    int healamt = (u.uhpmax + 1 - u.uhp) / 2;
	    long creamed = (long)u.ucreamed;

	    if (Upolyd) healamt = (u.mhmax + 1 - u.mh) / 2;
	    if (healamt || Sick || Slimed || Blinded > creamed)
		pline("You feel better.");
	    else
		goto nothing_special;
	    if (healamt > 0) {
		if (Upolyd) u.mh += healamt;
		else u.uhp += healamt;
	    }
	    if (Sick) make_sick(0L,NULL,FALSE,SICK_ALL);
	    if (Slimed) Slimed = 0L;
	    if (Blinded > creamed) make_blinded(creamed, FALSE);
	    iflags.botl = 1;
	    break;
	  }
	case ENERGY_BOOST: {
	    int epboost = (u.uenmax + 1 - u.uen) / 2;
	    if (epboost > 120) epboost = 120;		/* arbitrary */
	    else if (epboost < 12) epboost = u.uenmax - u.uen;
	    if (epboost) {
		pline("You feel re-energized.");
		u.uen += epboost;
		iflags.botl = 1;
	    } else
		goto nothing_special;
	    break;
	  }
	case UNTRAP: {
	    if (!untrap(TRUE)) {
		obj->age = 0; /* don't charge for changing their mind */
		return 0;
	    }
	    break;
	  }
	case CHARGE_OBJ: {
	    struct obj *otmp = getobj(recharge_type, "charge");
	    boolean b_effect;

	    if (!otmp) {
		obj->age = 0;
		return 0;
	    }
	    b_effect = obj->blessed &&
		(Role_switch == oart->role || !oart->role);
	    recharge(otmp, b_effect ? 1 : obj->cursed ? -1 : 0);
	    update_inventory();
	    break;
	  }
	case LEV_TELE:
	    level_tele();
	    break;
	case CREATE_PORTAL: {
	    int i, num_ok_dungeons, last_ok_dungeon = 0;
	    d_level newlev;
	    extern int n_dgns; /* from dungeon.c */
	    struct nh_menuitem *items;
	    items = malloc(n_dgns * sizeof(struct nh_menuitem));

	    num_ok_dungeons = 0;
	    for (i = 0; i < n_dgns; i++) {
		if (!dungeons[i].dunlev_ureached)
		    continue;
		items[num_ok_dungeons].id = i+1;
		items[num_ok_dungeons].accel = 0;
		items[num_ok_dungeons].role = MI_NORMAL;
		items[num_ok_dungeons].selected = FALSE;
		strcpy(items[num_ok_dungeons].caption, dungeons[i].dname);
		num_ok_dungeons++;
		last_ok_dungeon = i;
	    }

	    if (num_ok_dungeons > 1) {
		/* more than one entry; display menu for choices */
		int n;
		int selected[1];

		n = display_menu(items, num_ok_dungeons, "Open a portal to which dungeon?", PICK_ONE, selected);
		free(items);
		if (n <= 0)
		    goto nothing_special;
		
		i = selected[0] - 1;
	    } else {
		free(items);
		i = last_ok_dungeon;	/* also first & only OK dungeon */
	    }

	    /*
	     * i is now index into dungeon structure for the new dungeon.
	     * Find the closest level in the given dungeon, open
	     * a use-once portal to that dungeon and go there.
	     * The closest level is either the entry or dunlev_ureached.
	     */
	    newlev.dnum = i;
	    if (dungeons[i].depth_start >= depth(&u.uz))
		newlev.dlevel = dungeons[i].entry_lev;
	    else
		newlev.dlevel = dungeons[i].dunlev_ureached;
	    if (u.uhave.amulet || In_endgame(&u.uz) || In_endgame(&newlev) ||
	       newlev.dnum == u.uz.dnum) {
		pline("You feel very disoriented for a moment.");
	    } else {
		if (!Blind) pline("You are surrounded by a shimmering sphere!");
		else pline("You feel weightless for a moment.");
		goto_level(&newlev, FALSE, FALSE, FALSE);
	    }
	    break;
	  }
	case ENLIGHTENING:
	    enlightenment(0);
	    break;
	case CREATE_AMMO: {
	    struct obj *otmp = mksobj(level, ARROW, TRUE, FALSE);

	    if (!otmp) goto nothing_special;
	    otmp->blessed = obj->blessed;
	    otmp->cursed = obj->cursed;
	    otmp->bknown = obj->bknown;
	    if (obj->blessed) {
		if (otmp->spe < 0) otmp->spe = 0;
		otmp->quan += rnd(10);
	    } else if (obj->cursed) {
		if (otmp->spe > 0) otmp->spe = 0;
	    } else
		otmp->quan += rnd(5);
	    otmp->owt = weight(otmp);
	    hold_another_object(otmp, "Suddenly %s out.", aobjnam(otmp, "fall"), NULL);
	    break;
	  }
	}
    } else {
	long eprop = (u.uprops[oart->inv_prop].extrinsic ^= W_ARTI),
	     iprop = u.uprops[oart->inv_prop].intrinsic;
	boolean on = (eprop & W_ARTI) != 0; /* true if invoked prop just set */

	if (on && obj->age > moves) {
	    /* the artifact is tired :-) */
	    u.uprops[oart->inv_prop].extrinsic ^= W_ARTI;
	    pline("You feel that %s %s ignoring you.",
		     the(xname(obj)), otense(obj, "are"));
	    /* can't just keep repeatedly trying */
	    obj->age += (long) dice(3,10);
	    return 1;
	} else if (!on) {
	    /* when turning off property, determine downtime */
	    /* arbitrary for now until we can tune this -dlc */
	    obj->age = moves + rnz(100);
	}

	if ((eprop & ~W_ARTI) || iprop) {
nothing_special:
	    /* you had the property from some other source too */
	    if (carried(obj))
		pline("You feel a surge of power, but nothing seems to happen.");
	    return 1;
	}
	switch(oart->inv_prop) {
	case CONFLICT:
	    if (on) pline("You feel like a rabble-rouser.");
	    else pline("You feel the tension decrease around you.");
	    break;
	case LEVITATION:
	    if (on) {
		float_up();
		spoteffects(FALSE);
	    } else float_down(I_SPECIAL|TIMEOUT, W_ARTI);
	    break;
	case INVIS:
	    if (BInvis || Blind) goto nothing_special;
	    newsym(u.ux, u.uy);
	    if (on)
		pline("Your body takes on a %s transparency...",
		     Hallucination ? "normal" : "strange");
	    else
		pline("Your body seems to unfade...");
	    break;
	}
    }

    return 1;
}
예제 #24
0
static boolean
clear_fcorr(struct monst *grd, boolean forceshow)
{
    int fcx, fcy, fcbeg, oldtyp;
    struct monst *mtmp;
    boolean showmsg = FALSE;

    if (!on_level(&(EGD(grd)->gdlevel), &u.uz))
        return TRUE;

    while ((fcbeg = EGD(grd)->fcbeg) < EGD(grd)->fcend) {
        fcx = EGD(grd)->fakecorr[fcbeg].fx;
        fcy = EGD(grd)->fakecorr[fcbeg].fy;
        if ((grd->mhp <= 0 || !in_fcorridor(grd, u.ux, u.uy)) &&
            EGD(grd)->gddone)
            forceshow = TRUE;
        if ((u.ux == fcx && u.uy == fcy && grd->mhp > 0)
            || (!forceshow && couldsee(fcx, fcy)))
            return FALSE;

        if ((Punished && !carried(uball)
             && uball->ox == fcx && uball->oy == fcy)) {
            unplacebc();
            placebc();
        }

        if ((mtmp = m_at(level, fcx, fcy)) != 0) {
            if (mtmp->isgd)
                return FALSE;
            else if (!in_fcorridor(grd, u.ux, u.uy)) {
                if (mtmp->mtame)
                    yelp(mtmp);
                rloc(mtmp, FALSE);
            }
        }
        oldtyp = level->locations[fcx][fcy].typ;
        level->locations[fcx][fcy].typ = EGD(grd)->fakecorr[fcbeg].ftyp;
        if (!ACCESSIBLE(level->locations[fcx][fcy].typ) && ACCESSIBLE(oldtyp)) {
            struct trap *t = t_at(level, fcx, fcy);

            if (couldsee(fcx, fcy))
                showmsg = TRUE;
            if (t)
                deltrap(level, t);
            level->locations[fcx][fcy].lit = FALSE;
            block_point(fcx, fcy);
        }
        map_location(fcx, fcy, 1, FALSE);      /* bypass vision */
        EGD(grd)->fcbeg++;
    }
    if (grd->mhp <= 0) {
        if (showmsg) {
            if (!Blind)
                pline("The corridor disappears.");
            else
                pline("You feel claustrophobic.");
        }
        if (IS_ROCK(level->locations[u.ux][u.uy].typ))
            pline("You are encased in rock.");
    }
    return TRUE;
}
예제 #25
0
/*
 *  move_bc()
 *
 *  Move the ball and chain.  This is called twice for every move.  The first
 *  time to pick up the ball and chain before the move, the second time to
 *  place the ball and chain after the move.  If the ball is carried, this
 *  function should never have BC_BALL as part of its control.
 *
 *  Should not be called while swallowed.
 */
void
move_bc(int before, int control, xchar ballx, xchar bally, xchar chainx,
        xchar chainy)
{
    if (Blind) {
        /* 
         *  The hero is blind.  Time to work hard.  The ball and chain that
         *  are attached to the hero are very special.  The hero knows that
         *  they are attached, so when they move, the hero knows that they
         *  aren't at the last position remembered.  This is complicated
         *  by the fact that the hero can "feel" the surrounding locations
         *  at any time, hence, making one or both of them show up again.
         *  So, we have to keep track of which is felt at any one time and
         *  act accordingly.
         */
        if (!before) {
            if ((control & BC_CHAIN) && (control & BC_BALL)) {
                /* 
                 *  Both ball and chain moved.  If felt, drop glyph.
                 */
                if (u.bc_felt & BC_BALL)
                    level->locations[uball->ox][uball->oy].mem_obj = u.bglyph;
                if (u.bc_felt & BC_CHAIN)
                    level->locations[uchain->ox][uchain->oy].mem_obj = u.cglyph;
                u.bc_felt = 0;

                /* Pick up mem_obj at new location. */
                u.bglyph = level->locations[ballx][bally].mem_obj;
                u.cglyph = level->locations[chainx][chainy].mem_obj;

                movobj(uball, ballx, bally);
                movobj(uchain, chainx, chainy);
            } else if (control & BC_BALL) {
                if (u.bc_felt & BC_BALL) {
                    if (u.bc_order == BCPOS_DIFFER) {   /* ball by itself */
                        level->locations[uball->ox][uball->oy].mem_obj =
                            u.bglyph;
                    } else if (u.bc_order == BCPOS_BALL) {
                        if (u.bc_felt & BC_CHAIN) {    /* know chain is there */
                            map_object(uchain, 0, TRUE);
                        } else {
                            level->locations[uball->ox][uball->oy].mem_obj =
                                u.bglyph;
                        }
                    }
                    u.bc_felt &= ~BC_BALL;      /* no longer feel the ball */
                }

                /* Pick up mem_obj at new position. */
                u.bglyph = (ballx != chainx ||
                            bally != chainy) ?
                    level->locations[ballx][bally].mem_obj : u.cglyph;

                movobj(uball, ballx, bally);
            } else if (control & BC_CHAIN) {
                if (u.bc_felt & BC_CHAIN) {
                    if (u.bc_order == BCPOS_DIFFER) {
                        level->locations[uchain->ox][uchain->oy].mem_obj =
                            u.cglyph;
                    } else if (u.bc_order == BCPOS_CHAIN) {
                        if (u.bc_felt & BC_BALL) {
                            map_object(uball, 0, TRUE);
                        } else {
                            level->locations[uchain->ox][uchain->oy].mem_obj =
                                u.cglyph;
                        }
                    }
                    u.bc_felt &= ~BC_CHAIN;
                }
                /* Pick up mem_obj at new position. */
                u.cglyph = (ballx != chainx ||
                            bally != chainy) ?
                    level->locations[chainx][chainy].mem_obj : u.bglyph;

                movobj(uchain, chainx, chainy);
            }

            u.bc_order = bc_order();    /* reset the order */
        }

    } else {
        /* 
         *  The hero is not blind.  To make this work correctly, we need to
         *  pick up the ball and chain before the hero moves, then put them
         *  in their new positions after the hero moves.
         */
        if (before) {
            if (!control) {
                /* 
                 * Neither ball nor chain is moving, so remember which was
                 * on top until !before.  Use the variable u.bc_order
                 * since it is only valid when blind.
                 */
                u.bc_order = bc_order();
            }

            remove_object(uchain);
            newsym(uchain->ox, uchain->oy);
            if (!carried(uball)) {
                remove_object(uball);
                newsym(uball->ox, uball->oy);
            }
        } else {
            int on_floor = !carried(uball);

            if ((control & BC_CHAIN) ||
                (!control && u.bc_order == BCPOS_CHAIN)) {
                /* If the chain moved or nothing moved & chain on top. */
                if (on_floor)
                    place_object(uball, level, ballx, bally);
                place_object(uchain, level, chainx, chainy); /* chain on top */
            } else {
                place_object(uchain, level, chainx, chainy);
                if (on_floor)
                    place_object(uball, level, ballx, bally);
                /* ball on top */
            }
            newsym(chainx, chainy);
            if (on_floor)
                newsym(ballx, bally);
        }
    }
}
예제 #26
0
/* return TRUE if the caller needs to place the ball and chain down again
 *
 *  Should not be called while swallowed.  Should be called before movement,
 *  because we might want to move the ball or chain to the hero's old position.
 *
 * It is called if we are moving.  It is also called if we are teleporting
 * *if* the ball doesn't move and we thus must drag the chain.  It is not
 * called for ordinary teleportation.
 *
 * allow_drag is only used in the ugly special case where teleporting must
 * drag the chain, while an identical-looking movement must drag both the ball
 * and chain.
 */
boolean
drag_ball(xchar x, xchar y, int *bc_control, xchar * ballx, xchar * bally,
          xchar * chainx, xchar * chainy, boolean * cause_delay,
          boolean allow_drag)
{
    struct trap *t = NULL;
    boolean already_in_rock;

    *ballx = uball->ox;
    *bally = uball->oy;
    *chainx = uchain->ox;
    *chainy = uchain->oy;
    *bc_control = 0;
    *cause_delay = FALSE;

    if (dist2(x, y, uchain->ox, uchain->oy) <= 2) {     /* nothing moved */
        move_bc(1, *bc_control, *ballx, *bally, *chainx, *chainy);
        return TRUE;
    }

    /* only need to move the chain? */
    if (carried(uball) || distmin(x, y, uball->ox, uball->oy) <= 2) {
        xchar oldchainx = uchain->ox, oldchainy = uchain->oy;

        *bc_control = BC_CHAIN;
        move_bc(1, *bc_control, *ballx, *bally, *chainx, *chainy);
        if (carried(uball)) {
            /* move chain only if necessary */
            if (distmin(x, y, uchain->ox, uchain->oy) > 1) {
                *chainx = u.ux;
                *chainy = u.uy;
            }
            return TRUE;
        }
#define CHAIN_IN_MIDDLE(chx, chy) \
    (distmin(x, y, chx, chy) <= 1 && \
     distmin(chx, chy, uball->ox, uball->oy) <= 1)
#define IS_CHAIN_ROCK(x,y) \
    (IS_ROCK(level->locations[x][y].typ) || \
     (IS_DOOR(level->locations[x][y].typ) && \
      (level->locations[x][y].doormask & (D_CLOSED|D_LOCKED))))
/* Don't ever move the chain into solid rock.  If we have to, then instead
 * undo the move_bc() and jump to the drag ball code.  Note that this also
 * means the "cannot carry and drag" message will not appear, since unless we
 * moved at least two squares there is no possibility of the chain position
 * being in solid rock.
 */
#define SKIP_TO_DRAG { *chainx = oldchainx; *chainy = oldchainy; \
    move_bc(0, *bc_control, *ballx, *bally, *chainx, *chainy); \
    goto drag; }
        if (IS_CHAIN_ROCK(u.ux, u.uy) || IS_CHAIN_ROCK(*chainx, *chainy)
            || IS_CHAIN_ROCK(uball->ox, uball->oy))
            already_in_rock = TRUE;
        else
            already_in_rock = FALSE;

        switch (dist2(x, y, uball->ox, uball->oy)) {
            /* two spaces diagonal from ball, move chain inbetween */
        case 8:
            *chainx = (uball->ox + x) / 2;
            *chainy = (uball->oy + y) / 2;
            if (IS_CHAIN_ROCK(*chainx, *chainy) && !already_in_rock)
                SKIP_TO_DRAG;
            break;

            /* player is distance 2/1 from ball; move chain to one of the two
               spaces between @ __ 0 */
        case 5:{
                xchar tempx, tempy, tempx2, tempy2;

                /* find position closest to current position of chain */
                /* no effect if current position is already OK */
                if (abs(x - uball->ox) == 1) {
                    tempx = x;
                    tempx2 = uball->ox;
                    tempy = tempy2 = (uball->oy + y) / 2;
                } else {
                    tempx = tempx2 = (uball->ox + x) / 2;
                    tempy = y;
                    tempy2 = uball->oy;
                }
                if (IS_CHAIN_ROCK(tempx, tempy) &&
                    !IS_CHAIN_ROCK(tempx2, tempy2) && !already_in_rock) {
                    if (allow_drag) {
                        /* Avoid pathological case *if* not teleporting: 0 0_
                           _X move northeast -----> X@ @ */
                        if (dist2(u.ux, u.uy, uball->ox, uball->oy) == 5 &&
                            dist2(x, y, tempx, tempy) == 1)
                            SKIP_TO_DRAG;
                        /* Avoid pathological case *if* not teleporting: 0 0 _X 
                           move east -----> X_ @ @ */
                        if (dist2(u.ux, u.uy, uball->ox, uball->oy) == 4 &&
                            dist2(x, y, tempx, tempy) == 2)
                            SKIP_TO_DRAG;
                    }
                    *chainx = tempx2;
                    *chainy = tempy2;
                } else if (!IS_CHAIN_ROCK(tempx, tempy) &&
                           IS_CHAIN_ROCK(tempx2, tempy2) && !already_in_rock) {
                    if (allow_drag) {
                        if (dist2(u.ux, u.uy, uball->ox, uball->oy) == 5 &&
                            dist2(x, y, tempx2, tempy2) == 1)
                            SKIP_TO_DRAG;
                        if (dist2(u.ux, u.uy, uball->ox, uball->oy) == 4 &&
                            dist2(x, y, tempx2, tempy2) == 2)
                            SKIP_TO_DRAG;
                    }
                    *chainx = tempx;
                    *chainy = tempy;
                } else if (IS_CHAIN_ROCK(tempx, tempy) &&
                           IS_CHAIN_ROCK(tempx2, tempy2) && !already_in_rock) {
                    SKIP_TO_DRAG;
                } else if (dist2(tempx, tempy, uchain->ox, uchain->oy) <
                           dist2(tempx2, tempy2, uchain->ox, uchain->oy) ||
                           ((dist2(tempx, tempy, uchain->ox, uchain->oy) ==
                             dist2(tempx2, tempy2, uchain->ox, uchain->oy)) &&
                            rn2(2))) {
                    *chainx = tempx;
                    *chainy = tempy;
                } else {
                    *chainx = tempx2;
                    *chainy = tempy2;
                }
                break;
            }

            /* ball is two spaces horizontal or vertical from player; move */
            /* chain inbetween *unless* current chain position is OK */
        case 4:
            if (CHAIN_IN_MIDDLE(uchain->ox, uchain->oy))
                break;
            *chainx = (x + uball->ox) / 2;
            *chainy = (y + uball->oy) / 2;
            if (IS_CHAIN_ROCK(*chainx, *chainy) && !already_in_rock)
                SKIP_TO_DRAG;
            break;

            /* ball is one space diagonal from player.  Check for the following 
               special case: @ _ moving southwest becomes @_ 0 0 (This will
               also catch teleporting that happens to resemble this case, but
               oh well.) Otherwise fall through. */
        case 2:
            if (dist2(x, y, uball->ox, uball->oy) == 2 &&
                dist2(x, y, uchain->ox, uchain->oy) == 4) {
                if (uchain->oy == y)
                    *chainx = uball->ox;
                else
                    *chainy = uball->oy;
                if (IS_CHAIN_ROCK(*chainx, *chainy) && !already_in_rock)
                    SKIP_TO_DRAG;
                break;
            }
            /* fall through */
        case 1:
        case 0:
            /* do nothing if possible */
            if (CHAIN_IN_MIDDLE(uchain->ox, uchain->oy))
                break;
            /* otherwise try to drag chain to player's old position */
            if (CHAIN_IN_MIDDLE(u.ux, u.uy)) {
                *chainx = u.ux;
                *chainy = u.uy;
                break;
            }
            /* otherwise use player's new position (they must have teleported,
               for this to happen) */
            *chainx = x;
            *chainy = y;
            break;

        default:
            impossible("bad chain movement");
            break;
        }
#undef SKIP_TO_DRAG
#undef IS_CHAIN_ROCK
#undef CHAIN_IN_MIDDLE
        return TRUE;
    }

drag:

    if (near_capacity() > SLT_ENCUMBER && dist2(x, y, u.ux, u.uy) <= 2) {
        pline("You cannot %sdrag the heavy iron ball.",
              invent ? "carry all that and also " : "");
        action_completed();
        return FALSE;
    }

    if ((is_pool(level, uchain->ox, uchain->oy) &&
         /* water not mere continuation of previous water */
         (level->locations[uchain->ox][uchain->oy].typ == POOL ||
          !is_pool(level, uball->ox, uball->oy) ||
          level->locations[uball->ox][uball->oy].typ == POOL))
        || ((t = t_at(level, uchain->ox, uchain->oy)) &&
            (t->ttyp == PIT || t->ttyp == SPIKED_PIT || t->ttyp == HOLE ||
             t->ttyp == TRAPDOOR))) {

        if (Levitation) {
            pline("You feel a tug from the iron ball.");
            if (t)
                t->tseen = 1;
        } else {
            struct monst *victim;

            pline("You are jerked back by the iron ball!");
            if ((victim = m_at(level, uchain->ox, uchain->oy)) != 0) {
                int tmp;

                tmp = -2 + Luck + find_mac(victim);
                tmp += omon_adj(victim, uball, TRUE);
                if (tmp >= rnd(20))
                    hmon(victim, uball, 1);
                else
                    miss(xname(uball), victim);

            }   /* now check again in case mon died */
            if (!m_at(level, uchain->ox, uchain->oy)) {
                u.ux = uchain->ox;
                u.uy = uchain->oy;
                newsym(u.ux0, u.uy0);
            }
            action_interrupted();

            *bc_control = BC_BALL;
            move_bc(1, *bc_control, *ballx, *bally, *chainx, *chainy);
            *ballx = uchain->ox;
            *bally = uchain->oy;
            move_bc(0, *bc_control, *ballx, *bally, *chainx, *chainy);
            spoteffects(TRUE);
            return FALSE;
        }
    }

    *bc_control = BC_BALL | BC_CHAIN;

    move_bc(1, *bc_control, *ballx, *bally, *chainx, *chainy);
    if (dist2(x, y, u.ux, u.uy) > 2) {
        /* Awful case: we're still in range of the ball, so we thought we could 
           only move the chain, but it turned out that the target square for
           the chain was rock, so we had to drag it instead. But we can't drag
           it either, because we teleported and are more than one square from
           our old position.  Revert to the teleport behavior. */
        *ballx = *chainx = x;
        *bally = *chainy = y;
    } else {
        *ballx = uchain->ox;
        *bally = uchain->oy;
        *chainx = u.ux;
        *chainy = u.uy;
    }
    *cause_delay = TRUE;
    return TRUE;
}