Ejemplo n.º 1
0
/**
 * Get input for the rest command
 */
void textui_cmd_rest(void)
{
	const char *p = "Rest (0-9999, '!' for HP or SP, '*' for HP and SP, '&' as needed): ";

	char out_val[5] = "& ";

	/* Ask for duration */
	if (!get_string(p, out_val, sizeof(out_val))) return;

	/* Rest... */
	if (out_val[0] == '&') {
		/* ...until done */
		cmdq_push(CMD_REST);
		cmd_set_arg_choice(cmdq_peek(), "choice", REST_COMPLETE);
	} else if (out_val[0] == '*') {
		/* ...a lot */
		cmdq_push(CMD_REST);
		cmd_set_arg_choice(cmdq_peek(), "choice", REST_ALL_POINTS);
	} else if (out_val[0] == '!') {
		/* ...until HP or SP filled */
		cmdq_push(CMD_REST);
		cmd_set_arg_choice(cmdq_peek(), "choice", REST_SOME_POINTS);
	} else {
		/* ...some */
		int turns = atoi(out_val);
		if (turns <= 0) return;
		if (turns > 9999) turns = 9999;

		cmdq_push(CMD_REST);
		cmd_set_arg_choice(cmdq_peek(), "choice", turns);
	}
}
Ejemplo n.º 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);
}
Ejemplo n.º 3
0
int test_drop_eat(void *state) {
	int num = 0;

	/* Load the saved game */
	eq(savefile_load("Test1", FALSE), TRUE);
	num = player->upkeep->inven[0]->number;

	cmdq_push(CMD_WALK);
	cmd_set_arg_direction(cmdq_peek(), "direction", 4);
	run_game_loop();
	cmdq_push(CMD_DROP);
	cmd_set_arg_item(cmdq_peek(), "item", player->upkeep->inven[0]);
	cmd_set_arg_number(cmdq_peek(), "quantity",
					   player->upkeep->inven[0]->number);
	run_game_loop();
	eq(square_object(cave, player->py, player->px)->number, num);
	cmdq_push(CMD_EAT);
	cmd_set_arg_item(cmdq_peek(), "item",
					 square_object(cave, player->py, player->px));
	run_game_loop();
	if (num > 1) {
		eq(square_object(cave, player->py, player->px)->number, num - 1);
	} else {
		eq(square_object(cave, player->py, player->px), NULL);
	}

	ok;
}
Ejemplo n.º 4
0
int test_newgame(void *state) {

	/* Try making a new game */

	cmdq_push(CMD_BIRTH_INIT);
	cmdq_push(CMD_BIRTH_RESET);
	cmdq_push(CMD_CHOOSE_RACE);
	cmd_set_arg_choice(cmdq_peek(), "choice", 0);

	cmdq_push(CMD_CHOOSE_CLASS);
	cmd_set_arg_choice(cmdq_peek(), "choice", 0);

	cmdq_push(CMD_ROLL_STATS);
	cmdq_push(CMD_NAME_CHOICE);
	cmd_set_arg_string(cmdq_peek(), "name", "Tester");

	cmdq_push(CMD_ACCEPT_CHARACTER);
	cmdq_execute(CMD_BIRTH);

	eq(player->is_dead, FALSE);
	cave_generate(&cave, player);
	on_new_level();
	noteq(cave, NULL);
	eq(player->chp, player->mhp);
	eq(player->food, PY_FOOD_FULL - 1);

	/* Should be all set up to save properly now */
	eq(savefile_save("Test1"), TRUE);

	/* Make sure it saved properly */
	eq(file_exists("Test1"), TRUE);

	ok;
}
Ejemplo n.º 5
0
/**
 * Rest (restores hit points and mana and such)
 */
void do_cmd_rest(struct command *cmd)
{
	int n;

	/* XXX-AS need to insert UI here */
	if (cmd_get_arg_choice(cmd, "choice", &n) != CMD_OK)
		return;

	/* 
	 * A little sanity checking on the input - only the specified negative 
	 * values are valid. 
	 */
    if (n < 0 && !player_resting_is_special(n))
        return;

	/* Do some upkeep on the first turn of rest */
	if (!player_is_resting(player)) {
		player->searching = false;
		player->upkeep->update |= (PU_BONUS);

		/* If a number of turns was entered, remember it */
		if (n > 1)
			player_set_resting_repeat_count(player, n);
		else if (n == 1)
			/* If we're repeating the command, use the same count */
			n = player_get_resting_repeat_count(player);
	}

	/* Set the counter, and stop if told to */
	player_resting_set_count(player, n);
	if (!player_is_resting(player))
		return;

	/* Take a turn */
	player_resting_step_turn(player);

	/* Redraw the state if requested */
	handle_stuff(player);

	/* Prepare to continue, or cancel and clean up */
	if (player_resting_count(player) > 0) {
		cmdq_push(CMD_REST);
		cmd_set_arg_choice(cmdq_peek(), "choice", n - 1);
	} else if (player_resting_is_special(n)) {
		cmdq_push(CMD_REST);
		cmd_set_arg_choice(cmdq_peek(), "choice", n);
		player_set_resting_repeat_count(player, 0);
	} else {
		player_resting_cancel(player, false);
	}

}
Ejemplo n.º 6
0
static enum birth_stage point_based_command(void)
{
	static int stat = 0;
	struct keypress ch;
	enum birth_stage next = BIRTH_POINTBASED;

	/* Place cursor just after cost of current stat */
	Term_gotoxy(COSTS_COL + 4, COSTS_ROW + stat);

	/* Get key */
	ch = inkey();
	
	if (ch.code == KTRL('X')) {
		quit(NULL);
	} else if (ch.code == ESCAPE) {
		/* Go back a step, or back to the start of this step */
		next = BIRTH_BACK;
	} else if (ch.code == 'r' || ch.code == 'R') {
		cmdq_push(CMD_RESET_STATS);
		cmd_set_arg_choice(cmdq_peek(), "choice", FALSE);
	} else if (ch.code == KC_ENTER) {
		/* Done */
		next = BIRTH_NAME_CHOICE;
	} else {
		int dir = target_dir(ch);

		/* Prev stat, looping round to the bottom when going off the top */
		if (dir == 8)
			stat = (stat + STAT_MAX - 1) % STAT_MAX;
		
		/* Next stat, looping round to the top when going off the bottom */
		if (dir == 2)
			stat = (stat + 1) % STAT_MAX;
		
		/* Decrease stat (if possible) */
		if (dir == 4) {
			cmdq_push(CMD_SELL_STAT);
			cmd_set_arg_choice(cmdq_peek(), "choice", stat);
		}
		
		/* Increase stat (if possible) */
		if (dir == 6) {
			cmdq_push(CMD_BUY_STAT);
			cmd_set_arg_choice(cmdq_peek(), "choice", stat);
		}
	}

	return next;
}
Ejemplo n.º 7
0
/**
 * Drop all {ignore}able items.
 */
void ignore_drop(void)
{
	struct object *obj;

	/* Scan through the slots backwards */
	for (obj = gear_last_item(); obj; obj = obj->prev) {
		/* Skip non-objects and unignoreable objects */
		assert(obj->kind);
		if (!ignore_item_ok(obj)) continue;

		/* Check for !d (no drop) inscription */
		if (!check_for_inscrip(obj, "!d") && !check_for_inscrip(obj, "!*")) {
			/* Confirm the drop if the item is equipped. */
			if (object_is_equipped(player->body, obj)) {
				if (!verify_object("Really take off and drop", obj)) {
					/* Hack - inscribe the item with !d to prevent repeated
					 * confirmations. */
					const char *inscription = quark_str(obj->note);

					if (inscription == NULL) {
						obj->note = quark_add("!d");
					} else {
						char buffer[1024];
						my_strcpy(buffer, inscription, sizeof(buffer));
						my_strcat(buffer, "!d", sizeof(buffer));
						obj->note = quark_add(buffer);
					}

					continue;
				}
			}

			/* We're allowed to drop it. */
			if (!square_isshop(cave, player->py, player->px)) {
				player->upkeep->dropping = true;
				cmdq_push(CMD_DROP);
				cmd_set_arg_item(cmdq_peek(), "item", obj);
				cmd_set_arg_number(cmdq_peek(), "quantity", obj->number);
			}
		}
	}

	/* Update the gear */
	player->upkeep->update |= (PU_INVEN);

	/* Combine/reorder the pack */
	player->upkeep->notice |= (PN_COMBINE);
}
Ejemplo n.º 8
0
int test_stairs2(void *state) {

	/* Load the saved game */
	eq(savefile_load("Test1", FALSE), TRUE);

	cmdq_push(CMD_WALK);
	cmd_set_arg_direction(cmdq_peek(), "direction", 4);
	run_game_loop();
	cmdq_push(CMD_WALK);
	cmd_set_arg_direction(cmdq_peek(), "direction", 6);
	run_game_loop();
	cmdq_push(CMD_GO_DOWN);
	run_game_loop();
	eq(player->depth, 1);

	ok;
}
Ejemplo n.º 9
0
int test_drop_pickup(void *state) {

	/* Load the saved game */
	eq(savefile_load("Test1", FALSE), TRUE);

	cmdq_push(CMD_WALK);
	cmd_set_arg_direction(cmdq_peek(), "direction", 4);
	run_game_loop();
	if (player->upkeep->inven[0]->number > 1) {
		cmdq_push(CMD_DROP);
		cmd_set_arg_item(cmdq_peek(), "item", player->upkeep->inven[0]);
		cmd_set_arg_number(cmdq_peek(), "quantity", 1);
		run_game_loop();
		eq(square_object(cave, player->py, player->px)->number, 1);
		cmdq_push(CMD_AUTOPICKUP);
		run_game_loop();
	}
	eq(square_object(cave, player->py, player->px), NULL);

	ok;
}
Ejemplo n.º 10
0
/**
 * ------------------------------------------------------------------------
 * Asking for the player's chosen name.
 * ------------------------------------------------------------------------ */
static enum birth_stage get_name_command(void)
{
	enum birth_stage next;
	char name[32];

	if (get_character_name(name, sizeof(name))) {
		cmdq_push(CMD_NAME_CHOICE);
		cmd_set_arg_string(cmdq_peek(), "name", name);
		next = BIRTH_HISTORY_CHOICE;
	} else {
		next = BIRTH_BACK;
	}

	return next;
}
Ejemplo n.º 11
0
/**
 * ------------------------------------------------------------------------
 * Allowing the player to choose their history.
 * ------------------------------------------------------------------------ */
static enum birth_stage get_history_command(void)
{
	enum birth_stage next = 0;
	struct keypress ke;
	char old_history[240];

	/* Save the original history */
	my_strcpy(old_history, player->history, sizeof(old_history));

	/* Ask for some history */
	prt("Accept character history? [y/n]", 0, 0);
	ke = inkey();

	/* Quit, go back, change history, or accept */
	if (ke.code == KTRL('X')) {
		quit(NULL);
	} else if (ke.code == ESCAPE) {
		next = BIRTH_BACK;
	} else if (ke.code == 'N' || ke.code == 'n') {
		char history[240];
		my_strcpy(history, player->history, sizeof(history));

		switch (edit_text(history, sizeof(history))) {
			case -1:
				next = BIRTH_BACK;

			case 0:
				cmdq_push(CMD_HISTORY_CHOICE);
				cmd_set_arg_string(cmdq_peek(), "history", history);
				next = BIRTH_HISTORY_CHOICE;
		}
	} else {
		next = BIRTH_FINAL_CONFIRM;
	}

	return next;
}
Ejemplo n.º 12
0
int test_magic_missile(void *state) {

	/* Try making a new game */
	cmdq_push(CMD_BIRTH_INIT);
	cmdq_push(CMD_BIRTH_RESET);
	cmdq_push(CMD_CHOOSE_RACE);
	cmd_set_arg_choice(cmdq_peek(), "choice", 4);

	cmdq_push(CMD_CHOOSE_CLASS);
	cmd_set_arg_choice(cmdq_peek(), "choice", 1);

	cmdq_push(CMD_ROLL_STATS);
	cmdq_push(CMD_NAME_CHOICE);
	cmd_set_arg_string(cmdq_peek(), "name", "Tyrion");

	cmdq_push(CMD_ACCEPT_CHARACTER);
	cmdq_execute(CMD_BIRTH);

	eq(player->is_dead, FALSE);
	cave_generate(&cave, player);
	on_new_level();
	notnull(cave);
	eq(player->chp, player->mhp);
	eq(player->food, PY_FOOD_FULL - 1);

	cmdq_push(CMD_STUDY);
	cmd_set_arg_choice(cmdq_peek(), "spell", 0);
	run_game_loop();
	cmdq_push(CMD_CAST);
	cmd_set_arg_choice(cmdq_peek(), "spell", 0);
	cmd_set_arg_target(cmdq_peek(), "target", 2);
	run_game_loop();
	noteq(player->csp, player->msp);

	ok;
}
Ejemplo n.º 13
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 -- targetting/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 = player->py;
	int px = player->px;

	int path_n;
	struct loc path_g[256];

	int i, d, m, t, bd;
	int wid, hgt, help_prompt_loc;

	bool done = FALSE;
	bool flag = TRUE;
	bool help = FALSE;

	ui_event press;

	/* These are used for displaying the path to the target */
	wchar_t *path_char = mem_zalloc(z_info->max_range * sizeof(wchar_t));
	int *path_attr = mem_zalloc(z_info->max_range * sizeof(int));
	struct point_set *targets;

	/* If we haven't been given an initial location, start on the
	   player, otherwise  honour it by going into "free targetting" mode. */
	if (x == -1 || y == -1) {
		x = player->px;
		y = player->py;
	} else {
		flag = FALSE;
	}

	/* Cancel target */
	target_set_monster(0);

	/* Calculate the window location for the help prompt */
	Term_get_size(&wid, &hgt);
	help_prompt_loc = hgt - 1;
	
	/* Display the help prompt */
	prt("Press '?' for help.", help_prompt_loc, 0);

	/* Prepare the target set */
	targets = target_get_monsters(mode);

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

	/* Interact */
	while (!done) {
		bool path_drawn = FALSE;
		
		/* Interesting grids if chosen and there are any, otherwise arbitrary */
		if (flag && point_set_size(targets)) {
			y = targets->pts[m].y;
			x = targets->pts[m].x;

			/* Adjust panel if needed */
			if (adjust_panel_help(y, x, help)) handle_stuff(player);
		
			/* Update help */
			if (help) {
				bool good_target = target_able(square_monster(cave, y, x));
				target_display_help(good_target,
									!(flag && point_set_size(targets)));
			}

			/* Find the path. */
			path_n = project_path(path_g, z_info->max_range, py, px, y, x,
								  PROJECT_THRU);

			/* Draw the path in "target" mode. If there is one */
			if (mode & (TARGET_KILL))
				path_drawn = draw_path(path_n, path_g, path_char, path_attr,
									   py, px);

			/* Describe and Prompt */
			press = target_set_interactive_aux(y, x, mode);

			/* Remove the path */
			if (path_drawn) load_path(path_n, path_g, path_char, path_attr);

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


			/* Analyze */
			if (press.type == EVT_MOUSE) {
				if (press.mouse.button == 3) {
					/* give the target selection command */
					press.mouse.button = 2;
					press.mouse.mods = KC_MOD_CONTROL;
				}
				if (press.mouse.button == 2) {
					y = KEY_GRID_Y(press);
					x = KEY_GRID_X(press);
					if (press.mouse.mods & KC_MOD_CONTROL) {
						/* same as keyboard target selection command below */
						struct monster *m = square_monster(cave, y, x);

						if (target_able(m)) {
							/* Set up target information */
							monster_race_track(player->upkeep, m->race);
							health_track(player->upkeep, m);
							target_set_monster(m);
							done = TRUE;
						} else {
							bell("Illegal target!");
						}
					} else if (press.mouse.mods & KC_MOD_ALT) {
						/* go to spot - same as 'g' command below */
						cmdq_push(CMD_PATHFIND);
						cmd_set_arg_point(cmdq_peek(), "point", y, x);
						done = TRUE;
					} else {
						/* cancel look mode */
						done = TRUE;
					}
				} else {
					y = KEY_GRID_Y(press);
					x = KEY_GRID_X(press);
					if (square_monster(cave, y, x) ||
						square_object(cave, y, x)) {
							/* reset the flag, to make sure we stay in this
							 * mode if something is actually there */
						flag = FALSE;
						/* scan the interesting list and see if there is
						 * anything here */
						for (i = 0; i < point_set_size(targets); i++) {
							if ((y == targets->pts[i].y) &&
								(x == targets->pts[i].x)) {
								m = i;
								flag = TRUE;
								break;
							}
						}
					} else {
						flag = FALSE;
					}
				}
			} else
				switch (press.key.code)
				{
					case ESCAPE:
					case 'q':
					{
						done = TRUE;
						break;
					}

					case ' ':
					case '*':
					case '+':
					{
						if (++m == point_set_size(targets))
							m = 0;

						break;
					}

					case '-':
					{
						if (m-- == 0)
							m = point_set_size(targets) - 1;

						break;
					}

					case 'p':
					{
						/* Recenter around player */
						verify_panel();

						/* Handle stuff */
						handle_stuff(player);

						y = player->py;
						x = player->px;
					}

					case 'o':
					{
						flag = FALSE;
						break;
					}

					case 'm':
					{
						break;
					}

					case 't':
					case '5':
					case '0':
					case '.':
					{
						struct monster *m = square_monster(cave, y, x);

						if (target_able(m)) {
							health_track(player->upkeep, m);
							target_set_monster(m);
							done = TRUE;
						} else {
							bell("Illegal target!");
						}
						break;
					}

					case 'g':
					{
						cmdq_push(CMD_PATHFIND);
						cmd_set_arg_point(cmdq_peek(), "point", y, x);
						done = TRUE;
						break;
					}
				
					case '?':
					{
						help = !help;
					
						/* Redraw main window */
						player->upkeep->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP);
						Term_clear();
						handle_stuff(player);
						if (!help)
							prt("Press '?' for help.", help_prompt_loc, 0);
					
						break;
					}

					default:
					{
						/* Extract direction */
						d = target_dir(press.key);

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

						break;
					}
				}

			/* Hack -- move around */
			if (d) {
				int old_y = targets->pts[m].y;
				int old_x = targets->pts[m].x;

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

				/* Scroll to find interesting grid */
				if (i < 0) {
					int old_wy = Term->offset_y;
					int old_wx = Term->offset_x;

					/* Change if legal */
					if (change_panel(d)) {
						/* Recalculate interesting grids */
						point_set_dispose(targets);
						targets = target_get_monsters(mode);

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

						/* Restore panel if needed */
						if ((i < 0) && modify_panel(Term, old_wy, old_wx)) {
							/* Recalculate interesting grids */
							point_set_dispose(targets);
							targets = target_get_monsters(mode);
						}

						/* Handle stuff */
						handle_stuff(player);
					}
				}

				/* Use interesting grid if found */
				if (i >= 0) m = i;
			}
		} else {
			/* Update help */
			if (help) {
				bool good_target = target_able(square_monster(cave, y, x));
				target_display_help(good_target,
									!(flag && point_set_size(targets)));
			}

			/* Find the path. */
			path_n = project_path(path_g, z_info->max_range, py, px, y, x,
								  PROJECT_THRU);

			/* Draw the path in "target" mode. If there is one */
			if (mode & (TARGET_KILL))
				path_drawn = draw_path (path_n, path_g, path_char, path_attr,
										py, px);

			/* Describe and Prompt (enable "TARGET_LOOK") */
			press = target_set_interactive_aux(y, x, mode | TARGET_LOOK);

			/* Remove the path */
			if (path_drawn)  load_path(path_n, path_g, path_char, path_attr);

			/* Assume no direction */
			d = 0;

			/* Analyze the keypress */
			if (press.type == EVT_MOUSE) {
				if (press.mouse.button == 3) {
					/* give the target selection command */
					press.mouse.button = 2;
					press.mouse.mods = KC_MOD_CONTROL;
				}
				if (press.mouse.button == 2) {
					if (mode & (TARGET_KILL)) {
						if ((y == KEY_GRID_Y(press)) 
								&& (x == KEY_GRID_X(press))) {
							d = -1;
						}
					}
					y = KEY_GRID_Y(press);
					x = KEY_GRID_X(press);
					if (press.mouse.mods & KC_MOD_CONTROL) {
						/* same as keyboard target selection command below */
						target_set_location(y, x);
						done = TRUE;
					} else if (press.mouse.mods & KC_MOD_ALT) {
						/* go to spot - same as 'g' command below */
						cmdq_push(CMD_PATHFIND);
						cmd_set_arg_point(cmdq_peek(), "point", y, x);
						done = TRUE;
					} else {
						/* cancel look mode */
						done = TRUE;
						if (d == -1) {
							target_set_location(y, x);
							d = 0;
						}
					}
				} else {
					int dungeon_hgt = cave->height;
					int dungeon_wid = cave->width;

					y = KEY_GRID_Y(press);
					x = KEY_GRID_X(press);
				  
					if (press.mouse.y <= 1) {
						/* move the screen north */
						y--;
					} else if (press.mouse.y >= (Term->hgt - 2)) {
						/* move the screen south */
						y++;
					} else if (press.mouse.x <= COL_MAP) {
						/* move the screen in west */
						x--;
					} else if (press.mouse.x >= (Term->wid - 2)) {
						/* move the screen east */
						x++;
					}
          
					if (y < 0) y = 0;
					if (x < 0) x = 0;
					if (y >= dungeon_hgt-1) y = dungeon_hgt-1;
					if (x >= dungeon_wid-1) x = dungeon_wid-1;

					/* Adjust panel if needed */
					if (adjust_panel_help(y, x, help)) {
						/* Handle stuff */
						handle_stuff(player);

						/* Recalculate interesting grids */
						point_set_dispose(targets);
						targets = target_get_monsters(mode);
					}

					if (square_monster(cave, y, x) ||
						square_object(cave, y, x)) {
						/* scan the interesting list and see if there in
						 * anything here */
						for (i = 0; i < point_set_size(targets); i++) {
							if ((y == targets->pts[i].y) &&
								(x == targets->pts[i].x)) {
								m = i;
								flag = TRUE;
								break;
							}
						}
					} else {
						flag = FALSE;
					}
				}
			} else
				switch (press.key.code)
				{
					case ESCAPE:
					case 'q':
					{
						done = TRUE;
						break;
					}

					case ' ':
					case '*':
					case '+':
					case '-':
					{
						break;
					}

					case 'p':
					{
						/* Recenter around player */
						verify_panel();

						/* Handle stuff */
						handle_stuff(player);

						y = player->py;
						x = player->px;
					}

					case 'o':
					{
						break;
					}

					case 'm':
					{
						flag = TRUE;

						m = 0;
						bd = 999;

						/* Pick a nearby monster */
						for (i = 0; i < point_set_size(targets); i++) {
							t = distance(y, x, targets->pts[i].y,
										 targets->pts[i].x);

							/* Pick closest */
							if (t < bd) {
								m = i;
								bd = t;
							}
						}

						/* Nothing interesting */
						if (bd == 999) flag = FALSE;

						break;
					}

					case 't':
					case '5':
					case '0':
					case '.':
					{
						target_set_location(y, x);
						done = TRUE;
						break;
					}

					case 'g':
					{
						cmdq_push(CMD_PATHFIND);
						cmd_set_arg_point(cmdq_peek(), "point", y, x);
						done = TRUE;
						break;
					}

					case '?':
					{
						help = !help;

						/* Redraw main window */
						player->upkeep->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP);
						Term_clear();
						handle_stuff(player);
						if (!help)
							prt("Press '?' for help.", help_prompt_loc, 0);
					
						break;
					}

					default:
					{
						/* Extract a direction */
						d = target_dir(press.key);

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

						break;
					}
				}

			/* Handle "direction" */
			if (d) {
				int dungeon_hgt = cave->height;
				int dungeon_wid = cave->width;

				/* 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 (adjust_panel_help(y, x, help)) {
					/* Handle stuff */
					handle_stuff(player);

					/* Recalculate interesting grids */
					point_set_dispose(targets);
					targets = target_get_monsters(mode);
				}
			}
		}
	}

	/* Forget */
	point_set_dispose(targets);

	/* Redraw as necessary */
	if (help) {
		player->upkeep->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP);
		Term_clear();
	} else {
		prt("", 0, 0);
		prt("", help_prompt_loc, 0);
		player->upkeep->redraw |= (PR_DEPTH | PR_STATUS);
	}

	/* Recenter around player */
	verify_panel();

	/* Handle stuff */
	handle_stuff(player);

	mem_free(path_attr);
	mem_free(path_char);

	/* Failure to set target */
	if (!target_is_set()) return (FALSE);

	/* Success */
	return (TRUE);
}
Ejemplo n.º 14
0
/**
 * Take one step along the current "run" path
 *
 * Called with a real direction to begin a new run, and with zero
 * to continue a run in progress.
 */
void run_step(int dir)
{
	int x, y;

	/* Start or continue run */
	if (dir) {
		/* Initialize */
		run_init(dir);

		/* Hack -- Set the run counter */
		player->upkeep->running = 1000;

		/* Calculate torch radius */
		player->upkeep->update |= (PU_TORCH);
	} else {
		/* Continue running */
		if (!player->upkeep->running_withpathfind) {
			/* Update regular running */
			if (run_test()) {
				/* Disturb */
				disturb(player, 0);
				return;
			}
		} else {
			/* Pathfinding */
			if (pf_result_index < 0) {
				/* Abort if the path is finished */
				disturb(player, 0);
				player->upkeep->running_withpathfind = FALSE;
				return;
			} else if (pf_result_index == 0) {
				/* Abort if we would hit a wall */
				y = player->py + ddy[pf_result[pf_result_index] - '0'];
				x = player->px + ddx[pf_result[pf_result_index] - '0'];

				/* Known wall */
				if (square_ismark(cave, y, x) &&
					!square_ispassable(cave, y, x)) {
					disturb(player, 0);
					player->upkeep->running_withpathfind = FALSE;
					return;
				}
			} else if (pf_result_index > 0) {
				/* If the player has computed a path that is going to end up
				 * in a wall, we notice this and convert to a normal run. This
				 * allows us to click on unknown areas to explore the map.
				 *
				 * We have to look ahead two, otherwise we don't know which is
				 * the last direction moved and don't initialise the run
				 * properly. */
				y = player->py + ddy[pf_result[pf_result_index] - '0'];
				x = player->px + ddx[pf_result[pf_result_index] - '0'];

				/* Known wall */
				if (square_ismark(cave, y, x) &&
					!square_ispassable(cave, y, x)) {
					disturb(player, 0);
					player->upkeep->running_withpathfind = FALSE;
					return;
				}

				/* Get step after */
				y = y + ddy[pf_result[pf_result_index - 1] - '0'];
				x = x + ddx[pf_result[pf_result_index - 1] - '0'];

				/* Known wall, so run the direction we were going */
				if (square_ismark(cave, y, x) &&
					!square_ispassable(cave, y, x)) {
					player->upkeep->running_withpathfind = FALSE;
					run_init(pf_result[pf_result_index] - '0');
				}
			}

			/* Now actually run the step if we're still going */
			run_cur_dir = pf_result[pf_result_index--] - '0';
		}
	}

	/* Decrease counter if it hasn't been cancelled */
	if (player->upkeep->running)
		player->upkeep->running--;

	/* Take time */
	player->upkeep->energy_use = z_info->move_energy;

	/* Move the player */
	move_player(run_cur_dir, TRUE);

	/* Prepare the next step */
	if (player->upkeep->running) {
		cmdq_push(CMD_RUN);
		cmd_set_arg_direction(cmdq_peek(), "direction", 0);
	}
}
Ejemplo n.º 15
0
/**
 * Take one step along the current "run" path
 *
 * Called with a real direction to begin a new run, and with zero
 * to continue a run in progress.
 */
void run_step(int dir)
{
	/* Start or continue run */
	if (dir) {
		/* Initialize */
		run_init(dir);

		/* Hack -- Set the run counter */
		player->upkeep->running = 1000;

		/* Calculate torch radius */
		player->upkeep->update |= (PU_TORCH);
	} else {
		/* Continue running */
		if (!player->upkeep->running_withpathfind) {
			/* Update regular running */
			if (run_test()) {
				/* Disturb */
				disturb(player, 0);
				return;
			}
		} else if (pf_result_index < 0) {
			/* Pathfinding, and the path is finished */
			disturb(player, 0);
			player->upkeep->running_withpathfind = false;
			return;
		} else {
			int y = player->py + ddy[pf_result[pf_result_index] - '0'];
			int x = player->px + ddx[pf_result[pf_result_index] - '0'];

			if (pf_result_index == 0) {
				/* Known wall */
				if (square_isknown(cave, y, x) &&
					!square_ispassable(cave, y, x)) {
					disturb(player, 0);
					player->upkeep->running_withpathfind = false;
					return;
				}
			} else if (pf_result_index > 0) {
				struct object *obj;

				/* If the player has computed a path that is going to end up
				 * in a wall, we notice this and convert to a normal run. This
				 * allows us to click on unknown areas to explore the map.
				 *
				 * We have to look ahead two, otherwise we don't know which is
				 * the last direction moved and don't initialise the run
				 * properly. */
				y = player->py + ddy[pf_result[pf_result_index] - '0'];
				x = player->px + ddx[pf_result[pf_result_index] - '0'];

				/* Known wall */
				if (square_isknown(cave, y, x) &&
					!square_ispassable(cave, y, x)) {
					disturb(player, 0);
					player->upkeep->running_withpathfind = false;
					return;
				}

				/* Visible monsters abort running */
				if (cave->squares[y][x].mon > 0) {
					struct monster *mon = square_monster(cave, y, x);

					/* Visible monster */
					if (mflag_has(mon->mflag, MFLAG_VISIBLE)) {
						disturb(player, 0);
						player->upkeep->running_withpathfind = false;
						return;
					}
				}

				/* Visible objects abort running */
				for (obj = square_object(cave, y, x); obj; obj = obj->next)
					/* Visible object */
					if (obj->known && !ignore_item_ok(obj)) {
					disturb(player, 0);
					player->upkeep->running_withpathfind = false;
					return;
				}

				/* Get step after */
				y = y + ddy[pf_result[pf_result_index - 1] - '0'];
				x = x + ddx[pf_result[pf_result_index - 1] - '0'];

				/* Known wall, so run the direction we were going */
				if (square_isknown(cave, y, x) &&
					!square_ispassable(cave, y, x)) {
					player->upkeep->running_withpathfind = false;
					run_init(pf_result[pf_result_index] - '0');
				}
			}

			/* Now actually run the step if we're still going */
			run_cur_dir = pf_result[pf_result_index--] - '0';
		}
	}

	/* Decrease counter if it hasn't been cancelled */
	if (player->upkeep->running)
		player->upkeep->running--;
	else if (!player->upkeep->running_withpathfind)
		return;

	/* Take time */
	player->upkeep->energy_use = z_info->move_energy;

	/* Move the player; running straight into a trap == trying to disarm */
	move_player(run_cur_dir, dir ? true : false);

	/* Prepare the next step */
	if (player->upkeep->running) {
		cmdq_push(CMD_RUN);
		cmd_set_arg_direction(cmdq_peek(), "direction", 0);
	}
}
Ejemplo n.º 16
0
/**
 * Allow the user to select from the current menu, and return the 
 * corresponding command to the game.  Some actions are handled entirely
 * by the UI (displaying help text, for instance).
 */
static enum birth_stage menu_question(enum birth_stage current,
									  struct menu *current_menu,
									  cmd_code choice_command)
{
	struct birthmenu_data *menu_data = menu_priv(current_menu);
	ui_event cx;

	enum birth_stage next = BIRTH_RESET;
	
	/* Print the question currently being asked. */
	clear_question();
	Term_putstr(QUESTION_COL, QUESTION_ROW, -1, COLOUR_YELLOW, menu_data->hint);

	current_menu->cmd_keys = "?=*\x18";	 /* ?, =, *, <ctl-X> */

	while (next == BIRTH_RESET) {
		/* Display the menu, wait for a selection of some sort to be made. */
		cx = menu_select(current_menu, EVT_KBRD, FALSE);

		/* As all the menus are displayed in "hierarchical" style, we allow
		   use of "back" (left arrow key or equivalent) to step back in 
		   the proces as well as "escape". */
		if (cx.type == EVT_ESCAPE) {
			next = BIRTH_BACK;
		} else if (cx.type == EVT_SELECT) {
			if (current == BIRTH_ROLLER_CHOICE) {
				if (current_menu->cursor) {
					/* Do a first roll of the stats */
					cmdq_push(CMD_ROLL_STATS);
					next = current + 2;
				} else {
					/* 
					 * Make sure we've got a point-based char to play with. 
					 * We call point_based_start here to make sure we get
					 * an update on the points totals before trying to
					 * display the screen.  The call to CMD_RESET_STATS
					 * forces a rebuying of the stats to give us up-to-date
					 * totals.  This is, it should go without saying, a hack.
					 */
					point_based_start();
					cmdq_push(CMD_RESET_STATS);
					cmd_set_arg_choice(cmdq_peek(), "choice", TRUE);
					next = current + 1;
				}
			} else {
				cmdq_push(choice_command);
				cmd_set_arg_choice(cmdq_peek(), "choice", current_menu->cursor);
				next = current + 1;
			}
		} else if (cx.type == EVT_KBRD) {
			/* '*' chooses an option at random from those the game's provided */
			if (cx.key.code == '*' && menu_data->allow_random) {
				current_menu->cursor = randint0(current_menu->count);
				cmdq_push(choice_command);
				cmd_set_arg_choice(cmdq_peek(), "choice", current_menu->cursor);

				menu_refresh(current_menu, FALSE);
				next = current + 1;
			} else if (cx.key.code == '=') {
				do_cmd_options_birth();
				next = current;
			} else if (cx.key.code == KTRL('X')) {
				quit(NULL);
			} else if (cx.key.code == '?') {
				do_cmd_help();
			}
		}
	}
	
	return next;
}