Esempio n. 1
0
/* The player kicks or whips the steed */
void
kick_steed(void)
{
    char He[4];

    if (!u.usteed)
        return;

    /* [ALI] Various effects of kicking sleeping/paralyzed steeds */
    if (u.usteed->msleeping || !u.usteed->mcanmove) {
        /* We assume a message has just been output of the form "You kick
           <steed>." */
        strcpy(He, mhe(u.usteed));
        *He = highc(*He);
        if ((u.usteed->mcanmove || u.usteed->mfrozen) && !rn2(2)) {
            if (u.usteed->mcanmove)
                u.usteed->msleeping = 0;
            else if (u.usteed->mfrozen > 2)
                u.usteed->mfrozen -= 2;
            else {
                u.usteed->mfrozen = 0;
                u.usteed->mcanmove = 1;
            }
            if (u.usteed->msleeping || !u.usteed->mcanmove)
                pline("%s stirs.", He);
            else
                pline("%s rouses %sself!", He, mhim(u.usteed));
        } else
            pline("%s does not respond.", He);
        return;
    }

    /* Make the steed less tame and check if it resists */
    if (u.usteed->mtame)
        u.usteed->mtame--;
    if (!u.usteed->mtame && u.usteed->mleashed)
        m_unleash(u.usteed, TRUE);
    if (!u.usteed->mtame ||
            (u.ulevel + u.usteed->mtame < rnd(MAXULEV / 2 + 5))) {
        newsym(u.usteed->mx, u.usteed->my);
        dismount_steed(DISMOUNT_THROWN);
        return;
    }

    pline("%s gallops!", Monnam(u.usteed));
    u.ugallop += rn1(20, 30);
    return;
}
Esempio n. 2
0
/*
   If dmg is zero, then the monster is not casting at you.
   If the monster is intentionally not casting at you, we have previously
   called spell_would_be_useless() and spellnum should always be a valid
   undirected spell.
   If you modify either of these, be sure to change is_undirected_spell()
   and spell_would_be_useless().
 */
static void cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
{
    if (dmg == 0 && !is_undirected_spell(AD_SPEL, spellnum)) {
	impossible("cast directed wizard spell (%d) with dmg=0?", spellnum);
	return;
    }

    switch (spellnum) {
    case MGC_DEATH_TOUCH:
	pline("Oh no, %s's using the touch of death!", mhe(mtmp));
	if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
	    pline("You seem no deader than before.");
	} else if (!Antimagic && rn2(mtmp->m_lev) > 12) {
	    if (Hallucination) {
		pline("You have an out of body experience.");
	    } else {
		killer_format = KILLED_BY_AN;
		killer = "touch of death";
		done(DIED);
	    }
	} else {
	    if (Antimagic) shieldeff(u.ux, u.uy);
	    pline("Lucky for you, it didn't work!");
	}
	dmg = 0;
	break;
    case MGC_CLONE_WIZ:
	if (mtmp->iswiz && flags.no_of_wizards == 1) {
	    pline("Double Trouble...");
	    clonewiz();
	    dmg = 0;
	} else
	    impossible("bad wizard cloning?");
	break;
    case MGC_SUMMON_MONS:
    {
	int count;

	count = nasty(mtmp);	/* summon something nasty */
	if (mtmp->iswiz)
	    verbalize("Destroy the thief, my pet%s!", plur(count));
	else {
	    const char *mappear =
		(count == 1) ? "A monster appears" : "Monsters appear";

	    /* messages not quite right if plural monsters created but
	       only a single monster is seen */
	    if (Invisible && !perceives(mtmp->data) &&
				    (mtmp->mux != u.ux || mtmp->muy != u.uy))
		pline("%s around a spot near you!", mappear);
	    else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy))
		pline("%s around your displaced image!", mappear);
	    else
		pline("%s from nowhere!", mappear);
	}
	dmg = 0;
	break;
    }
    case MGC_AGGRAVATION:
	pline("You feel that monsters are aware of your presence.");
	aggravate();
	dmg = 0;
	break;
    case MGC_CURSE_ITEMS:
	pline("You feel as if you need some help.");
	rndcurse();
	dmg = 0;
	break;
    case MGC_DESTRY_ARMR:
	if (Antimagic) {
	    shieldeff(u.ux, u.uy);
	    pline("A field of force surrounds you!");
	} else if (!destroy_arm(some_armor(&youmonst))) {
	    pline("Your skin itches.");
	}
	dmg = 0;
	break;
    case MGC_WEAKEN_YOU:		/* drain strength */
	if (Antimagic) {
	    shieldeff(u.ux, u.uy);
	    pline("You feel momentarily weakened.");
	} else {
	    pline("You suddenly feel weaker!");
	    dmg = mtmp->m_lev - 6;
	    if (Half_spell_damage) dmg = (dmg + 1) / 2;
	    losestr(rnd(dmg));
	    if (u.uhp < 1)
		done_in_by(mtmp);
	}
	dmg = 0;
	break;
    case MGC_DISAPPEAR:		/* makes self invisible */
	if (!mtmp->minvis && !mtmp->invis_blkd) {
	    if (canseemon(mtmp))
		pline("%s suddenly %s!", Monnam(mtmp),
		      !See_invisible ? "disappears" : "becomes transparent");
	    mon_set_minvis(mtmp);
	    dmg = 0;
	} else
	    impossible("no reason for monster to cast disappear spell?");
	break;
    case MGC_STUN_YOU:
	if (Antimagic || Free_action) {
	    shieldeff(u.ux, u.uy);
	    if (!Stunned)
		pline("You feel momentarily disoriented.");
	    make_stunned(1L, FALSE);
	} else {
	    pline(Stunned ? "You struggle to keep your balance." : "You reel...");
	    dmg = dice(ACURR(A_DEX) < 12 ? 6 : 4, 4);
	    if (Half_spell_damage) dmg = (dmg + 1) / 2;
	    make_stunned(HStun + dmg, FALSE);
	}
	dmg = 0;
	break;
    case MGC_HASTE_SELF:
	mon_adjust_speed(mtmp, 1, NULL);
	dmg = 0;
	break;
    case MGC_CURE_SELF:
	if (mtmp->mhp < mtmp->mhpmax) {
	    if (canseemon(mtmp))
		pline("%s looks better.", Monnam(mtmp));
	    /* note: player healing does 6d4; this used to do 1d8 */
	    if ((mtmp->mhp += dice(3,6)) > mtmp->mhpmax)
		mtmp->mhp = mtmp->mhpmax;
	    dmg = 0;
	}
	break;
    case MGC_PSI_BOLT:
	/* prior to 3.4.0 Antimagic was setting the damage to 1--this
	   made the spell virtually harmless to players with magic res. */
	if (Antimagic) {
	    shieldeff(u.ux, u.uy);
	    dmg = (dmg + 1) / 2;
	}
	if (dmg <= 5)
	    pline("You get a slight %sache.", body_part(HEAD));
	else if (dmg <= 10)
	    pline("Your brain is on fire!");
	else if (dmg <= 20)
	    pline("Your %s suddenly aches painfully!", body_part(HEAD));
	else
	    pline("Your %s suddenly aches very painfully!", body_part(HEAD));
	break;
    default:
	impossible("mcastu: invalid magic spell (%d)", spellnum);
	dmg = 0;
	break;
    }

    if (dmg) mdamageu(mtmp, dmg);
}
Esempio n. 3
0
void invault(void) {
    struct monst *guard;
    int trycount, vaultroom = (int)vault_occupied(u.urooms);

    if (!vaultroom) {
        u.uinvault = 0;
        return;
    }

    vaultroom -= ROOMOFFSET;

    guard = findgd();
    if (++u.uinvault % 30 == 0 && !guard) { /* if time ok and no guard now. */
        char buf[BUFSZ];
        int x, y, dd, gx, gy;
        int lx = 0, ly = 0;
        /* first find the goal for the guard */
        for (dd = 2; (dd < ROWNO || dd < COLNO); dd++) {
            for (y = u.uy - dd; y <= u.uy + dd; ly = y, y++) {
                if (y < 0 || y > ROWNO - 1)
                    continue;
                for (x = u.ux - dd; x <= u.ux + dd; lx = x, x++) {
                    if (y != u.uy - dd && y != u.uy + dd && x != u.ux - dd)
                        x = u.ux + dd;
                    if (x < 1 || x > COLNO - 1)
                        continue;
                    if (levl[x][y].typ == CORR) {
                        if (x < u.ux)
                            lx = x + 1;
                        else if (x > u.ux)
                            lx = x - 1;
                        else
                            lx = x;
                        if (y < u.uy)
                            ly = y + 1;
                        else if (y > u.uy)
                            ly = y - 1;
                        else
                            ly = y;
                        if (levl[lx][ly].typ != STONE && levl[lx][ly].typ != CORR)
                            goto incr_radius;
                        goto fnd;
                    }
                }
            }
            incr_radius: ;
        }
        impossible("Not a single corridor on this level??");
        tele();
        return;
        fnd: gx = x;
        gy = y;

        /* next find a good place for a door in the wall */
        x = u.ux;
        y = u.uy;
        if (levl[x][y].typ != ROOM) { /* player dug a door and is in it */
            if (levl[x + 1][y].typ == ROOM)
                x = x + 1;
            else if (levl[x][y + 1].typ == ROOM)
                y = y + 1;
            else if (levl[x - 1][y].typ == ROOM)
                x = x - 1;
            else if (levl[x][y - 1].typ == ROOM)
                y = y - 1;
            else if (levl[x + 1][y + 1].typ == ROOM) {
                x = x + 1;
                y = y + 1;
            } else if (levl[x - 1][y - 1].typ == ROOM) {
                x = x - 1;
                y = y - 1;
            } else if (levl[x + 1][y - 1].typ == ROOM) {
                x = x + 1;
                y = y - 1;
            } else if (levl[x - 1][y + 1].typ == ROOM) {
                x = x - 1;
                y = y + 1;
            }
        }
        while (levl[x][y].typ == ROOM) {
            int dx, dy;

            dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
            dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
            if (abs(gx - x) >= abs(gy - y))
                x += dx;
            else
                y += dy;
        }
        if (x == u.ux && y == u.uy) {
            if (levl[x + 1][y].typ == HWALL || levl[x + 1][y].typ == DOOR)
                x = x + 1;
            else if (levl[x - 1][y].typ == HWALL || levl[x - 1][y].typ == DOOR)
                x = x - 1;
            else if (levl[x][y + 1].typ == VWALL || levl[x][y + 1].typ == DOOR)
                y = y + 1;
            else if (levl[x][y - 1].typ == VWALL || levl[x][y - 1].typ == DOOR)
                y = y - 1;
            else
                return;
        }

        /* make something interesting happen */
        if (!(guard = makemon(&mons[PM_GUARD], x, y, NO_MM_FLAGS)))
            return;
        guard->isgd = 1;
        guard->mpeaceful = 1;
        set_malign(guard);
        EGD(guard)->gddone = 0;
        EGD(guard)->ogx = x;
        EGD(guard)->ogy = y;
        assign_level(&(EGD(guard)->gdlevel), &u.uz);
        EGD(guard)->vroom = vaultroom;
        EGD(guard)->warncnt = 0;

        reset_faint(); /* if fainted - wake up */
        if (canspotmon(guard)) {
            char name[BUFSZ];
            g_monnam(name, BUFSZ, guard);
            pline("Suddenly one of the Vault's %s enters!", makeplural(name));
        } else {
            pline("Someone else has entered the Vault.");
        }
        newsym(guard->mx, guard->my);
        if (youmonst.m_ap_type == M_AP_OBJECT || u.uundetected) {
            if (youmonst.m_ap_type == M_AP_OBJECT && youmonst.mappearance != GOLD_PIECE)
                verbalize("Hey! Who left that %s in here?", mimic_obj_name(&youmonst));
            /* You're mimicking some object or you're hidden. */
            pline("Puzzled, %s turns around and leaves.", mhe(guard));
            mongone(guard);
            return;
        }
        if (Strangled|| is_silent(youmonst.data) || multi < 0) {
            /* [we ought to record whether this this message has already
             been given in order to vary it upon repeat visits, but
             discarding the monster and its egd data renders that hard] */
            verbalize("I'll be back when you're ready to speak to me!");
            mongone(guard);
            return;
        }

        stop_occupation(); /* if occupied, stop it *now* */
        trycount = 5;
        do {
            getlin("\"Hello stranger, who are you?\" -", buf);
            (void)mungspaces(buf);
        } while (!letter(buf[0]) && --trycount > 0);

        if (u.ualign.type == A_LAWFUL &&
        /* ignore trailing text, in case player includes character's rank */
        strncmpi(buf, plname, (int)strlen(plname)) != 0) {
            adjalign(-1); /* Liar! */
        }

        if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos") || !strcmpi(buf, "Creosote")) {
            if (!mvitals[PM_CROESUS].died) {
                verbalize("Oh, yes, of course.  Sorry to have disturbed you.");
                mongone(guard);
            } else {
                setmangry(guard);
                verbalize("Back from the dead, are you?  I'll remedy that!");
                /* don't want guard to waste next turn wielding a weapon */
                if (!MON_WEP(guard)) {
                    guard->weapon_check = NEED_HTH_WEAPON;
                    (void)mon_wield_item(guard);
                }
            }
            return;
        }
        verbalize("I don't know you.");
        if (!u.ugold && !hidden_gold())
            verbalize("Please follow me.");
        else {
            if (!u.ugold)
                verbalize("You have hidden gold.");
            verbalize("Most likely all your gold was stolen from this vault.");
            verbalize("Please drop that gold and follow me.");
        }
        EGD(guard)->gdx = gx;
        EGD(guard)->gdy = gy;
        EGD(guard)->fcbeg = 0;
        EGD(guard)->fakecorr[0].fx = x;
        EGD(guard)->fakecorr[0].fy = y;
        if (IS_WALL(levl[x][y].typ))
            EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ;
        else { /* the initial guard location is a dug door */
            int vlt = EGD(guard)->vroom;
            signed char lowx = rooms[vlt].lx, hix = rooms[vlt].hx;
            signed char lowy = rooms[vlt].ly, hiy = rooms[vlt].hy;

            if (x == lowx - 1 && y == lowy - 1)
                EGD(guard)->fakecorr[0].ftyp = TLCORNER;
            else if (x == hix + 1 && y == lowy - 1)
                EGD(guard)->fakecorr[0].ftyp = TRCORNER;
            else if (x == lowx - 1 && y == hiy + 1)
                EGD(guard)->fakecorr[0].ftyp = BLCORNER;
            else if (x == hix + 1 && y == hiy + 1)
                EGD(guard)->fakecorr[0].ftyp = BRCORNER;
            else if (y == lowy - 1 || y == hiy + 1)
                EGD(guard)->fakecorr[0].ftyp = HWALL;
            else if (x == lowx - 1 || x == hix + 1)
                EGD(guard)->fakecorr[0].ftyp = VWALL;
        }
        levl[x][y].typ = DOOR;
        levl[x][y].flags = D_NODOOR;
        unblock_point(x, y); /* doesn't block light */
        EGD(guard)->fcend = 1;
        EGD(guard)->warncnt = 1;
    }
}
Esempio n. 4
0
int main()
{
	USING_NAMESPACE_ACADO

	// Variables:
	DifferentialState	p;		// the trolley position
	DifferentialState v;		// the trolley velocity
	DifferentialState phi;		// the excitation angle
	DifferentialState omega;	// the angular velocity
	Control a;					// the acc. of the trolley

	const double g = 9.81;		// the gravitational constant
	const double b = 0.20;		// the friction coefficient

	// Model equations:
	DifferentialEquation f;

	f << dot( p ) == v;
	f << dot( v ) == a;
	f << dot( phi ) == omega;
	f << dot( omega ) == -g * sin(phi) - a * cos(phi) - b * omega;

	// Measurement functions and weighting matrices:
	Function h, hN;
	h << p << phi << a;
	hN << p << phi;

	ExportVariable W(h.getDim(), h.getDim());
	ExportVariable WN(hN.getDim(), hN.getDim());

	//
	// Optimal Control Problem
	//
	OCP ocp(0.0, 3.0, 10);

	ocp.subjectTo( f );

	ocp.minimizeLSQ(W, h);
	ocp.minimizeLSQEndTerm(WN, hN);

	// Export the code:
	OCPexport mhe( ocp );

	mhe.set( HESSIAN_APPROXIMATION, GAUSS_NEWTON );
	mhe.set( DISCRETIZATION_TYPE, MULTIPLE_SHOOTING );
	mhe.set( INTEGRATOR_TYPE, INT_RK4 );
	mhe.set( NUM_INTEGRATOR_STEPS, 30 );

	// NOTE: Those three options define MHE configuration!
	mhe.set( FIX_INITIAL_STATE, NO );
	mhe.set( SPARSE_QP_SOLUTION, CONDENSING );
	mhe.set( QP_SOLVER, QP_QPOASES );

//	mpc.set( LEVENBERG_MARQUARDT, 1.0e-4 );

	mhe.set( GENERATE_TEST_FILE, NO );
	mhe.set( GENERATE_MAKE_FILE, NO );
	mhe.set( GENERATE_MATLAB_INTERFACE, NO );
	mhe.set( GENERATE_SIMULINK_INTERFACE, YES );

//	mpc.set( USE_SINGLE_PRECISION, YES );

	// Set custom module name:
	mhe.setName("mhe");

	if (mhe.exportCode( "crane_cl_mhe_export" ) != SUCCESSFUL_RETURN)
		exit( EXIT_FAILURE );

	mhe.printDimensionsQP( );

	return EXIT_SUCCESS;
}
Esempio n. 5
0
/* Start riding, with the given monster */
boolean
mount_steed(struct monst * mtmp,        /* The animal */
            boolean force)
{   /* Quietly force this animal */
    struct obj *otmp;
    const struct permonst *ptr;

    /* Sanity checks */
    if (u.usteed) {
        pline("You are already riding %s.", mon_nam(u.usteed));
        return FALSE;
    }

    /* Is the player in the right form? */
    if (Hallucination && !force) {
        pline("Maybe you should find a designated driver.");
        return FALSE;
    }
    /* While riding Wounded_legs refers to the steed's, not the hero's legs.
       That opens up a potential abuse where the player can mount a steed, then
       dismount immediately to heal leg damage, because leg damage is always
       healed upon dismount (Wounded_legs context switch). By preventing a hero
       with Wounded_legs from mounting a steed, the potential for abuse is
       minimized, if not eliminated altogether. */
    if (Wounded_legs) {
        pline("Your %s are in no shape for riding.",
              makeplural(body_part(LEG)));
        if (force && wizard && yn("Heal your legs?") == 'y')
            LWounded_legs = RWounded_legs = 0;
        else
            return FALSE;
    }

    if (Upolyd &&
            (!humanoid(youmonst.data) || verysmall(youmonst.data) ||
             bigmonst(youmonst.data) || slithy(youmonst.data))) {
        pline("You won't fit on a saddle.");
        return FALSE;
    }
    if (!force && (near_capacity() > SLT_ENCUMBER)) {
        pline("You can't do that while carrying so much stuff.");
        return FALSE;
    }

    /* Can the player reach and see the monster? */
    if (!mtmp ||
            (!force &&
             ((Blind && !Blind_telepat) || mtmp->mundetected ||
              mtmp->m_ap_type == M_AP_FURNITURE ||
              mtmp->m_ap_type == M_AP_OBJECT))) {
        pline("I see nobody there.");
        return FALSE;
    }

    struct test_move_cache cache;
    init_test_move_cache(&cache);

    if (Engulfed || u.ustuck || u.utrap || Punished ||
            !test_move(u.ux, u.uy, mtmp->mx - u.ux, mtmp->my - u.uy, 0,
                       TEST_MOVE, &cache)) {
        if (Punished || !(Engulfed || u.ustuck || u.utrap))
            pline("You are unable to swing your %s over.", body_part(LEG));
        else
            pline("You are stuck here for now.");
        return FALSE;
    }

    /* Is this a valid monster? */
    otmp = which_armor(mtmp, os_saddle);
    if (!otmp) {
        pline("%s is not saddled.", Monnam(mtmp));
        return FALSE;
    }
    ptr = mtmp->data;
    if (touch_petrifies(ptr) && !Stone_resistance) {
        pline("You touch %s.", mon_nam(mtmp));
        instapetrify(killer_msg(STONING,
                                msgcat("attempting to ride ", an(mtmp->data->mname))));
    }
    if (!mtmp->mtame || mtmp->isminion) {
        pline("I think %s would mind.", mon_nam(mtmp));
        return FALSE;
    }
    if (mtmp->mtrapped) {
        struct trap *t = t_at(level, mtmp->mx, mtmp->my);

        pline("You can't mount %s while %s's trapped in %s.", mon_nam(mtmp),
              mhe(mtmp), t ? an(trapexplain[t->ttyp - 1]) : "ice");
        return FALSE;
    }

    if (!force && !Role_if(PM_KNIGHT) && !(--mtmp->mtame)) {
        /* no longer tame */
        newsym(mtmp->mx, mtmp->my);
        pline("%s resists%s!", Monnam(mtmp),
              mtmp->mleashed ? " and its leash comes off" : "");
        if (mtmp->mleashed)
            m_unleash(mtmp, FALSE);
        return FALSE;
    }
    if (!force && Underwater && !is_swimmer(ptr)) {
        pline("You can't ride that creature while under water.");
        return FALSE;
    }
    if (!can_saddle(mtmp) || !can_ride(mtmp)) {
        pline("You can't ride such a creature.");
        return 0;
    }

    /* Is the player impaired? */
    if (!force && !is_floater(ptr) && !is_flyer(ptr) && Levitation &&
            !Lev_at_will) {
        pline("You cannot reach %s.", mon_nam(mtmp));
        return FALSE;
    }
    if (!force && uarm && is_metallic(uarm) && greatest_erosion(uarm)) {
        pline("Your %s armor is too stiff to be able to mount %s.",
              uarm->oeroded ? "rusty" : "corroded", mon_nam(mtmp));
        return FALSE;
    }
    if (!force &&
            (Confusion || Fumbling || Glib || Wounded_legs || otmp->cursed ||
             ((u.ulevel + mtmp->mtame < rnd(MAXULEV / 2 + 5)) &&
              (!Role_if(PM_KNIGHT))))) {
        if (Levitation) {
            pline("%s slips away from you.", Monnam(mtmp));
            return FALSE;
        }
        pline("You slip while trying to get on %s.", mon_nam(mtmp));

        const char *buf = msgcat(
                              "slipped while mounting ",
                              /* "a saddled mumak" or "a saddled pony called Dobbin" */
                              x_monnam(mtmp, ARTICLE_A, NULL,
                                       SUPPRESS_IT | SUPPRESS_INVISIBLE |
                                       SUPPRESS_HALLUCINATION, TRUE));
        losehp(rn1(5, 10), buf);
        return FALSE;
    }

    /* Success */
    maybewakesteed(mtmp);
    if (!force) {
        if (Levitation && !is_floater(ptr) && !is_flyer(ptr))
            /* Must have Lev_at_will at this point */
            pline("%s magically floats up!", Monnam(mtmp));
        pline("You mount %s.", mon_nam(mtmp));
    }
    /* setuwep handles polearms differently when you're mounted */
    if (uwep && is_pole(uwep))
        u.bashmsg = TRUE;
    u.usteed = mtmp;
    remove_monster(level, mtmp->mx, mtmp->my);
    teleds(mtmp->mx, mtmp->my, TRUE);
    return TRUE;
}
Esempio n. 6
0
void
invault(void)
{
    struct monst *guard;
    int trycount, vaultroom = (int)vault_occupied(u.urooms);
    boolean messages = TRUE;

    if (!vaultroom) {
        u.uinvault = 0;
        return;
    }

    vaultroom -= ROOMOFFSET;

    guard = findgd();
    if (++u.uinvault % 30 == 0 && !guard) {  /* if time ok and no guard now. */
        int x, y, gx, gy;
        xchar rx, ry;
        long umoney;
        const char *buf;

        /* first find the goal for the guard */
        if (!find_guard_dest(NULL, &rx, &ry))
            return;
        gx = rx;
        gy = ry;

        /* next find a good place for a door in the wall */
        x = u.ux;
        y = u.uy;
        if (level->locations[x][y].typ != ROOM) {       /* player dug a door
                                                           and is in it */
            if (level->locations[x + 1][y].typ == ROOM)
                x = x + 1;
            else if (level->locations[x][y + 1].typ == ROOM)
                y = y + 1;
            else if (level->locations[x - 1][y].typ == ROOM)
                x = x - 1;
            else if (level->locations[x][y - 1].typ == ROOM)
                y = y - 1;
            else if (level->locations[x + 1][y + 1].typ == ROOM) {
                x = x + 1;
                y = y + 1;
            } else if (level->locations[x - 1][y - 1].typ == ROOM) {
                x = x - 1;
                y = y - 1;
            } else if (level->locations[x + 1][y - 1].typ == ROOM) {
                x = x + 1;
                y = y - 1;
            } else if (level->locations[x - 1][y + 1].typ == ROOM) {
                x = x - 1;
                y = y + 1;
            }
        }
        while (level->locations[x][y].typ == ROOM) {
            int dx, dy;

            dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
            dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
            if (abs(gx - x) >= abs(gy - y))
                x += dx;
            else
                y += dy;
        }
        if (x == u.ux && y == u.uy) {
            if (level->locations[x + 1][y].typ == HWALL ||
                level->locations[x + 1][y].typ == DOOR)
                x = x + 1;
            else if (level->locations[x - 1][y].typ == HWALL ||
                     level->locations[x - 1][y].typ == DOOR)
                x = x - 1;
            else if (level->locations[x][y + 1].typ == VWALL ||
                     level->locations[x][y + 1].typ == DOOR)
                y = y + 1;
            else if (level->locations[x][y - 1].typ == VWALL ||
                     level->locations[x][y - 1].typ == DOOR)
                y = y - 1;
            else
                return;
        }

        /* make something interesting happen */
        if (!(guard = makemon(&mons[PM_GUARD], level, x, y, NO_MM_FLAGS)))
            return;
        guard->isgd = 1;
        msethostility(guard, FALSE, TRUE);
        EGD(guard)->gddone = 0;
        EGD(guard)->ogx = x;
        EGD(guard)->ogy = y;
        assign_level(&(EGD(guard)->gdlevel), &u.uz);
        EGD(guard)->vroom = vaultroom;
        EGD(guard)->warncnt = 0;

        /* We used to reset fainted status here, but that doesn't really make
           sense; instead, that's treated like normal helplessness */
        if (canspotmon(guard))
            pline("Suddenly one of the Vault's guards enters!");
        else if (canhear())
            You_hear("someone else enter the Vault.");
        else
            messages = FALSE;

        newsym(guard->mx, guard->my);
        if (youmonst.m_ap_type == M_AP_OBJECT || u.uundetected || u.uburied) {
            if (youmonst.m_ap_type == M_AP_OBJECT &&
                youmonst.mappearance != GOLD_PIECE)
                verbalize("Hey! Who left that %s in here?",
                          mimic_obj_name(&youmonst));
            /* You're mimicking some object or you're hidden. */
            if (messages)
                pline("Puzzled, %s turns around and leaves.", mhe(guard));
            mongone(guard);
            return;
        }
        if (Engulfed) {
            if ((!u.ustuck->minvis || perceives(guard->data)))
                verbalize("How did that %s get in here?", m_monnam(u.ustuck));
            if (messages)
                pline("Puzzled, %s turns around and leaves.", mhe(guard));
            mongone(guard);
            return;
        }
        if (Strangled || is_silent(youmonst.data) || u_helpless(hm_all)) {
            /* [we ought to record whether this this message has already been
               given in order to vary it upon repeat visits, but discarding the 
               monster and its egd data renders that hard] */
            verbalize("I'll be back when you're ready to speak to me!");
            mongone(guard);
            return;
        }

        action_interrupted();

        trycount = 5;
        do {
            buf = getlin("\"Hello stranger, who are you?\" -", FALSE);
            buf = msgmungspaces(buf);
        } while (!letter(buf[0]) && --trycount > 0);

        if (u.ualign.type == A_LAWFUL &&
            /* ignore trailing text, in case player includes character's rank */
            strncmpi(buf, u.uplname, (int)strlen(u.uplname)) != 0) {
            adjalign(-1);       /* Liar! */
        }

        if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos") ||
            !strcmpi(buf, "Creosote")) {
            if (!mvitals[PM_CROESUS].died) {
                verbalize("Oh, yes, of course.  Sorry to have disturbed you.");
                mongone(guard);
            } else {
                setmangry(guard);
                verbalize("Back from the dead, are you?  I'll remedy that!");
                /* don't want guard to waste next turn wielding a weapon */
                if (!MON_WEP(guard)) {
                    guard->weapon_check = NEED_HTH_WEAPON;
                    mon_wield_item(guard);
                }
            }
            return;
        }
        verbalize("I don't know you.");
        umoney = money_cnt(invent);
        if (!umoney && !hidden_gold())
            verbalize("Please follow me.");
        else {
            if (!umoney)
                verbalize("You have hidden money.");
            verbalize("Most likely all your money was stolen from this vault.");
            verbalize("Please drop that money and follow me.");
        }

        EGD(guard)->gdx = gx;
        EGD(guard)->gdy = gy;
        EGD(guard)->fcbeg = 0;
        EGD(guard)->fakecorr[0].fx = x;
        EGD(guard)->fakecorr[0].fy = y;
        if (IS_WALL(level->locations[x][y].typ))
            EGD(guard)->fakecorr[0].ftyp = level->locations[x][y].typ;
        else {  /* the initial guard location is a dug door */
            int vlt = EGD(guard)->vroom;
            xchar lowx = level->rooms[vlt].lx, hix = level->rooms[vlt].hx;
            xchar lowy = level->rooms[vlt].ly, hiy = level->rooms[vlt].hy;

            if (x == lowx - 1 && y == lowy - 1)
                EGD(guard)->fakecorr[0].ftyp = TLCORNER;
            else if (x == hix + 1 && y == lowy - 1)
                EGD(guard)->fakecorr[0].ftyp = TRCORNER;
            else if (x == lowx - 1 && y == hiy + 1)
                EGD(guard)->fakecorr[0].ftyp = BLCORNER;
            else if (x == hix + 1 && y == hiy + 1)
                EGD(guard)->fakecorr[0].ftyp = BRCORNER;
            else if (y == lowy - 1 || y == hiy + 1)
                EGD(guard)->fakecorr[0].ftyp = HWALL;
            else if (x == lowx - 1 || x == hix + 1)
                EGD(guard)->fakecorr[0].ftyp = VWALL;
        }
        level->locations[x][y].typ = DOOR;
        level->locations[x][y].doormask = D_NODOOR;
        unblock_point(x, y);    /* doesn't block light */
        EGD(guard)->fcend = 1;
        EGD(guard)->warncnt = 1;
    }
}