Exemplo n.º 1
0
/*
 * Request a game command from the uI and carry out whatever actions
 * go along with it.
 */
void process_command(cmd_context ctx, bool no_request)
{
	int idx;
	game_command cmd;

	/* If we've got a command to process, do it. */
	if (cmd_get(ctx, &cmd, !no_request) == 0)
	{
		idx = cmd_idx(cmd.command);

		if (idx == -1) return;

		/* Do some sanity checking on those arguments that might have
		   been declared as "unknown", such as directions and targets. */
		switch (cmd.command)
		{
			case CMD_WALK:
			case CMD_RUN:
			case CMD_JUMP:
			case CMD_OPEN:
			case CMD_CLOSE:
			case CMD_TUNNEL:
			case CMD_DISARM:
			case CMD_BASH:
			case CMD_ALTER:
			case CMD_JAM:
			case CMD_MAKE_TRAP:
			{
				/* Direction hasn't been specified, so we ask for one. */
				if (cmd.args[0].direction == DIR_UNKNOWN)
				{
					if (!get_rep_dir(&cmd.args[0].direction))
						return;
				}

				break;
			}

			/*
			 * These take an item number and a  "target" as arguments,
			 * though a target isn't always actually needed, so we'll
			 * only prompt for it via callback if the item being used needs it.
			 */
			case CMD_USE_WAND:
			case CMD_USE_ROD:
			case CMD_QUAFF:
			case CMD_ACTIVATE:
			case CMD_READ_SCROLL:
			case CMD_FIRE:
			case CMD_THROW:
			case CMD_STEAL:
			{
				bool get_target = FALSE;

				if (cmd.command == CMD_FIRE ||
					cmd.command == CMD_THROW ||
					obj_needs_aim(object_from_item_idx(cmd.args[0].choice)))
				{
					if (cmd.args[1].direction == DIR_UNKNOWN)
						get_target = TRUE;

					if (cmd.args[1].direction == DIR_TARGET && !target_okay())
						get_target = TRUE;
				}

				if (get_target && !get_aim_dir(&cmd.args[1].direction, FALSE))
						return;

				break;
			}

			/* This takes a choice and a direction. */
			case CMD_CAST:
			{
				bool get_target = FALSE;

				if (spell_needs_aim(cp_ptr->spell_book, cmd.args[0].choice))
				{
					if (cmd.args[1].direction == DIR_UNKNOWN)
						get_target = TRUE;

					if (cmd.args[1].direction == DIR_TARGET && !target_okay())
						get_target = TRUE;

				}

				if (get_target && !get_aim_dir(&cmd.args[1].direction, FALSE))
						return;

				break;
			}

			default:
			{
				/* I can see the point of the compiler warning, but still... */
				break;
			}
		}

		/* Command repetition */
		if (game_cmds[idx].repeat_allowed)
		{
			/* Auto-repeat */
			if (game_cmds[idx].auto_repeat_n > 0 && p_ptr->command_arg == 0 && p_ptr->command_rep == 0)
				p_ptr->command_arg = game_cmds[idx].auto_repeat_n;

			allow_repeated_command();
		}

		repeat_prev_allowed = TRUE;

		if (game_cmds[idx].fn)
			game_cmds[idx].fn(cmd.command, cmd.args);
	}
}
Exemplo n.º 2
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);
}