コード例 #1
0
ファイル: cmd-cave.c プロジェクト: Moriwen/angband
/*
 * Determine if a given grid may be "walked"
 */
static bool do_cmd_walk_test(int y, int x)
{
	int m_idx = cave->m_idx[y][x];
	struct monster *m_ptr = cave_monster(cave, m_idx);

	/* Allow attack on visible monsters if unafraid */
	if (m_idx > 0 && m_ptr->ml && !is_mimicking(m_ptr))
	{
		/* Handle player fear */
		if (check_state(p_ptr, OF_AFRAID, p_ptr->state.flags))
		{
			/* Extract monster name (or "it") */
			char m_name[80];
			monster_desc(m_name, sizeof(m_name), m_ptr, MDESC_DEFAULT);

			/* Message */
			msgt(MSG_AFRAID, "You are too afraid to attack %s!", m_name);

			/* Nope */
			return (FALSE);
		}

		return (TRUE);
	}

	/* If we don't know the grid, allow attempts to walk into it */
	if (!(cave->info[y][x] & CAVE_MARK))
		return TRUE;

	/* Require open space */
	if (!cave_ispassable(cave, y, x))
	{
		/* Rubble */
		if (cave_isrubble(cave, y, x))
			msgt(MSG_HITWALL, "There is a pile of rubble in the way!");

		/* Door */
		else if (cave_iscloseddoor(cave, y, x))
			return TRUE;

		/* Wall */
		else
			msgt(MSG_HITWALL, "There is a wall in the way!");

		/* Cancel repeat */
		disturb(p_ptr, 0, 0);

		/* Nope */
		return (FALSE);
	}

	/* Okay */
	return (TRUE);
}
コード例 #2
0
ファイル: cmd2.c プロジェクト: qwerty16/angband
/*
 * Determine if a given grid may be "opened"
 */
static bool do_cmd_open_test(int y, int x)
{
	/* Must have knowledge */
	if (!(cave->info[y][x] & (CAVE_MARK))) {
		msg("You see nothing there.");
		return FALSE;
	}

	if (!cave_iscloseddoor(cave, y, x)) {
		msgt(MSG_NOTHING_TO_OPEN, "You see nothing there to open.");
		return FALSE;
	}

	/* Okay */
	return (TRUE);
}
コード例 #3
0
ファイル: cmd2.c プロジェクト: qwerty16/angband
/*
 * Determine if a given grid may be "bashed"
 */
static bool do_cmd_bash_test(int y, int x)
{
	/* Must have knowledge */
	if (!(cave->info[y][x] & (CAVE_MARK))) {
		msg("You see nothing there.");
		return (FALSE);
	}

	if (!cave_iscloseddoor(cave, y, x)) {
		msg("You see nothing there to bash.");
		return FALSE;
	}

	/* Okay */
	return (TRUE);
}
コード例 #4
0
ファイル: cmd2.c プロジェクト: qwerty16/angband
/*
 * Manipulate an adjacent grid in some way
 *
 * Attack monsters, tunnel through walls, disarm traps, open doors.
 *
 * This command must always take energy, to prevent free detection
 * of invisible monsters.
 *
 * The "semantics" of this command must be chosen before the player
 * is confused, and it must be verified against the new grid.
 */
void do_cmd_alter_aux(int dir)
{
	int y, x;
	bool more = FALSE;

	/* Get location */
	y = p_ptr->py + ddy[dir];
	x = p_ptr->px + ddx[dir];

	/* Take a turn */
	p_ptr->energy_use = 100;

	/* Apply confusion */
	if (player_confuse_dir(p_ptr, &dir, FALSE)) {
		/* Get location */
		y = p_ptr->py + ddy[dir];
		x = p_ptr->px + ddx[dir];
	}

	/* Attack monsters */
	if (cave->m_idx[y][x] > 0)
		py_attack(y, x);

	/* Tunnel through walls and rubble */
	else if (cave_isdiggable(cave, y, x))
		more = do_cmd_tunnel_aux(y, x);

	/* Open closed doors */
	else if (cave_iscloseddoor(cave, y, x))
		more = do_cmd_open_aux(y, x);

	/* Disarm traps */
	else if (cave_isknowntrap(cave, y, x))
		more = do_cmd_disarm_aux(y, x);

	/* Oops */
	else
		msg("You spin around.");

	/* Cancel repetition unless we can continue */
	if (!more) disturb(p_ptr, 0, 0);
}
コード例 #5
0
ファイル: cmd-cave.c プロジェクト: Moriwen/angband
/*
 * Determine if a given grid may be "disarmed"
 */
static bool do_cmd_disarm_test(int y, int x)
{
	/* Must have knowledge */
	if (!(cave->info[y][x] & (CAVE_MARK))) {
		msg("You see nothing there.");
		return FALSE;
	}

	/* Look for a closed, unlocked door to lock */
	if (cave_iscloseddoor(cave, y, x) && !cave_islockeddoor(cave, y, x))
		return TRUE;

	/* Look for a trap */
	if (!cave_isknowntrap(cave, y, x)) {
		msg("You see nothing there to disarm.");
		return FALSE;
	}

	/* Okay */
	return TRUE;
}
コード例 #6
0
ファイル: cmd2.c プロジェクト: qwerty16/angband
/*
 * Determine if a given grid may be "spiked"
 */
static bool do_cmd_spike_test(int y, int x)
{
	/* Must have knowledge */
	if (!(cave->info[y][x] & (CAVE_MARK))) {
		msg("You see nothing there.");
		return FALSE;
	}

	/* Check if door is closed */
	if (!cave_iscloseddoor(cave, y, x)) {
		msg("You see nothing there to spike.");
		return FALSE;
	}

	/* Check that the door is not fully spiked */
	if (!(cave->feat[y][x] < FEAT_DOOR_TAIL)) {
		msg("You can't use more spikes on this door.");
		return FALSE;
	}

	/* Okay */
	return TRUE;
}
コード例 #7
0
ファイル: cmd1.c プロジェクト: tonberrytoby/angband
/*
 * Move player in the given direction.
 *
 * This routine should only be called when energy has been expended.
 *
 * Note that this routine handles monsters in the destination grid,
 * and also handles attempting to move into walls/doors/rubble/etc.
 */
void move_player(int dir, bool disarm)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	int y = py + ddy[dir];
	int x = px + ddx[dir];
	
	int m_idx = cave->m_idx[y][x];

	/* Attack monsters */
	if (m_idx > 0) {
		/* Mimics surprise the player */
		if (is_mimicking(m_idx)) {
			become_aware(m_idx);

			/* Mimic wakes up */
			mon_clear_timed(m_idx, MON_TMD_SLEEP, MON_TMD_FLG_NOMESSAGE);

		} else {
			py_attack(y, x);
		}
	}

	/* Optionally alter traps/doors on movement */
	else if (disarm && (cave->info[y][x] & CAVE_MARK) &&
			(cave_isknowntrap(cave, y, x) ||
			cave_iscloseddoor(cave, y, x)))
	{
		/* Auto-repeat if not already repeating */
		if (cmd_get_nrepeats() == 0)
			cmd_set_repeat(99);

		do_cmd_alter_aux(dir);
	}

	/* Cannot walk through walls */
	else if (!cave_floor_bold(y, x))
	{
		/* Disturb the player */
		disturb(p_ptr, 0, 0);

		/* Notice unknown obstacles */
		if (!(cave->info[y][x] & CAVE_MARK))
		{
			/* Rubble */
			if (cave->feat[y][x] == FEAT_RUBBLE)
			{
				msgt(MSG_HITWALL, "You feel a pile of rubble blocking your way.");
				cave->info[y][x] |= (CAVE_MARK);
				cave_light_spot(cave, y, x);
			}

			/* Closed door */
			else if (cave->feat[y][x] < FEAT_SECRET)
			{
				msgt(MSG_HITWALL, "You feel a door blocking your way.");
				cave->info[y][x] |= (CAVE_MARK);
				cave_light_spot(cave, y, x);
			}

			/* Wall (or secret door) */
			else
			{
				msgt(MSG_HITWALL, "You feel a wall blocking your way.");
				cave->info[y][x] |= (CAVE_MARK);
				cave_light_spot(cave, y, x);
			}
		}

		/* Mention known obstacles */
		else
		{
			if (cave->feat[y][x] == FEAT_RUBBLE)
				msgt(MSG_HITWALL, "There is a pile of rubble blocking your way.");
			else if (cave->feat[y][x] < FEAT_SECRET)
				msgt(MSG_HITWALL, "There is a door blocking your way.");
			else
				msgt(MSG_HITWALL, "There is a wall blocking your way.");
		}
	}

	/* Normal movement */
	else
	{
		/* See if trap detection status will change */
		bool old_dtrap = ((cave->info2[py][px] & (CAVE2_DTRAP)) != 0);
		bool new_dtrap = ((cave->info2[y][x] & (CAVE2_DTRAP)) != 0);

		/* Note the change in the detect status */
		if (old_dtrap != new_dtrap)
			p_ptr->redraw |= (PR_DTRAP);

		/* Disturb player if the player is about to leave the area */
		if (OPT(disturb_detect) && p_ptr->running && 
			!p_ptr->running_firststep && old_dtrap && !new_dtrap)
		{
			disturb(p_ptr, 0, 0);
			return;
		}

		/* Move player */
		monster_swap(py, px, y, x);
  
		/* New location */
		y = py = p_ptr->py;
		x = px = p_ptr->px;

		/* Searching */
		if (p_ptr->searching ||
				(p_ptr->state.skills[SKILL_SEARCH_FREQUENCY] >= 50) ||
				one_in_(50 - p_ptr->state.skills[SKILL_SEARCH_FREQUENCY]))
			search(FALSE);

		/* Handle "store doors" */
		if ((cave->feat[p_ptr->py][p_ptr->px] >= FEAT_SHOP_HEAD) &&
			(cave->feat[p_ptr->py][p_ptr->px] <= FEAT_SHOP_TAIL))
		{
			/* Disturb */
			disturb(p_ptr, 0, 0);
			cmd_insert(CMD_ENTER_STORE);
		}

		/* All other grids (including traps) */
		else
		{
			/* Handle objects (later) */
			p_ptr->notice |= (PN_PICKUP);
		}


		/* Discover invisible traps */
		if (cave->feat[y][x] == FEAT_INVIS)
		{
			/* Disturb */
			disturb(p_ptr, 0, 0);

			/* Message */
			msg("You found a trap!");

			/* Pick a trap */
			pick_trap(y, x);

			/* Hit the trap */
			hit_trap(y, x);
		}

		/* Set off an visible trap */
		else if (cave_isknowntrap(cave, y, x))
		{
			/* Disturb */
			disturb(p_ptr, 0, 0);

			/* Hit the trap */
			hit_trap(y, x);
		}
	}

	p_ptr->running_firststep = FALSE;
}
コード例 #8
0
ファイル: cmd-context.c プロジェクト: DaPortlyJester/angband
int context_menu_cave(struct cave *c, int y, int x, int adjacent, int mx, int my)
{
	menu_type *m;
	region r;
	int selected;
	char *labels;
	bool allowed = TRUE;
	int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG;
	unsigned char cmdkey;

	m = menu_dynamic_new();
	if (!m) {
		return 0;
	}

	labels = string_make(lower_case);
	m->selections = labels;

	/* Looking has different keys, but we don't have a way to look them up (see cmd-process.c). */
	cmdkey = (mode == KEYMAP_MODE_ORIG) ? 'l' : 'x';
	menu_dynamic_add_label(m, "Look At", cmdkey, MENU_VALUE_LOOK, labels);

	if (c->m_idx[y][x]) {
		/* '/' is used for recall in both keymaps. */
		menu_dynamic_add_label(m, "Recall Info", '/', MENU_VALUE_RECALL, labels);
	}

	ADD_LABEL("Use Item On", CMD_USE_ANY, MN_ROW_VALID);

	if (player_can_cast(p_ptr, FALSE)) {
		ADD_LABEL("Cast On", CMD_CAST, MN_ROW_VALID);
	}

	if (adjacent) {
		ADD_LABEL((c->m_idx[y][x]) ? "Attack" : "Alter", CMD_ALTER, MN_ROW_VALID);

		if (c->o_idx[y][x]) {
			s16b o_idx = chest_check(y,x, CHEST_ANY);
			if (o_idx) {
				object_type *o_ptr = object_byid(o_idx);
				if (!squelch_item_ok(o_ptr)) {
					if (object_is_known(o_ptr)) {
						if (is_locked_chest(o_ptr)) {
							ADD_LABEL("Disarm Chest", CMD_DISARM, MN_ROW_VALID);
							ADD_LABEL("Open Chest", CMD_OPEN, MN_ROW_VALID);
						}
						else {
							ADD_LABEL("Open Disarmed Chest", CMD_OPEN, MN_ROW_VALID);
						}
					}
					else {
						ADD_LABEL("Open Chest", CMD_OPEN, MN_ROW_VALID);
					}
				}
			}
		}

		if (cave_istrap(c, y, x)) {
			ADD_LABEL("Disarm", CMD_DISARM, MN_ROW_VALID);
			ADD_LABEL("Jump Onto", CMD_JUMP, MN_ROW_VALID);
		}

		if (cave_isopendoor(c, y, x)) {
			ADD_LABEL("Close", CMD_CLOSE, MN_ROW_VALID);
		}
		else if (cave_iscloseddoor(c, y, x)) {
			ADD_LABEL("Open", CMD_OPEN, MN_ROW_VALID);
			ADD_LABEL("Lock", CMD_DISARM, MN_ROW_VALID);
		}
		else if (cave_isdiggable(c, y, x)) {
			ADD_LABEL("Tunnel", CMD_TUNNEL, MN_ROW_VALID);
		}

		ADD_LABEL("Search", CMD_SEARCH, MN_ROW_VALID);
		ADD_LABEL("Walk Towards", CMD_WALK, MN_ROW_VALID);
	}
	else {
		/* ',' is used for squelch in rogue keymap, so we'll just swap letters. */
		cmdkey = (mode == KEYMAP_MODE_ORIG) ? ',' : '.';
		menu_dynamic_add_label(m, "Pathfind To", cmdkey, CMD_PATHFIND, labels);

		ADD_LABEL("Walk Towards", CMD_WALK, MN_ROW_VALID);
		ADD_LABEL("Run Towards", CMD_RUN, MN_ROW_VALID);
	}

	if (player_can_fire(p_ptr, FALSE)) {
		ADD_LABEL("Fire On", CMD_FIRE, MN_ROW_VALID);
	}

	ADD_LABEL("Throw To", CMD_THROW, MN_ROW_VALID);

	/* work out display region */
	r.width = (int)menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */
	if (mx > Term->wid - r.width - 1) {
		r.col = Term->wid - r.width - 1;
	} else {
		r.col = mx + 1;
	}
	r.page_rows = m->count;
	if (my > Term->hgt - r.page_rows - 1) {
		if (my - r.page_rows - 1 <= 0) {
			/* menu has too many items, so put in upper right corner */
			r.row = 1;
			r.col = Term->wid - r.width - 1;
		} else {
			r.row = Term->hgt - r.page_rows - 1;
		}
	} else {
		r.row = my + 1;
	}

	/* Hack -- no flush needed */
	msg_flag = FALSE;
	screen_save();

	menu_layout(m, &r);
	region_erase_bordered(&r);
	if (p_ptr->timed[TMD_IMAGE]) {
		prt("(Enter to select command, ESC to cancel) You see something strange:", 0, 0);
	} else
	if (c->m_idx[y][x]) {
		char m_name[80];
		monster_type *m_ptr = cave_monster_at(c, y, x);

		/* Get the monster name ("a kobold") */
		monster_desc(m_name, sizeof(m_name), m_ptr, MDESC_IND_VIS);

		prt(format("(Enter to select command, ESC to cancel) You see %s:", m_name), 0, 0);
	} else
	if (c->o_idx[y][x] && !squelch_item_ok(object_byid(c->o_idx[y][x]))) {
		char o_name[80];

		/* Get the single object in the list */
		object_type *o_ptr = object_byid(c->o_idx[y][x]);

		/* Obtain an object description */
		object_desc(o_name, sizeof (o_name), o_ptr, ODESC_PREFIX | ODESC_FULL);

		prt(format("(Enter to select command, ESC to cancel) You see %s:", o_name), 0, 0);
	} else
	{
		/* Feature (apply mimic) */
		const char *name = cave_apparent_name(c, p_ptr, y, x);

		/* Hack -- special introduction for store doors */
		if (cave_isshop(cave, y, x)) {
			prt(format("(Enter to select command, ESC to cancel) You see the entrance to the %s:", name), 0, 0);
		} else {
			prt(format("(Enter to select command, ESC to cancel) You see %s %s:",
					(is_a_vowel(name[0])) ? "an" : "a", name), 0, 0);
		}
	}

	selected = menu_dynamic_select(m);

	menu_dynamic_free(m);
	string_free(labels);

	screen_load();

	cmdkey = cmd_lookup_key(selected, mode);

	/* Check the command to see if it is allowed. */
	switch (selected) {
		case -1:
			/* User cancelled the menu. */
			return 3;

		case MENU_VALUE_LOOK:
		case MENU_VALUE_RECALL:
		case CMD_PATHFIND:
			allowed = TRUE;
			break;

		case CMD_SEARCH:
		case CMD_ALTER:
		case CMD_DISARM:
		case CMD_JUMP:
		case CMD_CLOSE:
		case CMD_OPEN:
		case CMD_TUNNEL:
		case CMD_WALK:
		case CMD_RUN:
		case CMD_CAST:
		case CMD_FIRE:
		case CMD_THROW:
		case CMD_USE_ANY:
			/* Only check for ^ inscriptions, since we don't have an object selected (if we need one). */
			allowed = key_confirm_command(cmdkey);
			break;

		default:
			/* Invalid command; prevent anything from happening. */
			bell("Invalid context menu command.");
			allowed = FALSE;
			break;
	}

	if (!allowed)
		return 1;

	/* Perform the command. */
	switch (selected) {
		case MENU_VALUE_LOOK:
			/* look at the spot */
			if (target_set_interactive(TARGET_LOOK, x, y)) {
				msg("Target Selected.");
			}
			break;

		case MENU_VALUE_RECALL: {
			/* recall monster Info */
			monster_type *m_ptr = cave_monster_at(c, y, x);
			if (m_ptr) {
				monster_lore *lore = get_lore(m_ptr->race);
				lore_show_interactive(m_ptr->race, lore);
			}
		}
			break;

		case CMD_SEARCH:
			cmd_insert(selected);
			break;

		case CMD_PATHFIND:
			cmd_insert(selected);
			cmd_set_arg_point(cmd_get_top(), 0, x, y);
			break;

		case CMD_ALTER:
		case CMD_DISARM:
		case CMD_JUMP:
		case CMD_CLOSE:
		case CMD_OPEN:
		case CMD_TUNNEL:
		case CMD_WALK:
		case CMD_RUN:
			cmd_insert(selected);
			cmd_set_arg_direction(cmd_get_top(), 0, coords_to_dir(y,x));
			break;

		case CMD_CAST:
			if (textui_obj_cast_ret() >= 0) {
				cmd_set_arg_target(cmd_get_top(), 1, DIR_TARGET);
			}
			break;

		case CMD_FIRE:
		case CMD_THROW:
		case CMD_USE_ANY:
			cmd_insert(selected);
			cmd_set_arg_target(cmd_get_top(), 1, DIR_TARGET);
			break;

		default:
			break;
	}

	return 1;
}
コード例 #9
0
ファイル: target.c プロジェクト: konijn/angband
/*
 * Hack -- determine if a given location is "interesting"
 */
static bool target_set_interactive_accept(int y, int x)
{
	object_type *o_ptr;


	/* Player grids are always interesting */
	if (cave->m_idx[y][x] < 0) return (TRUE);


	/* Handle hallucination */
	if (p_ptr->timed[TMD_IMAGE]) return (FALSE);


	/* Visible monsters */
	if (cave->m_idx[y][x] > 0)
	{
		monster_type *m_ptr = cave_monster(cave, cave->m_idx[y][x]);

		/* Visible monsters */
		if (m_ptr->ml && !m_ptr->unaware) return (TRUE);
	}

	/* Scan all objects in the grid */
	for (o_ptr = get_first_object(y, x); o_ptr; o_ptr = get_next_object(o_ptr))
	{
		/* Memorized object */
		if (o_ptr->marked && !squelch_item_ok(o_ptr)) return (TRUE);
	}

	/* Interesting memorized features */
	if (cave->info[y][x] & (CAVE_MARK))
	{
		/* Notice glyphs */
		if (cave->feat[y][x] == FEAT_GLYPH) return (TRUE);

		/* Notice doors */
		if (cave->feat[y][x] == FEAT_OPEN) return (TRUE);
		if (cave->feat[y][x] == FEAT_BROKEN) return (TRUE);

		/* Notice stairs */
		if (cave->feat[y][x] == FEAT_LESS) return (TRUE);
		if (cave->feat[y][x] == FEAT_MORE) return (TRUE);

		/* Notice shops */
		if ((cave->feat[y][x] >= FEAT_SHOP_HEAD) &&
		    (cave->feat[y][x] <= FEAT_SHOP_TAIL)) return (TRUE);

		/* Notice traps */
		if (cave_isknowntrap(cave, y, x)) return TRUE;

		/* Notice doors */
		if (cave_iscloseddoor(cave, y, x)) return TRUE;

		/* Notice rubble */
		if (cave->feat[y][x] == FEAT_RUBBLE) return (TRUE);

		/* Notice veins with treasure */
		if (cave->feat[y][x] == FEAT_MAGMA_K) return (TRUE);
		if (cave->feat[y][x] == FEAT_QUARTZ_K) return (TRUE);
	}

	/* Nope */
	return (FALSE);
}
コード例 #10
0
ファイル: cmd-cave.c プロジェクト: Moriwen/angband
/*
 * Disarms a trap, or a chest
 */
void do_cmd_disarm(cmd_code code, cmd_arg args[])
{
	int y, x, dir;

	s16b o_idx;

	bool more = FALSE;

	dir = args[0].direction;

	/* Get location */
	y = p_ptr->py + ddy[dir];
	x = p_ptr->px + ddx[dir];

	/* Check for chests */
	o_idx = chest_check(y, x, CHEST_TRAPPED);


	/* Verify legality */
	if (!o_idx && !do_cmd_disarm_test(y, x))
	{
		/* Cancel repeat */
		disturb(p_ptr, 0, 0);
		return;
	}

	/* Take a turn */
	p_ptr->energy_use = 100;

	/* Apply confusion */
	if (player_confuse_dir(p_ptr, &dir, FALSE))
	{
		/* Get location */
		y = p_ptr->py + ddy[dir];
		x = p_ptr->px + ddx[dir];

		/* Check for chests */
		o_idx = chest_check(y, x, CHEST_TRAPPED);
	}


	/* Monster */
	if (cave->m_idx[y][x] > 0) {
		msg("There is a monster in the way!");
		py_attack(y, x);
	}

	/* Chest */
	else if (o_idx)
		more = do_cmd_disarm_chest(y, x, o_idx);

	/* Door to lock */
	else if (    cave_iscloseddoor(cave, y, x)
	         && !cave_islockeddoor(cave, y, x))
		more = do_cmd_lock_door(y, x);

	/* Disarm trap */
	else
		more = do_cmd_disarm_aux(y, x);

	/* Cancel repeat unless told not to */
	if (!more) disturb(p_ptr, 0, 0);
}