/*
 * rloc_to()
 *
 * Pulls a monster from its current position and places a monster at a new x and
 * y.  If oldx is COLNO, then the monster was not in the levels.monsters array.
 * However, if oldx is COLNO, oldy may still have a value because mtmp is a
 * migrating_mon.  Worm tails are always placed randomly around the head of the
 * worm.  This only works for monsters on the current level.
 */
void
rloc_to(struct monst *mtmp, int x, int y)
{
    int oldx = mtmp->mx, oldy = mtmp->my;
    boolean resident_shk = mtmp->isshk && inhishop(mtmp);

    if (x == mtmp->mx && y == mtmp->my) /* that was easy */
        return;

    if (oldx != COLNO) { /* "pick up" monster */
        if (mtmp->wormno)
            remove_worm(mtmp);
        else {
            remove_monster(mtmp->dlevel, oldx, oldy);
            if (mtmp->dlevel == level)
                newsym(oldx, oldy); /* update old location */
        }
    }

    place_monster(mtmp, x, y);  /* put monster down */
    update_monster_region(mtmp);

    if (mtmp->wormno)   /* now put down tail */
        place_worm_tail_randomly(mtmp, x, y, rng_main);

    if (u.ustuck == mtmp) { /* implies mtmp->dlevel == level */
        if (Engulfed) {
            u.ux = x;
            u.uy = y;
            doredraw();
        } else
            u.ustuck = 0;
    }

    if (mtmp->dlevel == level)
        newsym(x, y);       /* update new location */
    set_apparxy(mtmp);  /* orient monster */

    /* In some cases involving migration, the player and monster are currently
       on the same square. One of them will move, but we don't want the monster
       to have itself in its muxy. */
    if (mtmp->mux == mtmp->mx && mtmp->muy == mtmp->my) {
        mtmp->mux = COLNO;
        mtmp->muy = ROWNO;
    }

    /* shopkeepers will only teleport if you zap them with a wand of
       teleportation or if they've been transformed into a jumpy monster; the
       latter only happens if you've attacked them with polymorph */
    if (resident_shk && !inhishop(mtmp))
        make_angry_shk(mtmp, oldx, oldy);
}
Exemple #2
0
/*
 * rloc_to()
 *
 * Pulls a monster from its current position and places a monster at
 * a new x and y.  If oldx is 0, then the monster was not in the levels.monsters
 * array.  However, if oldx is 0, oldy may still have a value because mtmp is a
 * migrating_mon.  Worm tails are always placed randomly around the head of
 * the worm.
 */
void
rloc_to(struct monst *mtmp, int x, int y)
{
    int oldx = mtmp->mx, oldy = mtmp->my;
    boolean resident_shk = mtmp->isshk && inhishop(mtmp);

    if (x == mtmp->mx && y == mtmp->my) /* that was easy */
        return;

    if (oldx) { /* "pick up" monster */
        if (mtmp->wormno)
            remove_worm(mtmp);
        else {
            remove_monster(level, oldx, oldy);
            newsym(oldx, oldy); /* update old location */
        }
    }

    place_monster(mtmp, x, y);  /* put monster down */
    update_monster_region(mtmp);

    if (mtmp->wormno)   /* now put down tail */
        place_worm_tail_randomly(mtmp, x, y);

    if (u.ustuck == mtmp) {
        if (u.uswallow) {
            u.ux = x;
            u.uy = y;
            doredraw();
        } else
            u.ustuck = 0;
    }

    newsym(x, y);       /* update new location */
    set_apparxy(mtmp);  /* orient monster */

    /* shopkeepers will only teleport if you zap them with a wand of
       teleportation or if they've been transformed into a jumpy monster; the
       latter only happens if you've attacked them with polymorph */
    if (resident_shk && !inhishop(mtmp))
        make_angry_shk(mtmp, oldx, oldy);
}