Beispiel #1
0
/**
 * Front-end command which fires at the nearest target with default ammo.
 */
void textui_cmd_fire_at_nearest(void) {
	/* the direction '5' means 'use the target' */
	int i, dir = 5, item = -1;

	/* Require a usable launcher */
	if (!p_ptr->inventory[INVEN_BOW].tval || !p_ptr->state.ammo_tval) {
		msg("You have nothing to fire with.");
		return;
	}

	/* Find first eligible ammo in the quiver */
	for (i = QUIVER_START; i < QUIVER_END; i++) {
		if (p_ptr->inventory[i].tval != p_ptr->state.ammo_tval) continue;
		item = i;
		break;
	}

	/* Require usable ammo */
	if (item < 0) {
		msg("You have no ammunition in the quiver to fire");
		return;
	}

	/* Require foe */
	if (!target_set_closest(TARGET_KILL | TARGET_QUIET)) return;

	/* Fire! */
	cmd_insert(CMD_FIRE);
	cmd_set_arg_item(cmd_get_top(), 0, item);
	cmd_set_arg_target(cmd_get_top(), 1, dir);
}
Beispiel #2
0
/**
 * Front-end command which fires at the nearest target with default ammo.
 */
void do_cmd_fire_at_nearest(void) {
	int i, dir = DIR_TARGET;
	struct object *ammo = NULL;
	struct object *bow = equipped_item_by_slot_name(player, "shooting");

	/* Require a usable launcher */
	if (!bow || !player->state.ammo_tval) {
		msg("You have nothing to fire with.");
		return;
	}

	/* Find first eligible ammo in the quiver */
	for (i = 0; i < z_info->quiver_size; i++) {
		if (!player->upkeep->quiver[i])
			continue;
		if (player->upkeep->quiver[i]->tval != player->state.ammo_tval)
			continue;
		ammo = player->upkeep->quiver[i];
		break;
	}

	/* Require usable ammo */
	if (!ammo) {
		msg("You have no ammunition in the quiver to fire.");
		return;
	}

	/* Require foe */
	if (!target_set_closest(TARGET_KILL | TARGET_QUIET)) return;

	/* Fire! */
	cmdq_push(CMD_FIRE);
	cmd_set_arg_item(cmdq_peek(), "item", ammo);
	cmd_set_arg_target(cmdq_peek(), "target", dir);
}
/**
 * Target closest monster.
 *
 * XXX: Move to using CMD_TARGET_CLOSEST at some point instead of invoking
 * target_set_closest() directly.
 */
void textui_target_closest(void)
{
	if (target_set_closest(TARGET_KILL)) {
		bool visibility;
		int x, y;

		target_get(&x, &y);

		/* Visual cue */
		Term_fresh();
		Term_get_cursor(&visibility);
		(void)Term_set_cursor(TRUE);
		move_cursor_relative(y, x);
		Term_redraw_section(x, y, x, y);

		/* TODO: what's an appropriate amount of time to spend highlighting */
		Term_xtra(TERM_XTRA_DELAY, 150);
		(void)Term_set_cursor(visibility);
	}
}
Beispiel #4
0
/*
 * Get an "aiming direction" (1,2,3,4,6,7,8,9 or 5) from the user.
 *
 * Return TRUE if a direction was chosen, otherwise return FALSE.
 *
 * The direction "5" is special, and means "use current target".
 *
 * This function tracks and uses the "global direction", and uses
 * that as the "desired direction", if it is set.
 *
 * Note that "Force Target", if set, will pre-empt user interaction,
 * if there is a usable target already set.
 *
 * Currently this function applies confusion directly.
 */
bool get_aim_dir(int *dp)
{
    /* Global direction */
    int dir = 0;

    ui_event_data ke;

    cptr p;

    /* Initialize */
    (*dp) = 0;

    /* Hack -- auto-target if requested */
    if (OPT(use_old_target) && target_okay() && !dir)
	dir = 5;

    /* Ask until satisfied */
    while (!dir) {
	/* Choose a prompt */
	if (!target_okay())
	    p = "Direction ('*' or <click> to target, \"'\" for closest, Escape to cancel)? ";
	else
	    p = "Direction ('5' for target, '*' or <click> to re-target, Escape to cancel)? ";

	/* Get a command (or Cancel) */
	if (!get_com_ex(p, &ke))
	    break;

	if (ke.type == EVT_MOUSE) {
	    if (target_set_interactive
		(TARGET_KILL, KEY_GRID_X(ke), KEY_GRID_Y(ke)))
		dir = 5;
	} else if (ke.type == EVT_KBRD) {
	    if (ke.key == '*') {
		/* Set new target, use target if legal */
		if (target_set_interactive(TARGET_KILL, -1, -1))
		    dir = 5;
	    } else if (ke.key == '\'') {
		/* Set to closest target */
		if (target_set_closest(TARGET_KILL))
		    dir = 5;
	    } else if (ke.key == 't' || ke.key == '5' || ke.key == '0'
		       || ke.key == '.') {
		if (target_okay())
		    dir = 5;
	    } else {
		/* Possible direction */
		int keypresses_handled = 0;

		while (ke.key != 0) {
		    int this_dir;

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

		    if (this_dir)
			dir = dir_transitions[dir][this_dir];
		    else
			break;

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

		    /* See if there's a second keypress within the defined
		     * period of time. */
		    inkey_scan = lazymove_delay;
		    ke = inkey_ex();
		}
	    }
	}

	/* Error */
	if (!dir)
	    bell("Illegal aim direction!");
    }

    /* No direction */
    if (!dir)
	return (FALSE);

    /* Save direction */
    (*dp) = dir;

    /* Check for confusion */
    if (p_ptr->timed[TMD_CONFUSED]) {
	/* Random direction */
	dir = ddd[randint0(8)];
    }

    /* Notice confusion */
    if ((*dp) != dir) {
	/* Warn the user */
	msg_print("You are confused.");
    }

    /* Save direction */
    (*dp) = dir;

    /* A "valid" direction was entered */
    return (TRUE);
}
Beispiel #5
0
// Repeat the previous command
// Assumes the command and args were properly saved
void do_cmd_repeat(void)
{
    if (!character_dungeon) return;
    if (!p_ptr->command_previous) return;

    // repeat the previous command
    command_type *command_ptr = &command_info[p_ptr->command_previous];

    // Make sure we are dealing with the same item
    if (command_ptr->cmd_needs & (ARG_ITEM))
    {
        object_type *o_ptr = object_from_item_idx(p_ptr->command_previous_args.item);

        if (o_ptr->k_idx != p_ptr->command_previous_args.k_idx)
        {
            pop_up_message_box("Unable to repeat command.<br>Item has been moved or changed.");
            p_ptr->player_previous_command_wipe();
            return;
        }
    }

    if (p_ptr->command_previous == CMD_CAST)
    {

        if (!spell_needs_aim(cp_ptr->spell_book, p_ptr->command_previous_args.number)) p_ptr->command_previous_args.direction = DIR_UNKNOWN;
        else if (p_ptr->command_previous_args.direction == DIR_CLOSEST)
        {
            int mode = TARGET_QUIET;

            if (!is_trap_spell(cp_ptr->spell_book, p_ptr->command_previous_args.number)) mode |= TARGET_KILL;
            else mode |= TARGET_TRAP;

            if (!target_set_closest(mode)) p_ptr->command_previous_args.direction = DIR_UNKNOWN;
        }
    }

    else if (p_ptr->command_previous == CMD_ITEM_USE)
    {
        object_type *o_ptr = object_from_item_idx(p_ptr->command_previous_args.item);

        if (!obj_needs_aim(o_ptr)) p_ptr->command_previous_args.direction = DIR_UNKNOWN;
        else if (p_ptr->command_previous_args.direction == DIR_CLOSEST)
        {
            int mode = TARGET_QUIET;

            if (!k_info[o_ptr->k_idx].is_trap_object_kind()) mode |= TARGET_KILL;
            else mode |= TARGET_TRAP;

            if (!target_set_closest(mode)) p_ptr->command_previous_args.direction = DIR_UNKNOWN;
        }
    }


    else if (!command_ptr->keep_direction())
    {
        p_ptr->command_previous_args.direction = DIR_UNKNOWN;
    }

    // Get the direction, if necessary
    if (command_ptr->needs_direction())
    {
        if (!get_aim_dir(&p_ptr->command_previous_args.direction, FALSE)) return;
    }

    command_ptr->command_function(p_ptr->command_previous_args);
}
void commands_angband_keyset(int key_press, bool shift_key, bool alt_key, bool ctrl_key, bool meta_key)
{
    bool using_mods = FALSE;
    if (shift_key || alt_key || ctrl_key || meta_key) using_mods = TRUE;

    // Normal mode
    switch (key_press)
    {
        // ESCAPE
        case Qt::Key_Escape:
        {
            ui_center(p_ptr->py, p_ptr->px);
            break;
        }

        // Move down
        case Qt::Key_2:
        case Qt::Key_Down:
        {
            process_move_key(2, shift_key, alt_key, ctrl_key, meta_key);
            break;
        }

        // Move up
        case Qt::Key_8:
        case Qt::Key_Up:
        {
            process_move_key(8, shift_key, alt_key, ctrl_key, meta_key);
            break;
        }

        // Move left
        case Qt::Key_4:
        case Qt::Key_Left:
        {
            process_move_key(4, shift_key, alt_key, ctrl_key, meta_key);
            break;
        }
        // Move right
        case Qt::Key_6:
        case Qt::Key_Right:
        {
            process_move_key(6, shift_key, alt_key, ctrl_key, meta_key);
            break;
        }
        // Move diagonally left and up
        case Qt::Key_7:
        case Qt::Key_Home:
        {
            process_move_key(7, shift_key, alt_key, ctrl_key, meta_key);
            break;
        }
        // Move diagonally right and up
        case Qt::Key_9:
        case Qt::Key_PageUp:
        {
            process_move_key(9, shift_key, alt_key, ctrl_key, meta_key);
            break;
        }
        // Move diagonally left and down
        case Qt::Key_1:
        case Qt::Key_End:
        {
            process_move_key(1, shift_key, alt_key, ctrl_key, meta_key);
            break;
        }
        // Move diagonally right and down
        case Qt::Key_3:
        case Qt::Key_PageDown:
        {
            process_move_key(3, shift_key, alt_key, ctrl_key, meta_key);
            break;
        }
        case Qt::Key_5:
        case Qt::Key_Clear:
        {
            do_cmd_hold();
            break;
        }
        case Qt::Key_A:
        {
            if (alt_key)           do_cmd_wizard_mode();
            else if (shift_key)          do_cmd_activate();
            else if (!using_mods)   do_cmd_aim_wand();
            break;
        }
        case Qt::Key_B:
        {
            if (shift_key)          do_cmd_bash(DIR_UNKNOWN);
            else if (!using_mods)   do_cmd_browse(-1);
            break;
        }
        case Qt::Key_C:
        {
            if (shift_key && alt_key) save_character_file();
            else if (shift_key)     do_cmd_character_screen();
            else if (!using_mods)   do_cmd_close(DIR_UNKNOWN);
            break;
        }
        case Qt::Key_D:
        {
            if (shift_key)          do_cmd_disarm(DIR_UNKNOWN);
            else if (!using_mods)   do_cmd_drop();
            break;
        }
        case Qt::Key_E:
        {
            if (shift_key)          do_cmd_eat_food();
            else if (!using_mods)   do_cmd_all_objects(TAB_EQUIP);
            break;
        }
        case Qt::Key_F:
        {
            if (ctrl_key)           do_cmd_feeling();
            else if (shift_key)     do_cmd_refuel();
            else if (!using_mods)   do_cmd_fire();
            break;
        }
        case Qt::Key_G:
        {
            if (shift_key)          do_cmd_study(-1);
            else if (!using_mods)   do_cmd_pickup_from_pile(FALSE, TRUE);
            break;
        }
        case Qt::Key_H:
        {
            if (!using_mods)        do_cmd_fire_at_nearest();
            break;
        }
        case Qt::Key_I:
        {
            if (shift_key)          do_cmd_examine();
            else if (!using_mods)   do_cmd_all_objects(TAB_INVEN);
            break;
        }
        case Qt::Key_J:
        {
            if (!using_mods)        do_cmd_spike(DIR_UNKNOWN);
            break;
        }
        case Qt::Key_K:
        {
            if (!using_mods)        do_cmd_destroy();
            break;
        }
        case Qt::Key_L:
        {
            if (shift_key)          ui_center(p_ptr->py, p_ptr->px);
            else if (!using_mods)   do_cmd_look();
            break;
        }
        case Qt::Key_M:
        {
            if (shift_key)          break; // TODO - MAP
            else if (!using_mods)   do_cmd_cast(-1);
            break;
        }
        case Qt::Key_N:
        case Qt::Key_0:
        case Qt::Key_Insert:
        {
            if (!using_mods)        do_cmd_repeat();
            break;
        }
        case Qt::Key_O:
        {
            if (shift_key)          do_cmd_make_trap(DIR_UNKNOWN);
            else if (!using_mods)   do_cmd_open(DIR_UNKNOWN);
            break;
        }
        case Qt::Key_P:
        {
            if (ctrl_key)           display_message_log();
            else if (!using_mods)   do_cmd_cast(-1);
            break;
        }
        case Qt::Key_Q:
        {
            if (alt_key)            do_cmd_quest_desc();
            else if (shift_key)     do_cmd_suicide();
            else if (!using_mods)   do_cmd_quaff_potion();
            break;
        }
        case Qt::Key_R:
        {
            if (ctrl_key)           ui_redraw_all();
            else if (shift_key)     do_cmd_rest();
            else if (!using_mods)   do_cmd_read_scroll();
            break;
        }
        case Qt::Key_S:
        {
            if (shift_key)          do_cmd_toggle_search();
            else if (!using_mods)   do_cmd_search();
            break;
        }
        case Qt::Key_T:
        {
            if (shift_key)          do_cmd_tunnel(DIR_UNKNOWN);
            else if (!using_mods)   do_cmd_takeoff();
            break;
        }
        case Qt::Key_U:
        {
            if (!using_mods)        do_cmd_use_staff();
            break;
        }
        case Qt::Key_V:
        {
            if (!using_mods)        do_cmd_throw();
            break;
        }
        case Qt::Key_W:
        {
            if (!using_mods)   do_cmd_wield();
            break;
        }
        case Qt::Key_X:
        {
            if (!using_mods)        do_cmd_swap_weapon();
            break;
        }
        case Qt::Key_Y:
        {
            break;
        }
        case Qt::Key_Z:
        {
            if (!using_mods)        do_cmd_zap_rod();
            break;
        }
        case Qt::Key_Apostrophe:
        case Qt::Key_Asterisk:
        {
            target_set_closest(TARGET_KILL);
            break;
        }
        case Qt::Key_BraceLeft:
        {
            do_cmd_inscribe();
            break;
        }
        case Qt::Key_BraceRight:
        {
            do_cmd_uninscribe();
            break;
        }
        case Qt::Key_Greater:
        {
            do_cmd_go_down();
            break;
        }
        case Qt::Key_Less:
        {
            do_cmd_go_up();
            break;
        }
        case Qt::Key_Period:
        {
            do_cmd_run(DIR_UNKNOWN);
            break;
        }
        case Qt::Key_Plus:
        {
            do_cmd_alter(DIR_UNKNOWN);
            break;
        }
        case Qt::Key_Minus:
        {
            do_cmd_walk(DIR_UNKNOWN, TRUE);
            break;
        }
        case Qt::Key_Underscore:
        case Qt::Key_Comma:
        {
            do_cmd_hold();
            break;
        }
        case Qt::Key_Semicolon:
        {
            do_cmd_walk(DIR_UNKNOWN, FALSE);
            break;
        }
        case Qt::Key_Colon:
        {
            do_cmd_write_note();
            break;
        }
        case Qt::Key_ParenRight:
        {
            save_screenshot(FALSE);
            break;
        }
        case Qt::Key_ParenLeft:
        {
            save_screenshot(TRUE);
            break;
        }
        case Qt::Key_AsciiTilde:
        {
            do_cmd_knowledge_screens();
            break;
        }
        default:
        {
            break;
        }
    }
}
Beispiel #7
0
/*
 * Handle "target" and "look".
 *
 * Note that this code can be called from "get_aim_dir()".
 *
 * Currently, when "flag" is true, that is, when
 * "interesting" grids are being used, and a directional key is used, we
 * only scroll by a single panel, in the direction requested, and check
 * for any interesting grids on that panel.  The "correct" solution would
 * actually involve scanning a larger set of grids, including ones in
 * panels which are adjacent to the one currently scanned, but this is
 * overkill for this function.  XXX XXX
 *
 * Hack -- targeting/observing an "outer border grid" may induce
 * problems, so this is not currently allowed.
 *
 * The player can use the direction keys to move among "interesting"
 * grids in a heuristic manner, or the "space", "+", and "-" keys to
 * move through the "interesting" grids in a sequential manner, or
 * can enter "location" mode, and use the direction keys to move one
 * grid at a time in any direction.  The "t" (set target) command will
 * only target a monster (as opposed to a location) if the monster is
 * target_able and the "interesting" mode is being used.
 *
 * The current grid is described using the "look" method above, and
 * a new command may be entered at any time, but note that if the
 * "TARGET_LOOK" bit flag is set (or if we are in "location" mode,
 * where "space" has no obvious meaning) then "space" will scan
 * through the description of the current grid until done, instead
 * of immediately jumping to the next "interesting" grid.  This
 * allows the "target" command to retain its old semantics.
 *
 * The "*", "+", and "-" keys may always be used to jump immediately
 * to the next (or previous) interesting grid, in the proper mode.
 *
 * The "return" key may always be used to scan through a complete
 * grid description (forever).
 *
 * This command will cancel any old target, even if used from
 * inside the "look" command.
 *
 * 'mode' is one of TARGET_LOOK or TARGET_KILL.
 * 'x' and 'y' are the initial position of the target to be highlighted,
 * or -1 if no location is specified.
 * Returns TRUE if a target has been successfully set, FALSE otherwise.
 */
bool target_set_interactive(int mode, int x, int y)
{
    int py = p_ptr->py;
    int px = p_ptr->px;

    int i, d, target_count;

    bool done = FALSE;
    bool interactive = TRUE;

    u16b path_n;
    u16b path_g[PATH_SIZE];
    u16b path_gx[PATH_SIZE];

    /* Cancel target */
    target_set_monster(0, FALSE);

      /* All grids are selectable */
    if (mode & (TARGET_GRID))
    {
        /* Disable other modes */
        mode &= ~(TARGET_LOOK | TARGET_KILL | TARGET_TRAP);

        /* Disable interesting grids */
       interactive = FALSE;
    }

    /* Prepare the "temp" array */
    target_set_interactive_prepare(mode);

    /* If we haven't been given an initial location, start on the
       player. */
    if ((x == -1 || y == -1) && target_grids.size())
    {
        x = p_ptr->px;
        y = p_ptr->py;
        ui_targeting_show(MODE_TARGETING_INTERACTIVE);
        ui_update_message_label(color_string("Interactive Target Mode", TERM_L_RED));
    }
    /*
     * If we /have/ been given an initial location, make sure we
     * honour it by going into "free targeting" mode.
     */
    else
    {
        if (x == -1 || y == -1)
        {
            x = p_ptr->px;
            y = p_ptr->py;
        }

        interactive = FALSE;
        ui_targeting_show(MODE_TARGETING_MANUAL);
        ui_update_message_label(color_string("Manual Target Mode", TERM_L_RED));
    }


    /* Start near the player */
    target_count = 0;

    /* Interact */
    while (!done)
    {
        /* Interesting grids */
        if (interactive && target_grids.size())
        {
            bool path_drawn = FALSE;
            int yy, xx;

            y = target_grids[target_count].y;
            x = target_grids[target_count].x;

            /* Dummy pointers to send to project_path */
            yy = y;
            xx = x;

            /* Adjust panel if needed */
            ui_ensure(y, x);

            /* Find the path. */
            path_n = project_path(path_g, path_gx, MAX_RANGE, py, px, &yy, &xx, PROJECT_THRU);

            /* Draw the path in "target" mode. If there is one */
            if ((mode & (TARGET_KILL)) && (dungeon_info[y][x].projectable()))
            {
                path_drawn = ui_draw_path(path_n, path_g, y, x);
            }

            ui_show_cursor(y, x);

            /* Describe and Prompt */
            describe_grid_brief(y, x);

            UserInput input = ui_get_input();

            /* Remove the path */
            if (path_drawn) ui_destroy_path();

            ui_show_cursor(-1, -1);

            /* Assume no "direction" */
            d = 0;

            // Use the mouse wheel to go through targets
            if (input.mode == INPUT_MODE_MOUSE_WHEEL)
            {
                if (input.key == Qt::Key_Plus)
                {
                    if (++target_count == target_grids.size()) target_count = 0;
                }
                else if (input.key == Qt::Key_Minus)
                {
                    if (target_count-- == 0)  target_count = target_grids.size() - 1;
                }
                continue;
            }

            // double-click - automatically target if appropriate
            if (input.mode == INPUT_MODE_MOUSE_DOUBLE_CLICK)
            {
                if (!set_selected_target(mode, y, x))
                {
                    target_set_location(y, x);
                }

                done = TRUE;
                continue;

            }

            /*
             * If we click, move the target location to the click and
             * switch to "free targeting" mode by unsetting 'flag'.
             * This means we get some info about wherever we've picked.
             */
            if (input.mode == INPUT_MODE_MOUSE_SINGLE_CLICK)
            {
                // If clicking twice on the same square, accept
                if (input.x == x && input.y == y)
                {
                    if (set_selected_target(mode, y, x)) done = TRUE;
                    continue;
                }

                x = input.x;
                y = input.y;
                ui_update_message_label(color_string("Interactive Target Mode", TERM_L_RED));
                ui_targeting_show(MODE_TARGETING_MANUAL);
                interactive = FALSE;
                continue;
            }

            /* Analyze */
            switch (input.key)
            {
                case Qt::Key_Escape:
                case Qt::Key_X:
                {
                    done = TRUE;
                    break;
                }
                case Qt::Key_C:
                case Qt::Key_Comma:
                {
                    /* Set to closest target */
                    if (target_set_closest(TARGET_KILL)) done = TRUE;
                    break;
                }
                case Qt::Key_Space:
                case Qt::Key_Plus:
                {
                    if (++target_count == target_grids.size()) target_count = 0;
                    break;
                }

                case Qt::Key_Minus:
                {
                    if (target_count-- == 0)  target_count = target_grids.size() - 1;
                    break;
                }
                case Qt::Key_Exclam:
                case Qt::Key_L:
                {
                    GridDialog(y, x);
                    break;
                }
                case Qt::Key_Asterisk:
                case Qt::Key_M:
                {
                    ui_update_message_label(color_string("Manual Target Mode", TERM_L_RED));
                    ui_targeting_show(MODE_TARGETING_MANUAL);
                    interactive = FALSE;
                    break;
                }
                case Qt::Key_Question:
                {
                    do_cmd_list_targeting_commands();
                    break;
                }
                case Qt::Key_H:
                case Qt::Key_5:
                case Qt::Key_Period:
                case Qt::Key_Clear:
                {
                    if (set_selected_target(mode, y, x)) done = TRUE;
                    break;
                }

                default:
                {
                    /* Extract direction */
                    d = target_dir(input);

                    /* Oops */
                    if (!d) message("Illegal command for target mode!");

                    break;
                }
            }

            /* Hack -- move around */
            if (d)
            {
                int old_y = target_grids[target_count].y;
                int old_x = target_grids[target_count].x;

                /* Find a new monster */
                i = target_pick(old_y, old_x, ddy[d], ddx[d]);

                /* Scroll to find interesting grid */
                if (i < 0)
                {
                    QRect vis = visible_dungeon();

                    int old_wy = vis.y();
                    int old_wx = vis.x();

                    /* Change if legal */
                    if (ui_change_panel(d))
                    {
                        /* Recalculate interesting grids */
                        target_set_interactive_prepare(mode);

                        /* Find a new monster */
                        i = target_pick(old_y, old_x, ddy[d], ddx[d]);

                        /* Restore panel if needed */
                        if ((i < 0) && ui_modify_panel(old_wy, old_wx))
                        {
                            /* Recalculate interesting grids */
                            target_set_interactive_prepare(mode);
                        }
                    }
                }

                /* Use interesting grid if found */
                if (i >= 0) target_count = i;
            }
        }

        /* Arbitrary grids */
        else
        {
            bool path_drawn = FALSE;

            /* Dummy pointers to send to project_path */
            int yy = y;
            int xx = x;

            /* Find the path. */
            path_n = project_path(path_g, path_gx, MAX_RANGE, py, px, &yy, &xx, PROJECT_THRU);

            /* Draw the path in "target" mode. If there is one */
            if ((mode & (TARGET_KILL)) && (dungeon_info[y][x].projectable()))
            {
                /* Save target info */
                path_drawn = ui_draw_path(path_n, path_g, y, x);
            }

            describe_grid_brief(y, x);

            ui_show_cursor(y, x);

            UserInput input = ui_get_input();

            /* Remove the path */
            if (path_drawn) ui_destroy_path();

            ui_show_cursor(y, x);

            /* Assume no direction */
            d = 0;

             if (input.mode == INPUT_MODE_MOUSE_WHEEL) continue;

            // double-click - automatically target if appropriate
            if (input.mode == INPUT_MODE_MOUSE_DOUBLE_CLICK)
            {

                if (set_selected_target(mode, y, x)) done = TRUE;
                else
                {
                    message(QString("Illegal target!"));
                }
                break;
            }

            if (input.mode == INPUT_MODE_MOUSE_SINGLE_CLICK)
            {
                /* We only target if we click somewhere where the cursor
                   is already (i.e. a double-click without a time limit) */
                if (input.x == x && input.y == y)
                {
                    target_set_location(y, x);
                    done = TRUE;
                }
                else
                {
                    /* Just move the cursor for now - another click will
                       target. */
                    x = input.x;
                    y = input.y;
                }
                continue;
            }

            /* Analyze the keypress */
            switch (input.key)
            {
                case Qt::Key_Escape:
                case Qt::Key_X:
                {
                    done = TRUE;
                    continue;
                }
                case Qt::Key_Asterisk:
                case Qt::Key_M:
                {
                    if (((mode & (TARGET_GRID)) != TARGET_GRID) && target_grids.size())
                    {
                        ui_update_message_label(color_string("Interactive Target Mode", TERM_L_RED));
                        ui_targeting_show(MODE_TARGETING_INTERACTIVE);
                        interactive = TRUE;
                    }
                    break;
                }
                case Qt::Key_copyright:
                case Qt::Key_C:
                case Qt::Key_Comma:
                {
                    /* Set to closest target */
                    if (target_set_closest(TARGET_KILL)) done = TRUE;
                    break;
                }
                case Qt::Key_Exclam:
                case Qt::Key_L:
                {
                    GridDialog(y, x);
                    break;
                }

                case Qt::Key_Ampersand:
                case Qt::Key_P:
                {
                    /* Recenter around player */
                    ui_center(py, px);

                    y = py;
                    x = px;

                    break;
                }

                case Qt::Key_H:
                case Qt::Key_5:
                case Qt::Key_Period:
                case Qt::Key_Clear:
                {
                    target_set_location(y, x);
                    done = TRUE;
                    break;
                }

                case Qt::Key_Question:
                {
                    do_cmd_list_targeting_commands();
                    break;
                }
                default:
                {
                    /* Extract a direction */
                    d = target_dir(input);

                    /* Oops */
                    if (!d) message("Illegal command for target mode!");

                    break;
                }
            }

            /* Handle "direction" */
            if (d)
            {
                int dungeon_hgt = p_ptr->cur_map_hgt;
                int dungeon_wid = p_ptr->cur_map_wid;

                /* Move */
                x += ddx[d];
                y += ddy[d];

                /* Slide into legality */
                if (x >= dungeon_wid - 1) x--;
                else if (x <= 0) x++;

                /* Slide into legality */
                if (y >= dungeon_hgt - 1) y--;
                else if (y <= 0) y++;

                /* Adjust panel if needed */
                if (ui_adjust_panel(y, x))
                {
                    /* Recalculate interesting grids */
                    target_set_interactive_prepare(mode);
                }
            }
        }
    }

    /* Forget */
    target_grids.clear();

    ui_targeting_hide();

    /* Recenter around player */
    ui_ensure(py, px);

    /* Failure to set target */
    if (!p_ptr->target_set) return (FALSE);

    /* Success */
    return (TRUE);
}
Beispiel #8
0
/*
 * Get an "aiming direction" (1,2,3,4,6,7,8,9 or 5) from the user.
 *
 * Return TRUE if a direction was chosen, otherwise return FALSE.
 *
 * The direction "5" is special, and means "use current target". Also DIR_TARGET
 *
 * This function tracks and uses the "global direction", and uses
 * that as the "desired direction", if it is set.
 *
 * Note that "Force Target", if set, will pre-empt user interaction,
 * if there is a usable target already set.
 *
 * Currently this function applies confusion directly.
 */
bool get_aim_dir(int *dp, bool target_trap)
{
    /* Global direction */
    int dir = 0;
    int old_dir;

    bool done = FALSE;

    int mode = TARGET_QUIET;

    if (target_trap) mode |= TARGET_TRAP;
    else mode |= TARGET_KILL;

    if (*dp == DIR_CLOSEST)
    {
        if (target_set_closest(mode))
        {
            return(TRUE);
        }
    }

    /* Initialize */
    (*dp) = 0;

    /* Hack -- auto-target if requested */
    if (use_old_target && target_okay() && !dir) dir = DIR_TARGET;

    else ui_update_message_label(color_string("Please select a target.", TERM_L_RED));

    ui_targeting_show(MODE_TARGETING_AIMING);

    /* Ask until satisfied */
    while (!dir && !done)
    {
        ui_show_cursor(p_ptr->py, p_ptr->px);        

        /* Get a command (or Cancel) */
        UserInput input = ui_get_input();

        // Paranoia
        if (input.mode == INPUT_MODE_NONE) break;

        if ((input.key == Qt::Key_Escape) || (input.key == Qt::Key_X))
        {
            break;
        }
        // Do nothing
        if (input.mode == INPUT_MODE_MOUSE_WHEEL)
        {
            continue;
        }

        // Skip interactive mode and directly choose target.
        if (input.mode == INPUT_MODE_MOUSE_DOUBLE_CLICK)
        {
            if (set_selected_target(mode, input.y, input.x)) dir = DIR_TARGET;
            else if (set_selected_target(TARGET_GRID, input.y, input.x)) dir = DIR_TARGET;
            continue;
        }

        if (input.mode == INPUT_MODE_MOUSE_SINGLE_CLICK)
        {
            /* Calculate approximate angle */
            if (target_set_interactive(mode, input.x, input.y)) dir = DIR_TARGET;
            else done = TRUE;
            continue;
        }

        /* Analyze */
        switch (input.key)
        {
            case Qt::Key_M:
            case Qt::Key_Asterisk:
            {
                /* Set new target, use target if legal */
                int mode = TARGET_KILL;
                if (target_trap) mode |= TARGET_TRAP;
                if (target_set_interactive(mode, -1, -1)) dir = DIR_TARGET;
                else done = TRUE;
                continue;
            }
            case Qt::Key_C:
            case Qt::Key_Comma:
            {
                /* Set to closest target */
                if (target_set_closest(TARGET_KILL))
                {
                    dir = DIR_CLOSEST;
                    continue;
                }
                break;
            }
            case Qt::Key_Question:
            {
                do_cmd_list_targeting_commands();
                continue;
            }
            case Qt::Key_H:
            case Qt::Key_5:
            case Qt::Key_Period:
            case Qt::Key_Clear:
            {
                /* Use current target, if set and legal */
                if (target_okay()) dir = DIR_TARGET;
                break;
            }
            default:
            {
                /* Possible direction */
                dir = target_dir(input);
                break;
            }
        }

        /* Error */
        if (!dir) color_message("Illegal aim direction!", TERM_ORANGE);
    }

    ui_targeting_hide();

    ui_show_cursor(-1, -1);

    ui_clear_message_label();

    /* No direction */
    if (!dir) return (FALSE);

    /* Save the direction */
    old_dir = dir;

    /* Check for confusion */
    if (p_ptr->timed[TMD_CONFUSED])
    {
        /* Random direction */
        dir = ddd[randint0(8)];
    }

    /* Notice confusion */
    if (old_dir != dir)
    {
        /* Warn the user */
        message(QString("You are confused."));
    }

    /* Save direction */
    (*dp) = dir;

    /* A "valid" direction was entered */
    return (TRUE);
}
Beispiel #9
0
/**
 * Get an "aiming direction" (1,2,3,4,6,7,8,9 or 5) from the user.
 *
 * Return true if a direction was chosen, otherwise return false.
 *
 * The direction "5" is special, and means "use current target".
 *
 * This function tracks and uses the "global direction", and uses
 * that as the "desired direction", if it is set.
 *
 * Note that "Force Target", if set, will pre-empt user interaction,
 * if there is a usable target already set.
 */
bool textui_get_aim_dir(int *dp)
{
    /* Global direction */
    int dir = 0;

    ui_event ke;

    const char *p;

    /* Initialize */
    (*dp) = 0;

    /* Hack -- auto-target if requested */
    if (OPT(use_old_target) && target_okay() && !dir) dir = 5;

    /* Ask until satisfied */
    while (!dir) {
        /* Choose a prompt */
        if (!target_okay())
            p = "Direction ('*' or <click> to target, \"'\" for closest, Escape to cancel)? ";
        else
            p = "Direction ('5' for target, '*' or <click> to re-target, Escape to cancel)? ";

        /* Get a command (or Cancel) */
        if (!get_com_ex(p, &ke)) break;

        if (ke.type == EVT_MOUSE) {
            if (ke.mouse.button == 1) {
                if (target_set_interactive(TARGET_KILL, KEY_GRID_X(ke),
                                           KEY_GRID_Y(ke)))
                    dir = 5;
            } else if (ke.mouse.button == 2) {
                break;
            }
        } else if (ke.type == EVT_KBRD) {
            if (ke.key.code == '*') {
                /* Set new target, use target if legal */
                if (target_set_interactive(TARGET_KILL, -1, -1))
                    dir = 5;
            } else if (ke.key.code == '\'') {
                /* Set to closest target */
                if (target_set_closest(TARGET_KILL))
                    dir = 5;
            } else if (ke.key.code == 't' || ke.key.code == '5' ||
                       ke.key.code == '0' || ke.key.code == '.') {
                if (target_okay())
                    dir = 5;
            } else {
                /* Possible direction */
                int keypresses_handled = 0;

                while (ke.key.code != 0) {
                    int this_dir;

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

                    if (this_dir)
                        dir = dir_transitions[dir][this_dir];
                    else
                        break;

                    if (op_ptr->lazymove_delay == 0 || ++keypresses_handled > 1)
                        break;

                    /* See if there's a second keypress within the defined
                     * period of time. */
                    inkey_scan = op_ptr->lazymove_delay;
                    ke = inkey_ex();
                }
            }
        }

        /* Error */
        if (!dir) bell("Illegal aim direction!");
    }

    /* No direction */
    if (!dir) return (false);

    /* Save direction */
    (*dp) = dir;

    /* A "valid" direction was entered */
    return (true);
}
Beispiel #10
0
void do_cmd_target_closest(void)
{
	target_set_closest(TARGET_KILL);
}