Exemplo n.º 1
0
        /*
         * Request a "movement" direction (1,2,3,4,6,7,8,9) from the user.
         *
         * Return true if a direction was chosen, otherwise return false.
         *
         * This function should be used for all "repeatable" commands, such as
         * run, walk, open, close, bash, disarm, spike, tunnel, etc, as well
         * as all commands which must reference a grid adjacent to the player,
         * and which may not reference the grid under the player.
         *
         * Directions "5" and "0" are illegal and will not be accepted.
         *
         * This function tracks and uses the "global direction", and uses
         * that as the "desired direction", if it is set.
         */
        public static bool get_rep_dir(out int dp)
        {
            int dir = 0;

            ui_event ke;

            /* Initialize */
            dp = 0;

            /* Get a direction */
            while (dir == 0)
            {
                /* Paranoia XXX XXX XXX */
                Utilities.message_flush();

                /* Get first keypress - the first test is to avoid displaying the
                   prompt for direction if there's already a keypress queued up
                   and waiting - this just avoids a flickering prompt if there is
                   a "lazy" movement delay. */
                Utilities.inkey_scan = Misc.SCAN_INSTANT;
                ke = Utilities.inkey_ex();
                Utilities.inkey_scan = Misc.SCAN_OFF;

                if (ke.type == ui_event_type.EVT_NONE || (ke.type == ui_event_type.EVT_KBRD && Utilities.target_dir(ke.key) == 0))
                {
                    Utilities.prt("Direction or <click> (Escape to cancel)? ", 0, 0);
                    ke = Utilities.inkey_ex();
                }

                /* Check mouse coordinates */
                if (ke.type == ui_event_type.EVT_MOUSE)
                {
                    /*if (ke.button) */
                    {
                        int y = Misc.KEY_GRID_Y(ke);
                        int x = Misc.KEY_GRID_X(ke);
                        Loc from = new Loc(Misc.p_ptr.px, Misc.p_ptr.py);
                        Loc to = new Loc(x, y);

                        throw new NotImplementedException();
                        //dir = pathfind_direction_to(from, to);
                    }
                }

                /* Get other keypresses until a direction is chosen. */
                else if (ke.type == ui_event_type.EVT_KBRD)
                {
                    int keypresses_handled = 0;

                    while (ke.type == ui_event_type.EVT_KBRD && ke.key.code != 0)
                    {
                        int this_dir;

                        if (ke.key.code == keycode_t.ESCAPE)
                        {
                            /* Clear the prompt */
                            Utilities.prt("", 0, 0);

                            return (false);
                        }

                        /* XXX Ideally show and move the cursor here to indicate
                           the currently "Pending" direction. XXX */
                        this_dir = Utilities.target_dir(ke.key);

                        if (this_dir != 0)
                            dir = dir_transitions[dir][this_dir];

                        if (Misc.lazymove_delay == 0 || ++keypresses_handled > 1)
                            break;

                        Utilities.inkey_scan = Misc.lazymove_delay;
                        ke = Utilities.inkey_ex();
                    }

                    /* 5 is equivalent to "escape" */
                    if (dir == 5)
                    {
                        /* Clear the prompt */
                        Utilities.prt("", 0, 0);

                        return (false);
                    }
                }

                /* Oops */
                if (dir == 0) Utilities.bell("Illegal repeatable direction!");
            }

            /* Clear the prompt */
            Utilities.prt("", 0, 0);

            /* Save direction */
            dp = dir;

            /* Success */
            return (true);
        }
Exemplo n.º 2
0
        /* Compute the direction (in the angband 123456789 sense) from a point to a
         * point. We decide to use diagonals if dx and dy are within a factor of two of
         * each other; otherwise we choose a cardinal direction. */
        public static Direction direction_to(Loc from, Loc to)
        {
            int adx = Math.Abs(to.x - from.x);
            int ady = Math.Abs(to.y - from.y);
            int dx = to.x - from.x;
            int dy = to.y - from.y;

            if (dx == 0 && dy == 0)
                return Direction.NONE;

            if (dx >= 0 && dy >= 0)
            {
                if (adx < ady * 2 && ady < adx * 2)
                    return Direction.NE;
                else if (adx > ady)
                    return Direction.E;
                else
                    return Direction.N;
            }
            else if (dx > 0 && dy < 0)
            {
                if (adx < ady * 2 && ady < adx * 2)
                    return Direction.SE;
                else if (adx > ady)
                    return Direction.E;
                else
                    return Direction.S;
            }
            else if (dx < 0 && dy > 0)
            {
                if (adx < ady * 2 && ady < adx * 2)
                    return Direction.NW;
                else if (adx > ady)
                    return Direction.W;
                else
                    return Direction.N;
            }
            else if (dx <= 0 && dy <= 0)
            {
                if (adx < ady * 2 && ady < adx * 2)
                    return Direction.SW;
                else if (adx > ady)
                    return Direction.W;
                else
                    return Direction.S;
            }

            Misc.assert(false);
            return Direction.UNKNOWN;
        }
Exemplo n.º 3
0
        /*
         * Sorting hook -- comp function -- by "distance to player"
         *
         * We use "u" and "v" to point to arrays of "x" and "y" positions,
         * and sort the arrays by double-distance to the player.
         */
        static int cmp_distance(Loc a, Loc b)
        {
            int py = Misc.p_ptr.py;
            int px = Misc.p_ptr.px;
            int da, db, kx, ky;

            /* Absolute distance components */
            kx = a.x; kx -= px; kx = Math.Abs(kx);
            ky = a.y; ky -= py; ky = Math.Abs(ky);

            /* Approximate Double Distance to the first point */
            da = ((kx > ky) ? (kx + kx + ky) : (ky + ky + kx));

            /* Absolute distance components */
            kx = b.x; kx -= px; kx = Math.Abs(kx);
            ky = b.y; ky -= py; ky = Math.Abs(ky);

            /* Approximate Double Distance to the first point */
            db = ((kx > ky) ? (kx + kx + ky) : (ky + ky + kx));

            /* Compare the distances */
            if (da < db)
                return -1;
            if (da > db)
                return 1;
            return 0;
        }