Exemple #1
0
/**
 * Go down one level
 */
void do_cmd_go_down(struct command *cmd)
{
	int descend_to = dungeon_get_next_level(player->depth, 1);

	/* Verify stairs */
	if (!square_isdownstairs(cave, player->py, player->px)) {
		msg("I see no down staircase here.");
		return;
	}

	/* Paranoia, no descent from z_info->max_depth - 1 */
	if (player->depth == z_info->max_depth - 1) {
		msg("The dungeon does not appear to extend deeper");
		return;
	}

	/* Warn a force_descend player if they're going to a quest level */
	if (OPT(birth_force_descend)) {
		descend_to = dungeon_get_next_level(player->max_depth, 1);
		if (is_quest(descend_to) &&
			!get_check("Are you sure you want to descend?"))
			return;
	}

	/* Hack -- take a turn */
	player->upkeep->energy_use = z_info->move_energy;

	/* Success */
	msgt(MSG_STAIRS_DOWN, "You enter a maze of down staircases.");

	/* Create a way back */
	player->upkeep->create_up_stair = true;
	player->upkeep->create_down_stair = false;

	/* Change level */
	dungeon_change_level(descend_to);
}
Exemple #2
0
static void ui_keymap_query(const char *title, int row)
{
	char tmp[1024];
	int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG;
	struct keypress c;
	const struct keypress *act;

	prt(title, 13, 0);
	prt("Key: ", 14, 0);
	
	/* Get a keymap trigger & mapping */
	c = keymap_get_trigger();
	act = keymap_find(mode, c);
	
	/* Nothing found */
	if (!act)
	{
		/* Prompt */
		prt("No keymap with that trigger.  Press any key to continue.", 16, 0);
		inkey();
	}
	
	/* Found one */
	else
	{
		/* Analyze the current action */
		keypress_to_text(tmp, sizeof(tmp), act, false);
	
		/* Display the current action */
		prt("Found: ", 15, 0);
		Term_addstr(-1, TERM_WHITE, tmp);

		prt("Press any key to continue.", 17, 0);
		inkey();
	}
}
Exemple #3
0
/*
 * Make a money object
 */
void make_gold(object_type *j_ptr, int lev, int coin_type)
{
	int sval;

	/* This average is 20 at dlev0, 105 at dlev40, 220 at dlev100. */
	/* Follows the formula: y=2x+20 */
	s32b avg = 2*lev + 20;
	s32b spread = lev + 10;
	s32b value = rand_spread(avg, spread);

	/* Increase the range to infinite, moving the average to 110% */
	while (one_in_(100) && value * 10 <= MAX_SHORT)
		value *= 10;

	/* Pick a treasure variety scaled by level, or force a type */
	if (coin_type != SV_GOLD_ANY)
		sval = coin_type;
	else
		sval = (((value * 100) / MAX_GOLD_DROP) * SV_GOLD_MAX) / 100;

	/* Do not create illegal treasure types */
	if (sval >= SV_GOLD_MAX) sval = SV_GOLD_MAX - 1;

	/* Prepare a gold object */
	object_prep(j_ptr, lookup_kind(TV_GOLD, sval), lev, RANDOMISE);

	/* If we're playing with no_selling, increase the value */
	if (OPT(birth_no_selling) && p_ptr->depth)
		value = value * MIN(5, p_ptr->depth);

	/* Cap gold at max short (or alternatively make pvals s32b) */
	if (value > MAX_SHORT)
		value = MAX_SHORT;

	j_ptr->pval[DEFAULT_PVAL] = value;
}
Exemple #4
0
/**
 * Go up one level
 */
void do_cmd_go_up(struct command *cmd)
{
	int ascend_to;

	/* Verify stairs */
	if (!square_isupstairs(cave, player->py, player->px)) {
		msg("I see no up staircase here.");
		return;
	}

	/* Force descend */
	if (OPT(birth_force_descend)) {
		msg("Nothing happens!");
		return;
	}
	
	ascend_to = dungeon_get_next_level(player->depth, -1);
	
	if (ascend_to == player->depth) {
		msg("You can't go up from here!");
		return;
	}

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

	/* Success */
	msgt(MSG_STAIRS_UP, "You enter a maze of up staircases.");

	/* Create a way back */
	player->upkeep->create_up_stair = false;
	player->upkeep->create_down_stair = true;
	
	/* Change level */
	dungeon_change_level(ascend_to);
}
/* If 'artifacts' is NULL, it counts the number of known artifacts, otherwise
   it collects the list of known artifacts into 'artifacts' as well. */
static int collect_known_artifacts(int *artifacts, size_t artifacts_len)
{
	int a_count = 0;
	int j;

	if (artifacts)
		assert(artifacts_len >= z_info->a_max);

	for (j = 0; j < z_info->a_max; j++)
	{
		/* Artifact doesn't exist */
		if (!a_info[j].name) continue;

		if (OPT(cheat_xtra) || artifact_is_known(j))
		{
			if (artifacts)
				artifacts[a_count++] = j;
			else
				a_count++;
		}
	}

	return a_count;
}
/*
 * Display known objects
 */
void textui_browse_object_knowledge(const char *name, int row)
{
	group_funcs kind_f =
		{ TV_GOLD, FALSE, kind_name, o_cmp_tval, obj2gid, 0 };
	member_funcs obj_f =
		{ display_object, desc_obj_fake, o_xchar, o_xattr, o_xtra_prompt,
		o_xtra_act, 0
	};

	int *objects;
	int o_count = 0;
	int i;
	object_kind *k_ptr;

	objects = C_ZNEW(z_info->k_max, int);

	for (i = 0; i < z_info->k_max; i++) {
		k_ptr = &k_info[i];
		/* It's in the list if we've ever seen it, or it has a flavour, and
		 * either it's not one of the special artifacts, or if it is, we're not 
		 * aware of it yet. This way the flavour appears in the list until it
		 * is found. */
		if ((k_ptr->everseen || k_ptr->flavor || OPT(cheat_xtra))
			&& (!kf_has(k_ptr->flags_kind, KF_INSTA_ART)
				|| !artifact_is_known(get_artifact_from_kind(k_ptr)))) {
			int c = obj_group_order[k_info[i].tval];
			if (c >= 0)
				objects[o_count++] = i;
		}
	}

	display_knowledge("known objects", objects, o_count, kind_f, obj_f,
					  "Squelch  Inscribed          Sym");

	FREE(objects);
}
Exemple #7
0
static void		print_op(t_ps *ps, int op)
{
	if (OPT(OPT_EXEC))
	{
		if (OPT(OPT_VERBOSE))
		{
			if (!(OPT(OPT_INTERACTIVE)))
				ft_putendl(g_ops[op].name);
			print_stacks(ps);
		}
		else if (!OPT(OPT_INTERACTIVE) && !(OPT(OPT_GRAPHIC)))
			ft_printf("%s ", g_ops[op].name);
		if (OPT(OPT_GRAPHIC))
		{
			if ((G_MODE(0)
			|| (G_MODE(1) && !(ps->total_ops % (ps->total_elem / 30 + 1)))
			|| (G_MODE(2) && CURR_VAL(FIRST(ps->stack_a)) == ps->range_min)))
				mlx_redraw(ps, g_ops[op].name);
		}
	}
}
/*
 * Interactive group by.
 * Recognises inscriptions, graphical symbols, lore
 */
static void display_knowledge(const char *title, int *obj_list,
							  int o_count, group_funcs g_funcs,
							  member_funcs o_funcs,
							  const char *otherfields)
{
	/* maximum number of groups to display */
	int max_group = g_funcs.maxnum < o_count ? g_funcs.maxnum : o_count;

	/* This could (should?) be (void **) */
	int *g_list, *g_offset;

	const char **g_names;

	int g_name_len = 8;			/* group name length, minumum is 8 */

	int grp_cnt = 0;			/* total number groups */

	int g_cur = 0, grp_old = -1;	/* group list positions */
	int o_cur = 0;				/* object list positions */
	int g_o_count = 0;			/* object count for group */
	int oid = -1;				/* object identifiers */

	region title_area = { 0, 0, 0, 4 };
	region group_region = { 0, 6, MISSING, -2 };
	region object_region = { MISSING, 6, 0, -2 };

	/* display state variables */
	bool tiles = (current_graphics_mode != NULL);
	bool tile_picker = FALSE;
	bool glyph_picker = FALSE;
	byte attr_top = 0;
	byte char_left = 0;

	int delay = 0;

	menu_type group_menu;
	menu_type object_menu;
	menu_iter object_iter =
		{ NULL, NULL, display_group_member, NULL, NULL };

	/* Panel state */
	/* These are swapped in parallel whenever the actively browsing " */
	/* changes */
	int *active_cursor = &g_cur, *inactive_cursor = &o_cur;
	menu_type *active_menu = &group_menu, *inactive_menu = &object_menu;
	int panel = 0;

	void *swapspace;
	bool do_swap = FALSE;

	bool flag = FALSE;
	bool redraw = TRUE;

	int browser_rows;
	int wid, hgt;
	int i;
	int prev_g = -1;

	int omode = OPT(rogue_like_commands);
	ui_event ke;

	/* Get size */
	Term_get_size(&wid, &hgt);
	browser_rows = hgt - 8;

	/* Disable the roguelike commands for the duration */
	OPT(rogue_like_commands) = FALSE;

	/* Determine if using tiles or not */
	if (tiles)
		tiles = (current_graphics_mode->grafID != 0);

	if (g_funcs.gcomp)
		sort(obj_list, o_count, sizeof(*obj_list), g_funcs.gcomp);

	/* Sort everything into group order */
	g_list = C_ZNEW(max_group + 1, int);
	g_offset = C_ZNEW(max_group + 1, int);

	for (i = 0; i < o_count; i++) {
		if (prev_g != g_funcs.group(obj_list[i])) {
			prev_g = g_funcs.group(obj_list[i]);
			g_offset[grp_cnt] = i;
			g_list[grp_cnt++] = prev_g;
		}
	}

	g_offset[grp_cnt] = o_count;
	g_list[grp_cnt] = -1;


	/* The compact set of group names, in display order */
	g_names = C_ZNEW(grp_cnt, const char *);

	for (i = 0; i < grp_cnt; i++) {
		int len;
		g_names[i] = g_funcs.name(g_list[i]);
		len = strlen(g_names[i]);
		if (len > g_name_len)
			g_name_len = len;
	}

	/* Reasonable max group name len */
	if (g_name_len >= 20)
		g_name_len = 20;

	object_region.col = g_name_len + 3;
	group_region.width = g_name_len;


	/* Leave room for the group summary information */
	if (g_funcs.summary)
		object_region.page_rows = -3;


	/* Set up the two menus */
	menu_init(&group_menu, MN_SKIN_SCROLL,
			  menu_find_iter(MN_ITER_STRINGS));
	menu_setpriv(&group_menu, grp_cnt, g_names);
	menu_layout(&group_menu, &group_region);

	menu_init(&object_menu, MN_SKIN_SCROLL, &object_iter);
	menu_setpriv(&object_menu, 0, &o_funcs);
	menu_layout(&object_menu, &object_region);

	o_funcs.is_visual = FALSE;

	/* Save screen */
	screen_save();
	clear_from(0);


	/* This is the event loop for a multi-region panel */
	/* Panels are -- text panels, two menus, and visual browser */
	/* with "pop-up menu" for lore */
	while ((!flag) && (grp_cnt)) {
		bool recall = FALSE;

		if (redraw) {
			/* Print the title bits */
			region_erase(&title_area);
			prt(format("Knowledge - %s", title), 2, 0);
			prt("Group", 4, 0);
			prt("Name", 4, g_name_len + 3);

			if (otherfields)
				prt(otherfields, 4, 46);


			/* Print dividers: horizontal and vertical */
			for (i = 0; i < 79; i++)
				Term_putch(i, 5, TERM_WHITE, '=');

			for (i = 0; i < browser_rows; i++)
				Term_putch(g_name_len + 1, 6 + i, TERM_WHITE, '|');


			/* Reset redraw flag */
			redraw = FALSE;
		}

		if (g_cur != grp_old) {
			grp_old = g_cur;
			o_cur = 0;
			g_o_count = g_offset[g_cur + 1] - g_offset[g_cur];
			menu_set_filter(&object_menu, obj_list + g_offset[g_cur],
							g_o_count);
			group_menu.cursor = g_cur;
			object_menu.cursor = 0;
		}

		/* HACK ... */
		if (!(tile_picker || glyph_picker)) {
			/* ... The object menu may be browsing the entire group... */
			o_funcs.is_visual = FALSE;
			menu_set_filter(&object_menu, obj_list + g_offset[g_cur],
							g_o_count);
			object_menu.cursor = o_cur;
		} else {
			/* ... or just a single element in the group. */
			o_funcs.is_visual = TRUE;
			menu_set_filter(&object_menu,
							obj_list + o_cur + g_offset[g_cur], 1);
			object_menu.cursor = 0;
		}

		oid = obj_list[g_offset[g_cur] + o_cur];

		/* Print prompt */
		{
			const char *pedit =
				(!o_funcs.xattr) ? "" : (!(attr_idx | char_idx) ?
										 ", 'c' to copy" :
										 ", 'c', 'p' to paste");
			const char *xtra =
				o_funcs.xtra_prompt ? o_funcs.xtra_prompt(oid) : "";
			const char *pvs = "";

			if (tile_picker)
				pvs = ", ENTER to accept";
			else if (glyph_picker)
				pvs = ", 'i' to insert, ENTER to accept";
			else if (o_funcs.xattr)
				pvs = ", 'v' for visuals";

			prt(format("<dir>%s%s%s, ESC", pvs, pedit, xtra), hgt - 1, 0);
		}

		if (do_swap) {
			do_swap = FALSE;
			swap(active_menu, inactive_menu);
			swap(active_cursor, inactive_cursor);
			panel = 1 - panel;
		}

		if (g_funcs.summary && !tile_picker && !glyph_picker) {
			g_funcs.summary(g_cur, obj_list, g_o_count, g_offset[g_cur],
							object_menu.active.row +
							object_menu.active.page_rows,
							object_region.col);
		}

		menu_refresh(inactive_menu, FALSE);
		menu_refresh(active_menu, FALSE);

		handle_stuff(p_ptr);

		if (tile_picker) {
			bigcurs = TRUE;
			display_tiles(g_name_len + 3, 7, browser_rows - 1,
						  wid - (g_name_len + 3), attr_top, char_left);
			place_tile_cursor(g_name_len + 3, 7, *o_funcs.xattr(oid),
							  (byte) * o_funcs.xchar(oid), attr_top,
							  char_left);
		}

		if (glyph_picker) {
			display_glyphs(g_name_len + 3, 7, browser_rows - 1,
						   wid - (g_name_len + 3), *o_funcs.xattr(oid),
						   *o_funcs.xchar(oid));
		}

		if (delay) {
			/* Force screen update */
			Term_fresh();

			/* Delay */
			Term_xtra(TERM_XTRA_DELAY, delay);

			delay = 0;
		}

		ke = inkey_ex();
		if (!tile_picker && !glyph_picker) {
			ui_event ke0 = EVENT_EMPTY;

			if (ke.type == EVT_MOUSE)
				menu_handle_mouse(active_menu, &ke, &ke0);
			else if (ke.type == EVT_KBRD)
				menu_handle_keypress(active_menu, &ke, &ke0);

			if (ke0.type != EVT_NONE)
				ke = ke0;
		}

		/* XXX Do visual mode command if needed */
		if (o_funcs.xattr && o_funcs.xchar) {
			if (tiles) {
				if (tile_picker_command(ke, &tile_picker, browser_rows - 1,
										wid - (g_name_len + 3), &attr_top,
										&char_left, o_funcs.xattr(oid),
										(byte *) o_funcs.xchar(oid),
										g_name_len + 3, 7, &delay))
					continue;
			} else {
				if (glyph_command(ke, &glyph_picker, browser_rows - 1,
								  wid - (g_name_len + 3),
								  o_funcs.xattr(oid), o_funcs.xchar(oid),
								  g_name_len + 3, 7))
					continue;
			}
		}

		switch (ke.type) {
		case EVT_KBRD:
			{
				if (ke.key.code == 'r' || ke.key.code == 'R')
					recall = TRUE;
				else if (o_funcs.xtra_act)
					o_funcs.xtra_act(ke.key, oid);

				break;
			}

		case EVT_MOUSE:
			{
				/* Change active panels */
				if (region_inside(&inactive_menu->boundary, &ke)) {
					swap(active_menu, inactive_menu);
					swap(active_cursor, inactive_cursor);
					panel = 1 - panel;
				}

				continue;
			}

		case EVT_ESCAPE:
			{
				if (panel == 1)
					do_swap = TRUE;
				else
					flag = TRUE;

				break;
			}

		case EVT_SELECT:
			{
				if (panel == 0)
					do_swap = TRUE;
				else if (panel == 1 && oid >= 0
						 && o_cur == active_menu->cursor)
					recall = TRUE;
				break;
			}

		case EVT_MOVE:
			{
				*active_cursor = active_menu->cursor;
				break;
			}

		default:
			{
				break;
			}
		}

		/* Recall on screen */
		if (recall) {
			if (oid >= 0)
				o_funcs.lore(oid);

			redraw = TRUE;
		}
	}

	/* Restore roguelike option */
	OPT(rogue_like_commands) = omode;

	/* Prompt */
	if (!grp_cnt)
		prt(format("No %s known.", title), 15, 0);

	FREE(g_names);
	FREE(g_offset);
	FREE(g_list);

	screen_load();
}
Exemple #9
0
/**
 * Determine the price of an object (qty one) in a store.
 *
 *  store_buying == TRUE  means the shop is buying, player selling
 *               == FALSE means the shop is selling, player buying
 *
 * This function never lets a shop-keeper lose money in a transaction.
 *
 * The "greed" value should exceed 100 when the player is "buying" the
 * object, and should be less than 100 when the player is "selling" it.
 *
 * Hack -- the black market always charges twice as much as it should.
 */
int price_item(struct store *store, const struct object *obj,
			   bool store_buying, int qty)
{
	int adjust = 100;
	int price;
	struct owner *proprietor;

	if (!store) return 0L;

	proprietor = store->owner;

	/* Get the value of the stack of wands, or a single item */
	if (tval_can_have_charges(obj))
		price = object_value(obj, qty, FALSE);
	else
		price = object_value(obj, 1, FALSE);

	/* Worthless items */
	if (price <= 0) return (0L);

	/* The black market is always a worse deal */
	if (store->sidx == STORE_B_MARKET)
		adjust = 150;

	/* Shop is buying */
	if (store_buying) {
		/* Set the factor */
		adjust = 100 + (100 - adjust);
		if (adjust > 100) adjust = 100;

		/* Shops now pay 2/3 of true value */
		price = price * 2 / 3;

		/* Black market sucks */
		if (store->sidx == STORE_B_MARKET)
			price = price / 2;

		/* Check for no_selling option */
		if (OPT(birth_no_selling)) return (0L);
	} else {
		/* Recalculate if the player doesn't know the flavour */
		if (!obj->kind->aware) {
			obj->kind->aware = TRUE;
			if (tval_can_have_charges(obj))
				price = object_value(obj, qty, FALSE);
			else
				price = object_value(obj, 1, FALSE);
			obj->kind->aware = FALSE;
		}

		/* Black market sucks */
		if (store->sidx == STORE_B_MARKET)
			price = price * 2;
	}

	/* Compute the final price (with rounding) */
	price = (price * adjust + 50L) / 100L;

	/* Now convert price to total price for non-wands */
	if (!tval_can_have_charges(obj))
		price *= qty;

	/* Now limit the price to the purse limit */
	if (store_buying && (price > proprietor->max_cost * qty))
		price = proprietor->max_cost * qty;

	/* Note -- Never become "free" */
	if (price <= 0L) return (qty);

	/* Return the price */
	return (price);
}
Exemple #10
0
/*
 * 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;
}
Exemple #11
0
/*
 * Let the user select an item, save its "index"
 *
 * Return TRUE only if an acceptable item was chosen by the user.
 *
 * The selected item must satisfy the "item_tester_hook()" function,
 * if that hook is set, and the "item_tester_tval", if that value is set.
 *
 * All "item_tester" restrictions are cleared before this function returns.
 *
 * The user is allowed to choose acceptable items from the equipment,
 * inventory, or floor, respectively, if the proper flag was given,
 * and there are any acceptable items in that location.
 *
 * The equipment or inventory are displayed (even if no acceptable
 * items are in that location) if the proper flag was given.
 *
 * If there are no acceptable items available anywhere, and "str" is
 * not NULL, then it will be used as the text of a warning message
 * before the function returns.
 *
 * Note that the user must press "-" to specify the item on the floor,
 * and there is no way to "examine" the item on the floor, while the
 * use of "capital" letters will "examine" an inventory/equipment item,
 * and prompt for its use.
 *
 * If a legal item is selected from the inventory, we save it in "cp"
 * directly (0 to 35), and return TRUE.
 *
 * If a legal item is selected from the floor, we save it in "cp" as
 * a negative (-1 to -511), and return TRUE.
 *
 * If no item is available, we do nothing to "cp", and we display a
 * warning message, using "str" if available, and return FALSE.
 *
 * If no item is selected, we do nothing to "cp", and return FALSE.
 *
 * Global "p_ptr->command_wrk" is used to choose between equip/inven/floor
 * listings.  It is equal to USE_INVEN or USE_EQUIP or USE_FLOOR, except
 * when this function is first called, when it is equal to zero, which will
 * cause it to be set to USE_INVEN.
 *
 * We always erase the prompt when we are done, leaving a blank line,
 * or a warning message, if appropriate, if no items are available.
 *
 * Note that only "acceptable" floor objects get indexes, so between two
 * commands, the indexes of floor objects may change.  XXX XXX XXX
 */
bool get_item(int *cp, const char *pmt, const char *str, cmd_code cmd, int mode)
{
	int py = p_ptr->py;
	int px = p_ptr->px;
	unsigned char cmdkey = cmd_lookup_key(cmd,
			OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG);

	//struct keypress which;
	ui_event press;

	int j, k;

	int i1, i2;
	int e1, e2;
	int f1, f2;

	bool done, item;

	bool oops = FALSE;

	bool use_inven = ((mode & USE_INVEN) ? TRUE : FALSE);
	bool use_equip = ((mode & USE_EQUIP) ? TRUE : FALSE);
	bool use_floor = ((mode & USE_FLOOR) ? TRUE : FALSE);
	bool is_harmless = ((mode & IS_HARMLESS) ? TRUE : FALSE);
	bool quiver_tags = ((mode & QUIVER_TAGS) ? TRUE : FALSE);

	int olist_mode = 0;

	bool allow_inven = FALSE;
	bool allow_equip = FALSE;
	bool allow_floor = FALSE;

	bool toggle = FALSE;

	char tmp_val[160];
	char out_val[160];

	int floor_list[MAX_FLOOR_STACK];
	int floor_num;

	bool show_list = TRUE;

	/* Hack - Only shift the command key if it actually needs to be shifted. */
	if (cmdkey < 0x20)
		cmdkey = UN_KTRL(cmdkey);

	/* Object list display modes */
	if (mode & SHOW_FAIL)
		olist_mode |= OLIST_FAIL;
	else
		olist_mode |= OLIST_WEIGHT;

	if (mode & SHOW_PRICES)
		olist_mode |= OLIST_PRICE;

	if (mode & SHOW_EMPTY)
		olist_mode |= OLIST_SEMPTY;

	/* Paranoia XXX XXX XXX */
	message_flush();


	/* Not done */
	done = FALSE;

	/* No item selected */
	item = FALSE;


	/* Full inventory */
	i1 = 0;
	i2 = INVEN_PACK - 1;

	/* Forbid inventory */
	if (!use_inven) i2 = -1;

	/* Restrict inventory indexes */
	while ((i1 <= i2) && (!get_item_okay(i1))) i1++;
	while ((i1 <= i2) && (!get_item_okay(i2))) i2--;

	/* Accept inventory */
	if (i1 <= i2) allow_inven = TRUE;


	/* Full equipment */
	e1 = INVEN_WIELD;
	e2 = ALL_INVEN_TOTAL - 1;

	/* Forbid equipment */
	if (!use_equip) e2 = -1;

	/* Restrict equipment indexes */
	while ((e1 <= e2) && (!get_item_okay(e1))) e1++;
	while ((e1 <= e2) && (!get_item_okay(e2))) e2--;

	/* Accept equipment */
	if (e1 <= e2) allow_equip = TRUE;


	/* Scan all non-gold objects in the grid */
	floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), py, px, 0x0B);

	/* Full floor */
	f1 = 0;
	f2 = floor_num - 1;

	/* Forbid floor */
	if (!use_floor) f2 = -1;

	/* Restrict floor indexes */
	while ((f1 <= f2) && (!get_item_okay(0 - floor_list[f1]))) f1++;
	while ((f1 <= f2) && (!get_item_okay(0 - floor_list[f2]))) f2--;

	/* Accept floor */
	if (f1 <= f2) allow_floor = TRUE;


	/* Require at least one legal choice */
	if (!allow_inven && !allow_equip && !allow_floor)
	{
		/* Oops */
		oops = TRUE;
		done = TRUE;
	}

	/* Analyze choices */
	else
	{
		/* Hack -- Start on equipment if requested */
		if ((p_ptr->command_wrk == USE_EQUIP) && allow_equip)
			p_ptr->command_wrk = USE_EQUIP;
		else if ((p_ptr->command_wrk == USE_INVEN) && allow_inven)
			p_ptr->command_wrk = USE_INVEN;
		else if ((p_ptr->command_wrk == USE_FLOOR) && allow_floor)
			p_ptr->command_wrk = USE_FLOOR;

		/* If we are using the quiver then start on equipment */
		else if (quiver_tags && allow_equip)
			p_ptr->command_wrk = USE_EQUIP;

		/* Use inventory if allowed */
		else if (use_inven && allow_inven)
			p_ptr->command_wrk = USE_INVEN;

		/* Use equipment if allowed */
		else if (use_equip && allow_equip)
			p_ptr->command_wrk = USE_EQUIP;

		/* Use floor if allowed */
		else if (use_floor && allow_floor)
			p_ptr->command_wrk = USE_FLOOR;

		/* Hack -- Use (empty) inventory */
		else
			p_ptr->command_wrk = USE_INVEN;
	}


	/* Start out in "display" mode */
	if (show_list)
	{
		/* Save screen */
		screen_save();
	}


	/* Repeat until done */
	while (!done)
	{
		int ni = 0;
		int ne = 0;

		/* Scan windows */
		for (j = 0; j < ANGBAND_TERM_MAX; j++)
		{
			/* Unused */
			if (!angband_term[j]) continue;

			/* Count windows displaying inven */
			if (op_ptr->window_flag[j] & (PW_INVEN)) ni++;

			/* Count windows displaying equip */
			if (op_ptr->window_flag[j] & (PW_EQUIP)) ne++;
		}

		/* Toggle if needed */
		if (((p_ptr->command_wrk == USE_EQUIP) && ni && !ne) ||
		    ((p_ptr->command_wrk == USE_INVEN) && !ni && ne))
		{
			/* Toggle */
			toggle_inven_equip();

			/* Track toggles */
			toggle = !toggle;
		}

		/* Redraw */
		p_ptr->redraw |= (PR_INVEN | PR_EQUIP);

		/* Redraw windows */
		redraw_stuff(p_ptr);

		/* Viewing inventory */
		if (p_ptr->command_wrk == USE_INVEN)
		{
			int nmode = olist_mode;

			/* Show the quiver counts in certain cases, like the 'i' command */
			if (mode & SHOW_QUIVER)
				nmode |= OLIST_QUIVER;

			/* Redraw if needed */
			if (show_list)
				show_inven(nmode);

			/* Begin the prompt */
			strnfmt(out_val, sizeof(out_val), "Inven:");

			/* List choices */
			if (i1 <= i2)
			{
				/* Build the prompt */
				strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,",
				        index_to_label(i1), index_to_label(i2));

				/* Append */
				my_strcat(out_val, tmp_val, sizeof(out_val));
			}

			/* Indicate ability to "view" */
			if (!show_list)
			{
				my_strcat(out_val, " * to see,", sizeof(out_val));
				button_add("[*]", '*');
			}

			/* Indicate legality of "toggle" */
			if (use_equip)
			{
				my_strcat(out_val, " / for Equip,", sizeof(out_val));
				button_add("[/]", '/');
			}

			/* Indicate legality of the "floor" */
			if (allow_floor)
			{
				my_strcat(out_val, " - for floor,", sizeof(out_val));
				button_add("[-]", '-');
			}
		}

		/* Viewing equipment */
		else if (p_ptr->command_wrk == USE_EQUIP)
		{
			/* Redraw if needed */
			if (show_list) show_equip(olist_mode);

			/* Begin the prompt */
			strnfmt(out_val, sizeof(out_val), "Equip:");

			/* List choices */
			if (e1 <= e2)
			{
				/* Build the prompt */
				strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,",
				        index_to_label(e1), index_to_label(e2));

				/* Append */
				my_strcat(out_val, tmp_val, sizeof(out_val));
			}

			/* Indicate ability to "view" */
			if (!show_list)
			{
				my_strcat(out_val, " * to see,", sizeof(out_val));
				button_add("[*]", '*');
			}

			/* Indicate legality of "toggle" */
			if (use_inven)
			{
				my_strcat(out_val, " / for Inven,", sizeof(out_val));
				button_add("[/]", '/');
			}

			/* Indicate legality of the "floor" */
			if (allow_floor)
			{
				my_strcat(out_val, " - for floor,", sizeof(out_val));
				button_add("[!]", '!');
			}
		}

		/* Viewing floor */
		else
		{
			/* Redraw if needed */
			if (show_list) show_floor(floor_list, floor_num, olist_mode);

			/* Begin the prompt */
			strnfmt(out_val, sizeof(out_val), "Floor:");

			/* List choices */
			if (f1 <= f2)
			{
				/* Build the prompt */
				strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,", I2A(f1), I2A(f2));

				/* Append */
				my_strcat(out_val, tmp_val, sizeof(out_val));
			}

			/* Indicate ability to "view" */
			if (!show_list)
			{
				my_strcat(out_val, " * to see,", sizeof(out_val));
				button_add("[*]", '*');
			}

			/* Append */
			if (use_inven)
			{
				my_strcat(out_val, " / for Inven,", sizeof(out_val));
				button_add("[/]", '/');
			}

			/* Append */
			else if (use_equip)
			{
				my_strcat(out_val, " / for Equip,", sizeof(out_val));
				button_add("[/]", '/');
			}
		}

		redraw_stuff(p_ptr);

		/* Finish the prompt */
		my_strcat(out_val, " ESC", sizeof(out_val));

		/* if we have a prompt header, show the part that we just built */
		if (pmt) {
			/* Build the prompt */
			strnfmt(tmp_val, sizeof(tmp_val), "(%s) %s", out_val, pmt);

			/* Show the prompt */
			prt(tmp_val, 0, 0);
		}

		/* Get a key */
		//which = inkey();
		press = inkey_m();

		/* Parse it */
		if (press.type == EVT_MOUSE) {
			if (press.mouse.button == 2) {
				done = TRUE;
			} else
			if (press.mouse.button == 1) {
				k = -1;
				if (p_ptr->command_wrk == USE_INVEN) {
					if (press.mouse.y == 0) {
						if (use_equip) {
							p_ptr->command_wrk = USE_EQUIP;
						} else
						if (allow_floor) {
							p_ptr->command_wrk = USE_FLOOR;
						}
					} else
					if ((press.mouse.y <= i2-i1+1) ){
					//&& (press.mouse.x > Term->wid - 1 - max_len - ex_width)) {
						//k = label_to_inven(index_to_label(i1+press.mouse.y-1));
						/* get the item index, allowing for skipped indices */
						for (j = i1; j <= i2; j++) {
							if (get_item_okay(j)) {
								if (press.mouse.y == 1) {
									k = j;
									break;
								}
								press.mouse.y--;
							}
						}
					}
				} else
				if (p_ptr->command_wrk == USE_EQUIP) {
					if (press.mouse.y == 0) {
						if (allow_floor) {
							p_ptr->command_wrk = USE_FLOOR;
						} else
						if (use_inven) {
							p_ptr->command_wrk = USE_INVEN;
						}
					} else
					if (press.mouse.y <= e2-e1+1) {
						if (olist_mode & OLIST_SEMPTY) {
							/* If we are showing empties, just set the object (empty objects will just keep the loop going) */
							k = label_to_equip(index_to_label(e1+press.mouse.y-1));
						}
						else {
							/* get the item index, allowing for skipped indices */
							for (j = e1; j <= e2; j++) {
								/* skip the quiver slot which is a blank line in the list */
								if (j == 36) {
									press.mouse.y--;
								} else
									if (get_item_okay(j)) {
										if (press.mouse.y == 1) {
											k = j;
											break;
										}
										press.mouse.y--;
									}
							}
						}
					}
				} else
				if (p_ptr->command_wrk == USE_FLOOR) {
					if (press.mouse.y == 0) {
						if (use_inven) {
							p_ptr->command_wrk = USE_INVEN;
						} else
						if (use_equip) {
							p_ptr->command_wrk = USE_EQUIP;
						}
					} else
					if ((press.mouse.y <= floor_num) && (press.mouse.y >= 1)) {
						/* Special index */
						k = 0 - floor_list[press.mouse.y-1];
						/* get the item index, allowing for skipped indices */
						for (j = f1; j <= f2; j++) {
							if (get_item_okay(0 - floor_list[j])) {
								if (press.mouse.y == 1) {
									k = 0 - floor_list[j];
									break;
								}
								press.mouse.y--;
							}
						}
						/* check the bounds the item number */
						if (k < 0) {
							/* Allow player to "refuse" certain actions */
							if (!get_item_allow(k, cmdkey, cmd, is_harmless))
							{
								done = TRUE;
							}

							/* Accept that choice */
							(*cp) = k;
							item = TRUE;
							done = TRUE;
						} else {
							/* set k to a value that will be invalid below */
							k = -1;
						}
					}
				}
				if (k >= 0) {
					/* Validate the item */
					if (!get_item_okay(k)) {
						bell("Illegal object choice (normal)!");
					}

					/* Allow player to "refuse" certain actions */
					if (!get_item_allow(k, cmdkey, cmd, is_harmless)) {
						done = TRUE;
					}

					/* Accept that choice */
					(*cp) = k;
					item = TRUE;
					done = TRUE;
				} else
				if (press.mouse.y == 0) {
					/* Hack -- Fix screen */
					if (show_list) {
						/* Load screen */
						screen_load();

						/* Save screen */
						screen_save();
					}
				}
			}
		} else
		//switch (which.code)
		switch (press.key.code)
		{
			case ESCAPE:
			case ' ':
			{
				done = TRUE;
				break;
			}

			case '/':
			{
				/* Toggle to inventory */
				if (use_inven && (p_ptr->command_wrk != USE_INVEN))
				{
					p_ptr->command_wrk = USE_INVEN;
				}

				/* Toggle to equipment */
				else if (use_equip && (p_ptr->command_wrk != USE_EQUIP))
				{
					p_ptr->command_wrk = USE_EQUIP;
				}

				/* No toggle allowed */
				else
				{
					bell("Cannot switch item selector!");
					break;
				}


				/* Hack -- Fix screen */
				if (show_list)
				{
					/* Load screen */
					screen_load();

					/* Save screen */
					screen_save();
				}

				/* Need to redraw */
				break;
			}

			case '-':
			{
				/* Paranoia */
				if (!allow_floor)
				{
					bell("Cannot select floor!");
					break;
				}

				/* There is only one item */
				if (floor_num == 1)
				{
					/* Auto-select */
					if (p_ptr->command_wrk == (USE_FLOOR))
					{
						/* Special index */
						k = 0 - floor_list[0];

						/* Allow player to "refuse" certain actions */
						if (!get_item_allow(k, cmdkey, cmd, is_harmless))
						{
							done = TRUE;
							break;
						}

						/* Accept that choice */
						(*cp) = k;
						item = TRUE;
						done = TRUE;

						break;
					}
				}

				/* Hack -- Fix screen */
				if (show_list)
				{
					/* Load screen */
					screen_load();

					/* Save screen */
					screen_save();
				}

				p_ptr->command_wrk = (USE_FLOOR);

#if 0
				/* Check each legal object */
				for (i = 0; i < floor_num; ++i)
				{
					/* Special index */
					k = 0 - floor_list[i];

					/* Skip non-okay objects */
					if (!get_item_okay(k)) continue;

					/* Allow player to "refuse" certain actions */
					if (!get_item_allow(k, cmdkey, cmd, is_harmless)) continue;

					/* Accept that choice */
					(*cp) = k;
					item = TRUE;
					done = TRUE;
					break;
				}
#endif

				break;
			}

			case '0':
			case '1': case '2': case '3':
			case '4': case '5': case '6':
			case '7': case '8': case '9':
			{
				/* Look up the tag */
				//if (!get_tag(&k, which.code, cmd, quiver_tags))
				if (!get_tag(&k, press.key.code, cmd, quiver_tags))
				{
					bell("Illegal object choice (tag)!");
					break;
				}

				/* Hack -- Validate the item */
				if ((k < INVEN_WIELD) ? !allow_inven : !allow_equip)
				{
					bell("Illegal object choice (tag)!");
					break;
				}

				/* Validate the item */
				if (!get_item_okay(k))
				{
					bell("Illegal object choice (tag)!");
					break;
				}

				/* Allow player to "refuse" certain actions */
				if (!get_item_allow(k, cmdkey, cmd, is_harmless))
				{
					done = TRUE;
					break;
				}

				/* Accept that choice */
				(*cp) = k;
				item = TRUE;
				done = TRUE;
				break;
			}

			case KC_ENTER:
			{
				/* Choose "default" inventory item */
				if (p_ptr->command_wrk == USE_INVEN)
				{
					if (i1 != i2)
					{
						bell("Illegal object choice (default)!");
						break;
					}

					k = i1;
				}

				/* Choose the "default" slot (0) of the quiver */
				else if (quiver_tags)
					k = e1;

				/* Choose "default" equipment item */
				else if (p_ptr->command_wrk == USE_EQUIP)
				{
					if (e1 != e2)
					{
						bell("Illegal object choice (default)!");
						break;
					}

					k = e1;
				}

				/* Choose "default" floor item */
				else
				{
					if (f1 != f2)
					{
						bell("Illegal object choice (default)!");
						break;
					}

					k = 0 - floor_list[f1];
				}

				/* Validate the item */
				if (!get_item_okay(k))
				{
					bell("Illegal object choice (default)!");
					break;
				}

				/* Allow player to "refuse" certain actions */
				if (!get_item_allow(k, cmdkey, cmd, is_harmless))
				{
					done = TRUE;
					break;
				}

				/* Accept that choice */
				(*cp) = k;
				item = TRUE;
				done = TRUE;
				break;
			}

			default:
			{
				bool verify;

				/* Note verify */
				//verify = (isupper((unsigned char)which.code) ? TRUE : FALSE);
				verify = (isupper((unsigned char)press.key.code) ? TRUE : FALSE);

				/* Lowercase */
				//which.code = tolower((unsigned char)which.code);
				press.key.code = tolower((unsigned char)press.key.code);

				/* Convert letter to inventory index */
				if (p_ptr->command_wrk == USE_INVEN)
				{
					//k = label_to_inven(which.code);
					k = label_to_inven(press.key.code);

					if (k < 0)
					{
						bell("Illegal object choice (inven)!");
						break;
					}
				}

				/* Convert letter to equipment index */
				else if (p_ptr->command_wrk == USE_EQUIP)
				{
					//k = label_to_equip(which.code);
					k = label_to_equip(press.key.code);

					if (k < 0)
					{
						bell("Illegal object choice (equip)!");
						break;
					}
				}

				/* Convert letter to floor index */
				else
				{
					//k = (islower((unsigned char)which.code) ? A2I((unsigned char)which.code) : -1);
					k = (islower((unsigned char)press.key.code) ? A2I((unsigned char)press.key.code) : -1);

					if (k < 0 || k >= floor_num)
					{
						bell("Illegal object choice (floor)!");
						break;
					}

					/* Special index */
					k = 0 - floor_list[k];
				}

				/* Validate the item */
				if (!get_item_okay(k))
				{
					bell("Illegal object choice (normal)!");
					break;
				}

				/* Verify the item */
				if (verify && !verify_item("Try", k))
				{
					done = TRUE;
					break;
				}

				/* Allow player to "refuse" certain actions */
				if (!get_item_allow(k, cmdkey, cmd, is_harmless))
				{
					done = TRUE;
					break;
				}

				/* Accept that choice */
				(*cp) = k;
				item = TRUE;
				done = TRUE;
				break;
			}
		}
	}


	/* Fix the screen if necessary */
	if (show_list)
	{
		/* Load screen */
		screen_load();

		/* Hack -- Cancel "display" */
		show_list = FALSE;
	}


	/* Kill buttons */
	button_kill('*');
	button_kill('/');
	button_kill('-');
	button_kill('!');
	redraw_stuff(p_ptr);
 
	/* Forget the item_tester_tval restriction */
	item_tester_tval = 0;

	/* Forget the item_tester_hook restriction */
	item_tester_hook = NULL;


	/* Toggle again if needed */
	if (toggle) toggle_inven_equip();

	/* Update */
	p_ptr->redraw |= (PR_INVEN | PR_EQUIP);
	redraw_stuff(p_ptr);


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

	/* Warning if needed */
	if (oops && str) msg("%s", str);

	/* Result */
	return (item);
}
Exemple #12
0
#include "stdg.h"
#include "error_msg.h"

extern Option OPT(CallFuture);
extern Option OPT(PutFuture);
extern Option OPT(Swing);

Option* OPT(family)[]=
{
  &OPT(CallFuture),
  &OPT(PutFuture),
  &OPT(Swing),
  NULL
};
Exemple #13
0
/*
 * Get a keypress from the user.
 *
 * This function recognizes a few "global parameters".  These are variables
 * which, if set to TRUE before calling this function, will have an effect
 * on this function, and which are always reset to FALSE by this function
 * before this function returns.  Thus they function just like normal
 * parameters, except that most calls to this function can ignore them.
 *
 * If "inkey_xtra" is TRUE, then all pending keypresses will be flushed.
 * This is set by flush(), which doesn't actually flush anything itself
 * but uses that flag to trigger delayed flushing.
 *
 * If "inkey_scan" is TRUE, then we will immediately return "zero" if no
 * keypress is available, instead of waiting for a keypress.
 *
 * If "inkey_flag" is TRUE, then we are waiting for a command in the main
 * map interface, and we shouldn't show a cursor.
 *
 * If we are waiting for a keypress, and no keypress is ready, then we will
 * refresh (once) the window which was active when this function was called.
 *
 * Note that "back-quote" is automatically converted into "escape" for
 * convenience on machines with no "escape" key.
 *
 * If "angband_term[0]" is not active, we will make it active during this
 * function, so that the various "main-xxx.c" files can assume that input
 * is only requested (via "Term_inkey()") when "angband_term[0]" is active.
 *
 * Mega-Hack -- This function is used as the entry point for clearing the
 * "signal_count" variable, and of the "character_saved" variable.
 *
 * Mega-Hack -- Note the use of "inkey_hack" to allow the "Borg" to steal
 * control of the keyboard from the user.
 */
ui_event inkey_ex(void)
{
	bool cursor_state;
	ui_event kk;
	ui_event ke = EVENT_EMPTY;

	bool done = FALSE;

	term *old = Term;

	/* Delayed flush */
	if (inkey_xtra) {
		Term_flush();
		inkey_next = NULL;
		inkey_xtra = FALSE;
	}

	/* Hack -- Use the "inkey_next" pointer */
	if (inkey_next && inkey_next->code)
	{
		/* Get next character, and advance */
		ke.key = *inkey_next++;

		/* Cancel the various "global parameters" */
		inkey_flag = FALSE;
		inkey_scan = 0;

		/* Accept result */
		return (ke);
	}

	/* Forget pointer */
	inkey_next = NULL;

#ifdef ALLOW_BORG

	/* Mega-Hack -- Use the special hook */
	if (inkey_hack)
	{
		ke.key = (*inkey_hack)(inkey_xtra);
		if (ke.key.type != EVT_NONE)
		{
			/* Cancel the various "global parameters" */
			inkey_flag = FALSE;
			inkey_scan = 0;
			ke.type = EVT_KBRD;

			/* Accept result */
			return (ke);
		}
	}

#endif /* ALLOW_BORG */


	/* Get the cursor state */
	(void)Term_get_cursor(&cursor_state);

	/* Show the cursor if waiting, except sometimes in "command" mode */
	if (!inkey_scan && (!inkey_flag || character_icky))
		(void)Term_set_cursor(TRUE);


	/* Hack -- Activate main screen */
	Term_activate(term_screen);


	/* Get a key */
	while (ke.type == EVT_NONE)
	{
		/* Hack -- Handle "inkey_scan == SCAN_INSTANT */
		if (inkey_scan == SCAN_INSTANT &&
				(0 != Term_inkey(&kk, FALSE, FALSE)))
			break;


		/* Hack -- Flush output once when no key ready */
		if (!done && (0 != Term_inkey(&kk, FALSE, FALSE)))
		{
			/* Hack -- activate proper term */
			Term_activate(old);

			/* Flush output */
			Term_fresh();

			/* Hack -- activate main screen */
			Term_activate(term_screen);

			/* Mega-Hack -- reset saved flag */
			character_saved = FALSE;

			/* Mega-Hack -- reset signal counter */
			signal_count = 0;

			/* Only once */
			done = TRUE;
		}


		/* Get a key (see above) */
		ke = inkey_aux(inkey_scan);

		/* Handle mouse buttons */
		if ((ke.type == EVT_MOUSE) && (OPT(mouse_buttons)))
		{
			/* Check to see if we've hit a button */
			/* Assuming text buttons here for now - this would have to
			 * change for GUI buttons */
			char key = button_get_key(ke.mouse.x, ke.mouse.y);

			if (key)
			{
				/* Rewrite the event */
				/* XXXmacro button implementation needs updating */
				ke.type = EVT_BUTTON;
				ke.key.code = key;
				ke.key.mods = 0;

				/* Done */
				break;
			}
		}

		/* Treat back-quote as escape */
		if (ke.key.code == '`')
			ke.key.code = ESCAPE;
	}


	/* Hack -- restore the term */
	Term_activate(old);


	/* Restore the cursor */
	Term_set_cursor(cursor_state);


	/* Cancel the various "global parameters" */
	inkey_flag = FALSE;
	inkey_scan = 0;

	/* Return the keypress */
	return (ke);
}
optimize P1(parse_node_t *, expr) {
    if (!expr) return 0;

    switch (expr->kind) {
    case NODE_TERNARY_OP:
	OPT(expr->l.expr);
	OPT(expr->r.expr->l.expr);
	OPT(expr->r.expr->r.expr);
	break;
    case NODE_BINARY_OP:
	OPT(expr->l.expr);
	if (expr->v.number == F_ASSIGN) {
	    if (IS_NODE(expr->r.expr, NODE_OPCODE_1, F_LOCAL_LVALUE)) {
		if (!optimizer_state) {
		    int x = expr->r.expr->l.number;

		    if (last_local_refs[x]) {
			last_local_refs[x]->v.number = F_TRANSFER_LOCAL;
			last_local_refs[x] = 0;
		    }
		}
	    }
	}
	OPT(expr->r.expr);
	break;
    case NODE_UNARY_OP:
	OPT(expr->r.expr);
	break;
    case NODE_OPCODE:
	break;
    case NODE_TERNARY_OP_1:
	OPT(expr->l.expr);
	OPT(expr->r.expr->l.expr);
	OPT(expr->r.expr->r.expr);
	break;
    case NODE_BINARY_OP_1:
	OPT(expr->l.expr);
	OPT(expr->r.expr);
	break;
    case NODE_UNARY_OP_1:
	OPT(expr->r.expr);
	if (expr->v.number == F_VOID_ASSIGN_LOCAL) {
	    if (last_local_refs[expr->l.number]	&& !optimizer_state) {
		last_local_refs[expr->l.number]->v.number = F_TRANSFER_LOCAL;
		last_local_refs[expr->l.number] = 0;
	    }
	}
	break;
    case NODE_OPCODE_1:
	if (expr->v.number == F_LOCAL || expr->v.number == F_LOCAL_LVALUE) {
	    if (expr->v.number == F_LOCAL) {
		if(!optimizer_state) {
		    last_local_refs[expr->l.number] = expr;
		    break;
		}
	    }
	    last_local_refs[expr->l.number] = 0;
	}
	break;
    case NODE_OPCODE_2:
	break;
    case NODE_RETURN:
	OPT(expr->r.expr);
	break;
    case NODE_STRING:
    case NODE_REAL:
    case NODE_NUMBER:
	break;
    case NODE_LAND_LOR:
    case NODE_BRANCH_LINK:
	OPT(expr->l.expr);
	OPT(expr->r.expr);
	break;
    case NODE_CALL_2:
    case NODE_CALL_1:
    case NODE_CALL:
	optimize_expr_list(expr->r.expr);
	break;
    case NODE_TWO_VALUES:
	OPT(expr->l.expr);
	OPT(expr->r.expr);
	break;
    case NODE_CONTROL_JUMP:
    case NODE_PARAMETER:
    case NODE_PARAMETER_LVALUE:
	break;
    case NODE_IF:
	{
	    int in_cond;
	    OPT(expr->v.expr);
	    in_cond = (optimizer_state & OPTIMIZER_IN_COND);
	    optimizer_state |= OPTIMIZER_IN_COND;
	    OPT(expr->l.expr);
	    OPT(expr->r.expr);
	    optimizer_state &= ~OPTIMIZER_IN_COND;
	    optimizer_state |= in_cond;
	    break;
	}
    case NODE_LOOP:
	{
	    int in_loop = (optimizer_state & OPTIMIZER_IN_LOOP);
	    optimizer_state |= OPTIMIZER_IN_LOOP;
	    OPT(expr->v.expr);
	    OPT(expr->l.expr);
	    OPT(expr->r.expr);
	    optimizer_state &= ~OPTIMIZER_IN_LOOP;
	    optimizer_state |= in_loop;
	    break;
	}
    case NODE_FOREACH:
	OPT(expr->l.expr);
	OPT(expr->r.expr);
	OPT(expr->v.expr);
	break;
    case NODE_CASE_NUMBER:
    case NODE_CASE_STRING:
    case NODE_DEFAULT:
	break;
    case NODE_SWITCH_STRINGS:
    case NODE_SWITCH_NUMBERS:
    case NODE_SWITCH_DIRECT:
    case NODE_SWITCH_RANGES:
	{
	    int in_cond;
	    OPT(expr->l.expr);
	    in_cond = (optimizer_state & OPTIMIZER_IN_COND);
	    optimizer_state |= OPTIMIZER_IN_COND;
	    OPT(expr->r.expr);
	    optimizer_state &= ~OPTIMIZER_IN_COND;
	    optimizer_state |= in_cond;
	    break;
	}
    case NODE_CATCH:
	OPT(expr->r.expr);
	break;
    case NODE_LVALUE_EFUN:
	OPT(expr->l.expr);
	optimize_lvalue_list(expr->r.expr);
	break;

    case NODE_FUNCTION_CONSTRUCTOR:
	/* Don't optimize inside of these; we'll get confused by local vars
	 * since it's a separate frame, etc
	 *
	 * OPT(expr->r.expr);
	 *
	 * BUT make sure to optimize the things which AREN'T part of that
	 * frame, namely, the arguments, otherwise we will screw up:
	 *
	 * use(local); return (: foo, local :);       // local evaluated at
	 * use(local); return (: ... $(local) ... :); // construction time
	 */
	if (expr->r.expr)
	    optimize_expr_list(expr->r.expr); /* arguments */
	break;
    case NODE_ANON_FUNC:
	break;
    case NODE_EFUN:
	optimize_expr_list(expr->r.expr);
	break;
    default:
	break;
    }
    return expr;
}
Exemple #15
0
/*
 * Print an item's flavour text.
 *
 * \param tb is the textblock to which we are adding.
 * \param o_ptr is the object we are describing.
 * \param ego is whether we're describing an ego template (as opposed to a
 * real object)
 */
static void describe_flavor_text(textblock *tb, const object_type *o_ptr,
	oinfo_detail_t mode)
{
	int i, count = 0;
	bool ego = mode & OINFO_EGO;
	bool subj = mode & OINFO_SUBJ;

	/* Display the known artifact description */
	if (!OPT(birth_randarts) && o_ptr->artifact &&
			object_is_known(o_ptr) && o_ptr->artifact->text)
		textblock_append(tb, "%s\n\n", o_ptr->artifact->text);

	else if (o_ptr->theme && o_ptr->theme->text &&
			object_theme_is_known(o_ptr))
		textblock_append(tb, "%s\n\n", o_ptr->theme->text);

	/* Display the known object description */
	else if (object_flavor_is_aware(o_ptr) || object_is_known(o_ptr) || ego) {
		bool did_desc = FALSE;

		if (!ego && o_ptr->kind->text) {
			textblock_append(tb, "%s", o_ptr->kind->text);
			did_desc = TRUE;
		}

		/* Display additional affix descriptions */
		for (i = 0; i < MAX_AFFIXES && o_ptr->affix[i]; i++)
			if (o_ptr->affix[i]->text && (ego ||
					object_affix_is_known(o_ptr, o_ptr->affix[i]->eidx))) {
				if (did_desc)
					textblock_append(tb, " ");
				textblock_append(tb, "%s", o_ptr->affix[i]->text);
				did_desc = TRUE;
			}

		if (did_desc)
			textblock_append(tb, "\n\n");
	}

	/* List the affixes on the item */
	for (i = 0; i < MAX_AFFIXES && o_ptr->affix[i]; i++)
		if (object_affix_is_known(o_ptr, o_ptr->affix[i]->eidx)) {
			if (count == 0)
				textblock_append(tb, "This item's known properties are: ");
			else
				textblock_append(tb, ", ");
			textblock_append(tb, "%s", o_ptr->affix[i]->name);
			count++;
		}
	if (count)
		textblock_append(tb, ".\n\n");

	if (!ego && subj && o_ptr->origin != ORIGIN_STORE) {
		/* List the item's known runes */
		count = 0;
		for (i = 0; i < OF_MAX; i++)
			if (of_has(o_ptr->flags, i) && of_has(p_ptr->known_runes, i) &&
					obj_flag_type(i) != OFT_INT && obj_flag_type(i) != OFT_NONE) {
				if (count == 0)
					textblock_append(tb, "This item's known runes are: ");
				else
					textblock_append(tb, ", ");
				textblock_append(tb, "%s", flag_name(i));
				count++;
			}
		if (count)
			textblock_append(tb, ".\n\n");

		/* List the item's unknown runes */
		count = 0;
		for (i = 0; i < OF_MAX; i++)
			if (of_has(o_ptr->flags, i) && !of_has(p_ptr->known_runes, i) &&
					obj_flag_type(i) != OFT_INT && obj_flag_type(i) != OFT_NONE) {
				if (count == 0)
					textblock_append(tb, "This item's unknown runes are: ");
				else
					textblock_append(tb, ", ");
				textblock_append(tb, "%s", flag_rune(i));
				count++;
			}
		if (count)
			textblock_append(tb, ".\n\n");
	}
}
int
main(int argc, char *argv[])
{
	int ret = 1, istty, i, idx;
	char *msg = NULL, *timer = NULL, *at_end = NULL, *halfway = NULL;
	dldev_t dev;
	tymer_t db;
	u8 *data;
	u16 len;

	/* for data security */
	/*
	umask(S_IRWXG | S_IRWXO);
	*/

	istty = isatty(0);

	i = strlen(argv[0]) - 1;
	for(; i >= 0 && argv[0][i] != '/'; i--);
	i++;
	if(strstr(argv[0] + i, "interval")){
		set_timer(POR_INTERVAL);
		is_countdn = 0;
	}

	while((i = getopt(argc, argv, "hd:")) != -1){
		switch(i){
		case 'd':
			dev_file = optarg;
			break;
		case 'h':
		default:
			usage();
			break;
		}
	}
	argc -= optind;
	argv += optind;

#ifdef USB_USBHID
	dev.usb.file = dev_file;
#endif

	BEGIN_OPT()
		OPT("msg", msg)
		OPT("timer", timer)
		OPT("at_end", at_end)
		OPT("halfway", halfway)
	END_OPT()

	/* allows the user to change only at_end in interval timer */
	if(istty && ((!msg || !timer) && (is_countdn || !at_end)))
		usage();

	if(open_dev(&dev)){
		ERROR("open_dev");
		goto exit;
	}

	if(start_session(&dev)){
		ERROR("read_app_info");
		goto exit;
	}

/******************************************************************************/
#ifdef DEBUG
	for(i = 0; i < NUM_APPS; i++){
		if(!dev.app[i].acd.app_idx)
			continue;
		printf("%2d: %d%d%d%d%d%d%d%d %02x %02x %04x %04x %04x %04x %04x %04x %s\n", i,
				dev.app[i].acd.app_idx,
				dev.app[i].acd.code_loc,
				dev.app[i].acd.db_loc,
				dev.app[i].acd.code_invalid,
				dev.app[i].acd.db_modified,
				dev.app[i].acd.db_invalid,
				dev.app[i].acd.passwd_req,
				dev.app[i].acd.mode_name,

				dev.app[i].acb.app_type,
				dev.app[i].acb.app_inst,
				dev.app[i].acb.asd_addr,
				dev.app[i].acb.add_addr,
				dev.app[i].acb.state_mgr_addr,
				dev.app[i].acb.refresh_addr,
				dev.app[i].acb.banner_addr,
				dev.app[i].acb.code_addr,
				dev.app[i].banner
		);
	}
#endif
/******************************************************************************/

	if((idx = find_app(&dev, uapp_name)) < 0){
		ERROR("%s application not found", uapp_name);
		goto end;
	}

	if(dump_add(&dev, idx, &data, &len)){
		ERROR("dump_add");
		goto end;
	}
	read_timer(&db, data);
	free(data);

	if(!istty)
		add_timer_file(&db, stdin);

	if(msg && timer){
		char buf[BUFSIZ];
		timer_data_t rec;

		sprintf(buf, "%s\t%s\t%s%s", msg, timer,
			(at_end ? at_end : "stop"),
			(halfway && strcmp(halfway, "no") ? "\thalfway" : ""));
		if(read_timer_line(&rec, buf))
			fprintf(stderr, "add_%s: format error!\n", lapp_name);
		else
		if(find_timer(&db, &rec) < 0)
			add_timer(&db, &rec);
	}
	if(!is_countdn && at_end){
		int i;

		for(i = 0; i < 3 && strcmp(at_end, timer_at_end[i]); i++);
		if(i < 3){
			set_timer_at_end(i);
			update_timer_at_end(&db);
		}
	}

	create_timer(&db, &data, &len);
	if(load_add(&dev, idx, data)){
		ERROR("load_add");
		goto end;
	}
	free(data);

	print_timer(&db, stdout);
	free_timer(&db);

/******************************************************************************/
end:
	if(end_session(&dev)){
		ERROR("end_session");
		goto exit;
	}

	ret = 0;
exit:
	close_dev(&dev);

	exit(ret);
}
/*
 * Display the objects in a group.
 */
static void display_object(int col, int row, bool cursor, int oid)
{
	int k_idx = oid;

	object_kind *k_ptr = &k_info[k_idx];
	const char *inscrip = get_autoinscription(oid);

	char o_name[80];

	/* Choose a color */
	bool aware = (!k_ptr->flavor || k_ptr->aware);
	byte attr = curs_attrs[(int) aware][(int) cursor];

	/* Find graphics bits -- versions of the object_char and object_attr
	 * defines */
	bool use_flavour = (k_ptr->flavor) && !(aware
											&& k_ptr->tval == TV_SCROLL);

	byte a =
		use_flavour ? flavor_info[k_ptr->flavor].x_attr : k_ptr->x_attr;
	wchar_t c =
		use_flavour ? flavor_info[k_ptr->flavor].x_char : k_ptr->x_char;

	/* Display known artifacts differently */
	if (kf_has(k_ptr->flags_kind, KF_INSTA_ART)
		&& artifact_is_known(get_artifact_from_kind(k_ptr))) {
		get_artifact_display_name(o_name, sizeof(o_name),
								  get_artifact_from_kind(k_ptr));
	} else {
		object_kind_name(o_name, sizeof(o_name), k_idx, OPT(cheat_know));
	}

	/* If the type is "tried", display that */
	if (k_ptr->tried && !aware)
		my_strcat(o_name, " {tried}", sizeof(o_name));

	/* Display the name */
	c_prt(attr, o_name, row, col);

	/* Object recall window */
	if (cursor) {
		character_icky--;
		character_icky--;
		p_ptr->object_kind_idx = k_idx;
		p_ptr->redraw |= PR_OBJECT;
		handle_stuff(p_ptr);
		character_icky++;
		character_icky++;
	}

	/* Show autoinscription if around */
	if (aware && inscrip)
		c_put_str(TERM_YELLOW, inscrip, row, 55);

	/* Hack - don't use if double tile */
	if ((tile_width > 1) || (tile_height > 1))
		return;

	/* Display symbol */
	big_pad(76, row, a, c);
}
/*
 * Display known monsters.
 */
static void do_cmd_knowledge_monsters(const char *name, int row)
{
	group_funcs r_funcs = { N_ELEMENTS(monster_group), FALSE, race_name,
		m_cmp_race, default_group, mon_summary
	};

	member_funcs m_funcs =
		{ display_monster, mon_lore, m_xchar, m_xattr, recall_prompt, 0,
0 };

	int *monsters;
	int m_count = 0;
	int i;
	size_t j;

	for (i = 0; i < z_info->r_max; i++) {
		monster_race *r_ptr = &r_info[i];
		if (!OPT(cheat_know) && !l_list[i].sights)
			continue;
		if (!r_ptr->name)
			continue;

		if (rf_has(r_ptr->flags, RF_UNIQUE))
			m_count++;

		for (j = 1; j < N_ELEMENTS(monster_group) - 1; j++) {
			const wchar_t *pat = monster_group[j].chars;
			if (wcschr(pat, r_ptr->d_char))
				m_count++;
		}
	}

	default_join = C_ZNEW(m_count, join_t);
	monsters = C_ZNEW(m_count, int);

	m_count = 0;
	for (i = 0; i < z_info->r_max; i++) {
		monster_race *r_ptr = &r_info[i];
		if (!OPT(cheat_know) && !l_list[i].sights)
			continue;
		if (!r_ptr->name)
			continue;

		for (j = 0; j < N_ELEMENTS(monster_group) - 1; j++) {
			const wchar_t *pat = monster_group[j].chars;
			if (j == 0 && !(rf_has(r_ptr->flags, RF_UNIQUE)))
				continue;
			else if (j > 0 && !wcschr(pat, r_ptr->d_char))
				continue;

			monsters[m_count] = m_count;
			default_join[m_count].oid = i;
			default_join[m_count++].gid = j;
		}
	}

	display_knowledge("monsters", monsters, m_count, r_funcs, m_funcs,
					  "                   Sym  Kills");
	FREE(default_join);
	FREE(monsters);
}
enum http_rc_e
action_forward (struct req_args_s *args)
{
	const char *id = OPT("id");
	const char *action = TOK("ACTION");

	if (!id)
		return _reply_format_error (args, BADREQ("Missing SRVID"));
	if (!action)
		return _reply_format_error (args, BADREQ("Missing action"));

	GError *err = NULL;
	if (!g_ascii_strcasecmp (action, "flush")) {
		err = sqlx_remote_execute_FLUSH (id);
		if (!err)
			return _reply_success_json (args, NULL);
		return _reply_common_error (args, err);
	}
	if (!g_ascii_strcasecmp (action, "reload")) {
		err = sqlx_remote_execute_RELOAD (id);
		if (!err)
			return _reply_success_json (args, NULL);
		return _reply_common_error (args, err);
	}
	if (!g_ascii_strcasecmp (action, "kill")) {
		GByteArray *encoded = message_marshall_gba_and_clean (
				metautils_message_create_named("REQ_KILL"));
		err = gridd_client_exec (id, 1.0, encoded);
		if (err)
			return _reply_common_error (args, err);
		return _reply_success_json (args, NULL);
	}
	if (!g_ascii_strcasecmp (action, "ping")) {
		args->rp->no_access();
		GByteArray *encoded = message_marshall_gba_and_clean (
				metautils_message_create_named("REQ_PING"));
		err = gridd_client_exec (id, 1.0, encoded);
		if (err)
			return _reply_common_error (args, err);
		return _reply_success_json (args, NULL);
	}
	if (!g_ascii_strcasecmp (action, "lean-glib")) {
		MESSAGE req = metautils_message_create_named("REQ_LEAN");
		metautils_message_add_field_str(req, "LIBC", "1");
		metautils_message_add_field_str(req, "THREADS", "1");
		GByteArray *encoded = message_marshall_gba_and_clean (req);
		err = gridd_client_exec (id, 1.0, encoded);
		if (err)
			return _reply_common_error (args, err);
		return _reply_success_json (args, NULL);
	}

	if (!g_ascii_strcasecmp (action, "lean-sqlx")) {
		GByteArray *encoded = message_marshall_gba_and_clean (
				metautils_message_create_named(NAME_MSGNAME_SQLX_LEANIFY));
		err = gridd_client_exec (id, 1.0, encoded);
		if (err)
			return _reply_common_error (args, err);
		return _reply_success_json (args, NULL);
	}

	if (!g_ascii_strcasecmp (action, "version")) {
		args->rp->no_access();
		MESSAGE req = metautils_message_create_named("REQ_VERSION");
		GByteArray *encoded = message_marshall_gba_and_clean (req);
		gchar *packed = NULL;
		err = gridd_client_exec_and_concat_string (id, 1.0, encoded, &packed);
		if (err) {
			g_free0 (packed);
			return _reply_common_error (args, err);
		}

		/* TODO(jfs): quite duplicated from _reply_json() but the original
		   was not suitable. */
		args->rp->set_status (200, "OK");
		args->rp->set_body_bytes (g_bytes_new_take((guint8*)packed, strlen(packed)));
		args->rp->finalize ();
		return HTTPRC_DONE;
	}

	if (!g_ascii_strcasecmp (action, "handlers")) {
		args->rp->no_access();
		MESSAGE req = metautils_message_create_named("REQ_HANDLERS");
		GByteArray *encoded = message_marshall_gba_and_clean (req);
		gchar *packed = NULL;
		err = gridd_client_exec_and_concat_string (id, 1.0, encoded, &packed);
		if (err) {
			g_free0 (packed);
			return _reply_common_error (args, err);
		}

		/* TODO(jfs): quite duplicated from _reply_json() but the original
		   was not suitable. */
		args->rp->set_status (200, "OK");
		args->rp->set_body_bytes (g_bytes_new_take((guint8*)packed, strlen(packed)));
		args->rp->finalize ();
		return HTTPRC_DONE;
	}

	return _reply_common_error (args, BADREQ("unexpected action"));
}
Exemple #20
0
/**
 * Returns TRUE if an item should be hidden due to the player's
 * current settings.
 */
bool squelch_hide_item(object_type * o_ptr)
{
	return (OPT(hide_squelchable) ? squelch_item_ok(o_ptr) : FALSE);
}
Exemple #21
0
/* Cast the specified spell */
bool spell_cast(int spell, int dir)
{
    int chance;
    int plev = p_ptr->lev;
    bool failed = FALSE;
    int py = p_ptr->py;
    int px = p_ptr->px;

    /* Get the spell */
    const magic_type *mt_ptr = &mp_ptr->info[spell];

    /* Spell failure chance */
    chance = spell_chance(spell);

    /* Specialty Ability */
    if (player_has(PF_HEIGHTEN_MAGIC))
	plev += 1 + ((p_ptr->heighten_power + 5) / 10);
    if (player_has(PF_CHANNELING))
	plev += get_channeling_boost();

    /* Failed spell */
    if (randint0(100) < chance) {
	failed = TRUE;

	if (OPT(flush_failure))
	    flush();
	msg(magic_desc[mp_ptr->spell_realm][SPELL_FAIL]);
    }

    /* Process spell */
    else {
	/* Cast the spell */
	if (!cast_spell(mp_ptr->spell_book, mt_ptr->index, dir, plev))
	    return FALSE;

	/* A spell was cast */
	sound(MSG_SPELL);


	/* A spell was cast or a prayer prayed */
	if (!(p_ptr->spell_flags[spell] & PY_SPELL_WORKED)){
	    int e = mt_ptr->sexp;

	    /* The spell worked */
	    p_ptr->spell_flags[spell] |= PY_SPELL_WORKED;

	    /* Gain experience */
	    gain_exp(e * mt_ptr->slevel);
	    
	    /* Redraw object recall */
	    p_ptr->redraw |= (PR_OBJECT);
	}
    }

    /* Hack - simplify rune of mana calculations by fully draining the rune
     * first */
    if (cave_trap_specific(py, px, RUNE_MANA) && 
	(mana_reserve <= mt_ptr->smana)	&& (mt_ptr->index != 60)) 
    {
	p_ptr->csp += mana_reserve;
	mana_reserve = 0;
    }

    /* Rune of mana can take less mana than specified */
    if (mt_ptr->index == 60) {
	/* Standard mana amount */
	int mana = 40;

	/* Already full? */
	if (mana_reserve >= MAX_MANA_RESERVE) {
	    /* Use no mana */
	    mana = 0;
	}

	/* Don't put in more than we have */
	else if (p_ptr->csp < mana)
	    mana = p_ptr->csp;

	/* Don't put in more than it will hold */
	if (mana_reserve + mana > MAX_MANA_RESERVE)
	    mana = MAX_MANA_RESERVE - mana_reserve;

	/* Deduct */
	p_ptr->csp -= mana;
    }

    /* Use mana from a rune if possible */
    else if (cave_trap_specific(py, px, RUNE_MANA)
	     && (mana_reserve > mt_ptr->smana)) {
	mana_reserve -= mt_ptr->smana;
    }

    /* Sufficient mana */
    else if (mt_ptr->smana <= p_ptr->csp) {
	/* Use some mana */
	p_ptr->csp -= mt_ptr->smana;

	/* Specialty ability Harmony */
	if ((failed == FALSE) & (player_has(PF_HARMONY))) {
	    int frac, boost;

	    /* Percentage of max hp to be regained */
	    frac = 3 + (mt_ptr->smana / 3);

	    /* Cap at 10 % */
	    if (frac > 10)
		frac = 10;

	    /* Calculate fractional bonus */
	    boost = (frac * p_ptr->mhp) / 100;

	    /* Apply bonus */
	    (void) hp_player(boost);
	}
    }

    /* Over-exert the player */
    else {
	int oops = mt_ptr->smana - p_ptr->csp;

	/* No mana left */
	p_ptr->csp = 0;
	p_ptr->csp_frac = 0;

	/* Message */
	if (mp_ptr->spell_realm == REALM_NECROMANTIC)
	    msg("You collapse after the ritual!");
	else
	    msg("You faint from the effort!");

	/* Hack -- Bypass free action */
	(void) inc_timed(TMD_PARALYZED, randint1(5 * oops + 1), TRUE);

	/* Damage CON (possibly permanently) */
	if (randint0(100) < 50) {
	    bool perm = (randint0(100) < 25);

	    /* Message */
	    msg("You have damaged your health!");

	    /* Reduce constitution */
	    (void) dec_stat(A_CON, 15 + randint1(10), perm);
	}
    }


    /* Redraw mana */
    p_ptr->redraw |= (PR_MANA);

    return TRUE;
}
Exemple #22
0
extern void get_chamber_monsters(int y1, int x1, int y2, int x2)
{
    bool dummy;
    int i, y, x;
    s16b monsters_left, depth;
    char symbol;

    /* Description of monsters in room */
    char *name;

    /* Get a legal depth. */
    depth = p_ptr->danger + randint0(11) - 5;
    if (depth > 60)
	depth = 60;
    if (depth < 5)
	depth = 5;

    /* Choose a monster type, using that depth. */
    symbol = mon_symbol_at_depth[depth / 5 - 1][randint0(13)];

    /* Allow (slightly) tougher monsters. */
    depth = p_ptr->danger + (p_ptr->danger < 60 ? p_ptr->danger / 12 : 5);

    /* Set monster generation restrictions.  Describe the monsters. */
    name = mon_restrict(symbol, (byte) depth, &dummy, TRUE);

    /* A default description probably means trouble, so stop. */
    if (streq(name, "misc") || !name[0])
	return;

    /* Build the monster probability table. */
    if (!get_mon_num(depth))
	return;

    /* No normal monsters. */
    generate_mark(y1, x1, y2, x2, CAVE_TEMP);


    /* Usually, we want 35 monsters. */
    monsters_left = 35;

    /* Fewer monsters near the surface. */
    if (p_ptr->danger < 45)
	monsters_left = 5 + 2 * p_ptr->danger / 3;

    /* More monsters of kinds that tend to be weak. */
    if (strstr("abciBCFKRS", d_char_req))
	monsters_left += 15;

    /* Place the monsters. */
    for (i = 0; i < 300; i++) {
	/* Check for early completion. */
	if (!monsters_left)
	    break;

	/* Pick a random in-room square. */
	y = y1 + randint0(1 + ABS(y2 - y1));
	x = x1 + randint0(1 + ABS(x2 - x1));

	/* Require a floor square with no monster in it already. */
	if (!cave_naked_bold(y, x))
	    continue;

	/* Place a single monster.  Sleeping 2/3rds of the time. */
	place_monster_aux(y, x, get_mon_num_quick(depth), (randint0(3) != 0),
			  FALSE);

	/* One less monster to place. */
	monsters_left--;
    }

    /* Remove our restrictions. */
    (void) mon_restrict('\0', (byte) depth, &dummy, FALSE);

    /* Describe */
    if (OPT(cheat_room)) {
	/* Room type */
	msg("Room of chambers (%s)", name);
    }
}
/**
 * Verify the current panel (relative to the player location).
 *
 * By default, when the player gets "too close" to the edge of the current
 * panel, the map scrolls one panel in that direction so that the player
 * is no longer so close to the edge.
 *
 * The "OPT(center_player)" option allows the current panel to always be
 * centered around the player, which is very expensive, and also has some
 * interesting gameplay ramifications.
 */
void verify_panel(void)
{
	verify_panel_int(OPT(center_player));
}
Exemple #24
0
/**
 * Update the current "run" path
 *
 * Return TRUE if the running should be stopped
 */
static bool run_test(void)
{
    int py = p_ptr->py;
    int px = p_ptr->px;

    int prev_dir;
    int new_dir;
    int check_dir = 0;
    int left_dir;
    int right_dir;

    int row, col;
    int i, max, inv;
    int option, option2;


    /* No options yet */
    option = 0;
    option2 = 0;

    /* Where we came from */
    prev_dir = p_ptr->run_old_dir;

    /* Range of newly adjacent grids */
    max = (prev_dir & 0x01) + 1;

    /* Simplistic running for outdoors -NRM- */
    if ((stage_map[p_ptr->stage][STAGE_TYPE] != CAVE)
	&& (stage_map[p_ptr->stage][STAGE_TYPE] != TOWN)) {
	/* Look at every newly adjacent square. */
	for (i = -max; i <= max; i++) {
	    s16b this_o_idx, next_o_idx = 0;


	    /* New direction */
	    new_dir = cycle[chome[prev_dir] + i];

	    /* New location */
	    row = py + ddy[new_dir];
	    col = px + ddx[new_dir];


	    /* Visible monsters abort running */
	    if (cave_m_idx[row][col] > 0) {
		monster_type *m_ptr = &m_list[cave_m_idx[row][col]];

		/* Visible monster */
		if (m_ptr->ml)
		    return (TRUE);
	    }

	    /* Visible objects abort running */
	    for (this_o_idx = cave_o_idx[row][col]; this_o_idx;
		 this_o_idx = next_o_idx) {
		object_type *o_ptr;

		/* Acquire object */
		o_ptr = &o_list[this_o_idx];

		/* Acquire next object */
		next_o_idx = o_ptr->next_o_idx;

		/* Visible object */
		if (o_ptr->marked && !squelch_hide_item(o_ptr))
		    return (TRUE);
	    }
	}

	/* Assume main direction */
	new_dir = p_ptr->run_old_dir;
	row = py + ddy[new_dir];
	col = px + ddx[new_dir];


	/* Step if there's a path in the right direction */
	if ((cave_feat[row][col] == FEAT_FLOOR)
	    || (cave_feat[row][col] == FEAT_INVIS)) {
	    p_ptr->run_cur_dir = new_dir;
	    return (FALSE);
	}

	/* Check to the left */
	left_dir = cycle[chome[prev_dir] - 1];
	row = py + ddy[left_dir];
	col = px + ddx[left_dir];
	if ((cave_feat[row][col] == FEAT_FLOOR)
	    || (cave_feat[row][col] == FEAT_INVIS))
	    option = left_dir;

	/* Check to the right */
	right_dir = cycle[chome[prev_dir] + 1];
	row = py + ddy[right_dir];
	col = px + ddx[right_dir];
	if ((cave_feat[row][col] == FEAT_FLOOR)
	    || (cave_feat[row][col] == FEAT_INVIS))
	    option2 = right_dir;

	/* Stop if it's a fork */
	if (option && option2)
	    return (TRUE);

	/* Otherwise step in the secondary direction */
	if (option) {
	    p_ptr->run_cur_dir = left_dir;
	    return (FALSE);
	} else if (option2) {
	    p_ptr->run_cur_dir = right_dir;
	    return (FALSE);
	}

	/* No paths, so try grass */
	row = py + ddy[new_dir];
	col = px + ddx[new_dir];


	/* Step if there's grass in the right direction */
	if ((cave_feat[row][col] == FEAT_GRASS)
	    || (cave_feat[row][col] == FEAT_GRASS_INVIS)) {
	    p_ptr->run_cur_dir = new_dir;
	    return (FALSE);
	}

	/* Check to the left */
	row = py + ddy[left_dir];
	col = px + ddx[left_dir];
	if ((cave_feat[row][col] == FEAT_GRASS)
	    || (cave_feat[row][col] == FEAT_GRASS_INVIS))
	    option = left_dir;

	/* Check to the right */
	right_dir = cycle[chome[prev_dir] + 1];
	row = py + ddy[right_dir];
	col = px + ddx[right_dir];
	if ((cave_feat[row][col] == FEAT_GRASS)
	    || (cave_feat[row][col] == FEAT_GRASS_INVIS))
	    option2 = right_dir;

	/* Stop if it's a fork */
	if (option && option2)
	    return (TRUE);

	/* Otherwise step in the secondary direction */
	if (option) {
	    p_ptr->run_cur_dir = left_dir;
	    return (FALSE);
	} else if (option2) {
	    p_ptr->run_cur_dir = right_dir;
	    return (FALSE);
	}

    }

    /* Look at every newly adjacent square. */
    for (i = -max; i <= max; i++) {
	s16b this_o_idx, next_o_idx = 0;


	/* New direction */
	new_dir = cycle[chome[prev_dir] + i];

	/* New location */
	row = py + ddy[new_dir];
	col = px + ddx[new_dir];


	/* Visible monsters abort running */
	if (cave_m_idx[row][col] > 0) {
	    monster_type *m_ptr = &m_list[cave_m_idx[row][col]];

	    /* Visible monster */
	    if (m_ptr->ml)
		return (TRUE);
	}

	/* Visible objects abort running */
	for (this_o_idx = cave_o_idx[row][col]; this_o_idx;
	     this_o_idx = next_o_idx) {
	    object_type *o_ptr;

	    /* Acquire object */
	    o_ptr = &o_list[this_o_idx];

	    /* Acquire next object */
	    next_o_idx = o_ptr->next_o_idx;

	    /* Visible object */
	    if (o_ptr->marked)
		return (TRUE);
	}


	/* Assume unknown */
	inv = TRUE;

	/* Check memorized grids */
	if (cave_info[row][col] & (CAVE_MARK)) {
	    bool notice = TRUE;

	    /* Examine the terrain */
	    switch (cave_feat[row][col]) {
		/* Floors */
	    case FEAT_FLOOR:

		/* Invis traps */
	    case FEAT_INVIS:
	    case FEAT_GRASS_INVIS:

		/* Secret doors */
	    case FEAT_SECRET:

		/* Normal veins */
	    case FEAT_MAGMA:
	    case FEAT_QUARTZ:

		/* Hidden treasure */
	    case FEAT_MAGMA_H:
	    case FEAT_QUARTZ_H:

		/* Special passable terrain. */
	    case FEAT_LAVA:
	    case FEAT_WATER:
	    case FEAT_TREE:
	    case FEAT_TREE2:
	    case FEAT_GRASS:
		{
		    /* Ignore */
		    notice = FALSE;

		    /* Done */
		    break;
		}

		/* Walls */
	    case FEAT_WALL_EXTRA:
	    case FEAT_WALL_INNER:
	    case FEAT_WALL_OUTER:
	    case FEAT_WALL_SOLID:
	    case FEAT_PERM_EXTRA:
	    case FEAT_PERM_INNER:
	    case FEAT_PERM_OUTER:
	    case FEAT_PERM_SOLID:
		{
		    /* Ignore */
		    notice = FALSE;

		    /* Done */
		    break;
		}

		/* Open doors */
	    case FEAT_OPEN:
	    case FEAT_BROKEN:
		{
		    /* Option -- ignore */
		    if (OPT(run_ignore_doors))
			notice = FALSE;

		    /* Done */
		    break;
		}

		/* Stairs */
	    case FEAT_LESS:
	    case FEAT_MORE:
		{
		    /* Option -- ignore */
		    if (OPT(run_ignore_stairs))
			notice = FALSE;

		    /* Done */
		    break;
		}
	    }

	    /* Interesting feature */
	    if (notice)
		return (TRUE);

	    /* The grid is "visible" */
	    inv = FALSE;
	}

	/* Analyze unknown grids and floors */
	if (inv || cave_floor_bold(row, col)) {
	    /* Looking for open area */
	    if (p_ptr->run_open_area) {
		/* Nothing */
	    }

	    /* The first new direction. */
	    else if (!option) {
		option = new_dir;
	    }

	    /* Three new directions. Stop running. */
	    else if (option2) {
		return (TRUE);
	    }

	    /* Two non-adjacent new directions.  Stop running. */
	    else if (option != cycle[chome[prev_dir] + i - 1]) {
		return (TRUE);
	    }

	    /* Two new (adjacent) directions (case 1) */
	    else if (new_dir & 0x01) {
		check_dir = cycle[chome[prev_dir] + i - 2];
		option2 = new_dir;
	    }

	    /* Two new (adjacent) directions (case 2) */
	    else {
		check_dir = cycle[chome[prev_dir] + i + 1];
		option2 = option;
		option = new_dir;
	    }
	}

	/* Obstacle, while looking for open area */
	else {
	    if (p_ptr->run_open_area) {
		if (i < 0) {
		    /* Break to the right */
		    p_ptr->run_break_right = TRUE;
		}

		else if (i > 0) {
		    /* Break to the left */
		    p_ptr->run_break_left = TRUE;
		}
	    }
	}
    }


    /* Looking for open area */
    if (p_ptr->run_open_area) {
	/* Hack -- look again */
	for (i = -max; i < 0; i++) {
	    new_dir = cycle[chome[prev_dir] + i];

	    row = py + ddy[new_dir];
	    col = px + ddx[new_dir];

	    /* Unknown grid or non-wall */
	    /* Was: cave_floor_bold(row, col) */
	    if (!(cave_info[row][col] & (CAVE_MARK))
		|| (cave_feat[row][col] < FEAT_SECRET)
		|| (cave_feat[row][col] > FEAT_SHOP_HEAD)) {
		/* Looking to break right */
		if (p_ptr->run_break_right) {
		    return (TRUE);
		}
	    }

	    /* Obstacle */
	    else {
		/* Looking to break left */
		if (p_ptr->run_break_left) {
		    return (TRUE);
		}
	    }
	}

	/* Hack -- look again */
	for (i = max; i > 0; i--) {
	    new_dir = cycle[chome[prev_dir] + i];

	    row = py + ddy[new_dir];
	    col = px + ddx[new_dir];

	    /* Unknown grid or non-wall */
	    /* Was: cave_floor_bold(row, col) */
	    if (!(cave_info[row][col] & (CAVE_MARK))
		|| (cave_feat[row][col] < FEAT_SECRET)
		|| (cave_feat[row][col] > FEAT_SHOP_HEAD)) {
		/* Looking to break left */
		if (p_ptr->run_break_left) {
		    return (TRUE);
		}
	    }

	    /* Obstacle */
	    else {
		/* Looking to break right */
		if (p_ptr->run_break_right) {
		    return (TRUE);
		}
	    }
	}
    }


    /* Not looking for open area */
    else {
	/* No options */
	if (!option) {
	    return (TRUE);
	}

	/* One option */
	else if (!option2) {
	    /* Primary option */
	    p_ptr->run_cur_dir = option;

	    /* No other options */
	    p_ptr->run_old_dir = option;
	}

	/* Two options, examining corners */
	else if (OPT(run_use_corners) && !OPT(run_cut_corners)) {
	    /* Primary option */
	    p_ptr->run_cur_dir = option;

	    /* Hack -- allow curving */
	    p_ptr->run_old_dir = option2;
	}

	/* Two options, pick one */
	else {
	    /* Get next location */
	    row = py + ddy[option];
	    col = px + ddx[option];

	    /* Don't see that it is closed off. */
	    /* This could be a potential corner or an intersection. */
	    if (!see_wall(option, row, col) || !see_wall(check_dir, row, col)) {
		/* Can not see anything ahead and in the direction we */
		/* are turning, assume that it is a potential corner. */
		if (OPT(run_use_corners) && see_nothing(option, row, col)
		    && see_nothing(option2, row, col)) {
		    p_ptr->run_cur_dir = option;
		    p_ptr->run_old_dir = option2;
		}

		/* STOP: we are next to an intersection or a room */
		else {
		    return (TRUE);
		}
	    }

	    /* This corner is seen to be enclosed; we cut the corner. */
	    else if (OPT(run_cut_corners)) {
		p_ptr->run_cur_dir = option2;
		p_ptr->run_old_dir = option2;
	    }

	    /* This corner is seen to be enclosed, and we */
	    /* deliberately go the long way. */
	    else {
		p_ptr->run_cur_dir = option;
		p_ptr->run_old_dir = option2;
	    }
	}
    }


    /* About to hit a known wall, stop */
    if (see_wall(p_ptr->run_cur_dir, py, px)) {
	return (TRUE);
    }


    /* Failure */
    return (FALSE);
}
Exemple #25
0
/*
 * Read the random artifacts
 */
static int rd_randarts(void)
{
	size_t i;
	byte tmp8u;
	s16b tmp16s;
	u16b tmp16u;
	u16b artifact_count;
	s32b tmp32s;
	u32b tmp32u;

	if (!OPT(adult_randarts))
		return 0;

	if (older_than(3, 0, 14))
	{
		/*
		 * XXX XXX XXX
		 * Importing old savefiles with random artifacts is dangerous
		 * since the randart-generators differ and produce different
		 * artifacts from the same random seed.
		 *
		 * Switching off the check for incompatible randart versions
		 * allows to import such a savefile - do it at your own risk.
		 */

		/* Check for incompatible randart version */
		if (randart_version != RANDART_VERSION)
		{
			note(format("Incompatible random artifacts version!"));
			return (-1);
		}

		/* Initialize randarts */
		do_randart(seed_randart, TRUE);
	}
	else
	{
		/* Read the number of artifacts */
		rd_u16b(&artifact_count);

		/* Alive or cheating death */
		if (!p_ptr->is_dead || arg_wizard)
		{
			/* Incompatible save files */
			if (artifact_count > z_info->a_max)
			{
				note(format("Too many (%u) random artifacts!", artifact_count));
				return (-1);
			}

			/* Mark the old artifacts as "empty" */
			for (i = 0; i < z_info->a_max; i++)
			{
				artifact_type *a_ptr = &a_info[i];
				a_ptr->name = 0;
				a_ptr->tval = 0;
				a_ptr->sval = 0;
			}

			/* Read the artifacts */
			for (i = 0; i < artifact_count; i++)
			{
				artifact_type *a_ptr = &a_info[i];
				u16b time_base, time_dice, time_sides;

				rd_byte(&a_ptr->tval);
				rd_byte(&a_ptr->sval);
				rd_s16b(&a_ptr->pval);

				rd_s16b(&a_ptr->to_h);
				rd_s16b(&a_ptr->to_d);
				rd_s16b(&a_ptr->to_a);
				rd_s16b(&a_ptr->ac);

				rd_byte(&a_ptr->dd);
				rd_byte(&a_ptr->ds);

				rd_s16b(&a_ptr->weight);

				rd_s32b(&a_ptr->cost);

				/* Hack - XXX - MarbleDice - Maximum saveable flags = 96 */
				for (i = 0; i < 12 && i < OF_SIZE; i++)
					rd_byte(&a_ptr->flags[i]);
				if (i < 12) strip_bytes(OF_SIZE - i);

				rd_byte(&a_ptr->level);
				rd_byte(&a_ptr->rarity);
				rd_byte(&a_ptr->alloc_prob);
				rd_byte(&a_ptr->alloc_min);
				rd_byte(&a_ptr->alloc_max);

				rd_u16b(&a_ptr->effect);
				rd_u16b(&time_base);
				rd_u16b(&time_dice);
				rd_u16b(&time_sides);
				a_ptr->time.base = time_base;
				a_ptr->time.dice = time_dice;
				a_ptr->time.sides = time_sides;
			}

		/* Initialize only the randart names */
		do_randart(seed_randart, FALSE);
		}
		else
		{
			/* Read the artifacts */
			for (i = 0; i < artifact_count; i++)
			{
				rd_byte(&tmp8u); /* a_ptr->tval */
				rd_byte(&tmp8u); /* a_ptr->sval */
				rd_s16b(&tmp16s); /* a_ptr->pval */

				rd_s16b(&tmp16s); /* a_ptr->to_h */
				rd_s16b(&tmp16s); /* a_ptr->to_d */
				rd_s16b(&tmp16s); /* a_ptr->to_a */
				rd_s16b(&tmp16s); /* a_ptr->ac */

				rd_byte(&tmp8u); /* a_ptr->dd */
				rd_byte(&tmp8u); /* a_ptr->ds */

				rd_s16b(&tmp16s); /* a_ptr->weight */

				rd_s32b(&tmp32s); /* a_ptr->cost */

				rd_u32b(&tmp32u); /* a_ptr->flags1 */
				rd_u32b(&tmp32u); /* a_ptr->flags2 */
				rd_u32b(&tmp32u); /* a_ptr->flags3 */

				rd_byte(&tmp8u); /* a_ptr->level */
				rd_byte(&tmp8u); /* a_ptr->rarity */
				rd_byte(&tmp8u); /* a_ptr->alloc_prob */
				rd_byte(&tmp8u); /* a_ptr->alloc_min */
				rd_byte(&tmp8u); /* a_ptr->alloc_max */

				rd_u16b(&tmp16u); /* a_ptr->effect */
				rd_u16b(&tmp16u); /* a_ptr->time_base */
				rd_u16b(&tmp16u); /* a_ptr->time_dice */
				rd_u16b(&tmp16u); /* a_ptr->time_sides */
			}
		}
	}

	return (0);
}
/**
 * This function takes a grid location (x, y) and extracts information the
 * player is allowed to know about it, filling in the grid_data structure
 * passed in 'g'.
 *
 * The information filled in is as follows:
 *  - g->f_idx is filled in with the terrain's feature type, or FEAT_NONE
 *    if the player doesn't know anything about the grid.  The function
 *    makes use of the "mimic" field in terrain in order to allow one
 *    feature to look like another (hiding secret doors, invisible traps,
 *    etc).  This will return the terrain type the player "Knows" about,
 *    not necessarily the real terrain.
 *  - g->m_idx is set to the monster index, or 0 if there is none (or the
 *    player doesn't know it).
 *  - g->first_kind is set to the object_kind of the first object in a grid
 *    that the player knows about, or NULL for no objects.
 *  - g->muliple_objects is TRUE if there is more than one object in the
 *    grid that the player knows and cares about (to facilitate any special
 *    floor stack symbol that might be used).
 *  - g->in_view is TRUE if the player can currently see the grid - this can
 *    be used to indicate field-of-view, such as through the OPT(view_bright_light)
 *    option.
 *  - g->lighting is set to indicate the lighting level for the grid:
 *    LIGHTING_DARK for unlit grids, LIGHTING_LIT for inherently light
 *    grids (lit rooms, etc), LIGHTING_TORCH for grids lit by the player's
 *    light source, and LIGHTING_LOS for grids in the player's line of sight.
 *    Note that lighting is always LIGHTING_LIT for known "interesting" grids
 *    like walls.
 *  - g->is_player is TRUE if the player is on the given grid.
 *  - g->hallucinate is TRUE if the player is hallucinating something "strange"
 *    for this grid - this should pick a random monster to show if the m_idx
 *    is non-zero, and a random object if first_kind is non-zero.
 * 
 * NOTES:
 * This is called pretty frequently, whenever a grid on the map display
 * needs updating, so don't overcomplicate it.
 *
 * Terrain is remembered separately from objects and monsters, so can be
 * shown even when the player can't "see" it.  This leads to things like
 * doors out of the player's view still change from closed to open and so on.
 *
 * TODO:
 * Hallucination is currently disabled (it was a display-level hack before,
 * and we need it to be a knowledge-level hack).  The idea is that objects
 * may turn into different objects, monsters into different monsters, and
 * terrain may be objects, monsters, or stay the same.
 */
void map_info(unsigned y, unsigned x, grid_data *g)
{
	object_type *obj;

	assert(x < (unsigned) cave->width);
	assert(y < (unsigned) cave->height);

	/* Default "clear" values, others will be set later where appropriate. */
	g->first_kind = NULL;
	g->trap = NULL;
	g->multiple_objects = FALSE;
	g->lighting = LIGHTING_DARK;
	g->unseen_object = FALSE;
	g->unseen_money = FALSE;

	/* Use real feature (remove later) */
	g->f_idx = cave->squares[y][x].feat;
	if (f_info[g->f_idx].mimic)
		g->f_idx = f_info[g->f_idx].mimic;

	g->in_view = (square_isseen(cave, y, x)) ? TRUE : FALSE;
	g->is_player = (cave->squares[y][x].mon < 0) ? TRUE : FALSE;
	g->m_idx = (g->is_player) ? 0 : cave->squares[y][x].mon;
	g->hallucinate = player->timed[TMD_IMAGE] ? TRUE : FALSE;
	g->trapborder = (square_isdedge(cave, y, x)) ? TRUE : FALSE;

	if (g->in_view) {
		g->lighting = LIGHTING_LOS;

		if (!square_isglow(cave, y, x) && OPT(view_yellow_light))
			g->lighting = LIGHTING_TORCH;

		/* Remember seen feature */
		cave_k->squares[y][x].feat = cave->squares[y][x].feat;
	} else if (!square_ismark(cave, y, x)) {
		g->f_idx = FEAT_NONE;
		//cave_k->squares[y][x].feat = FEAT_NONE;
	} else if (square_isglow(cave, y, x)) {
		g->lighting = LIGHTING_LIT;
	}

	/* Use known feature */
/*	g->f_idx = cave_k->squares[y][x].feat;
	if (f_info[g->f_idx].mimic)
		g->f_idx = f_info[g->f_idx].mimic;*/

    /* There is a trap in this square */
    if (square_istrap(cave, y, x) && square_ismark(cave, y, x)) {
		struct trap *trap = cave->squares[y][x].trap;

		/* Scan the square trap list */
		while (trap) {
			if (trf_has(trap->flags, TRF_TRAP) ||
				trf_has(trap->flags, TRF_RUNE)) {
				/* Accept the trap */
				g->trap = trap;
				break;
			}
			trap = trap->next;
		}
    }

	/* Objects */
	for (obj = square_object(cave, y, x); obj; obj = obj->next) {
		if (obj->marked == MARK_AWARE) {

			/* Distinguish between unseen money and objects */
			if (tval_is_money(obj)) {
				g->unseen_money = TRUE;
			} else {
				g->unseen_object = TRUE;
			}

		} else if (obj->marked == MARK_SEEN && !ignore_item_ok(obj)) {
			if (!g->first_kind) {
				g->first_kind = obj->kind;
			} else {
				g->multiple_objects = TRUE;
				break;
			}
		}
	}

	/* Monsters */
	if (g->m_idx > 0) {
		/* If the monster isn't "visible", make sure we don't list it.*/
		monster_type *m_ptr = cave_monster(cave, g->m_idx);
		if (!mflag_has(m_ptr->mflag, MFLAG_VISIBLE)) g->m_idx = 0;
	}

	/* Rare random hallucination on non-outer walls */
	if (g->hallucinate && g->m_idx == 0 && g->first_kind == 0) {
		if (one_in_(128) && (int) g->f_idx != FEAT_PERM)
			g->m_idx = 1;
		else if (one_in_(128) && (int) g->f_idx != FEAT_PERM)
			/* if hallucinating, we just need first_kind to not be NULL */
			g->first_kind = k_info;
		else
			g->hallucinate = FALSE;
	}

	assert((int) g->f_idx <= FEAT_PASS_RUBBLE);
	if (!g->hallucinate)
		assert((int)g->m_idx < cave->mon_max);
	/* All other g fields are 'flags', mostly booleans. */
}
Exemple #27
0
int context_menu_player(int mx, int my)
{
	menu_type *m;
	rect_region r;
	int selected;
	char *labels;

	cave_type *c_ptr = area(p_ptr->px,p_ptr->py);
	pcave_type *pc_ptr = parea(p_ptr->px,p_ptr->py);
	feature_type *feat;

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

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

	feat  = &(f_info[c_ptr->feat]);

	menu_dynamic_add_label(m, "Use Item", 'u', 1, labels);
	/* if player can cast, add casting option */
	if (player_is_caster()) {
		if (player_can_cast()) {
			menu_dynamic_add_label(m, "Cast", 'm', 2, labels);
		} else {
			menu_dynamic_add_label(m, "$Cast", 'm', 2, labels);
		}
	}
	/* if player can use racial powers or mutations, add option */
	if (player_has_power()) {
		if (player_can_use_power()) {
			menu_dynamic_add_label(m, "Use Power", 'U', 16, labels);
		} else {
			menu_dynamic_add_label(m, "$Use Power", 'U', 16, labels);
		}
	}
	/* if player is on stairs add option to use them */
	if (feat->flags & FF_EXIT_UP) {
		menu_dynamic_add_label(m, "Go Up", '<', 11, labels);
	}
	if (feat->flags & FF_EXIT_DOWN) {
		menu_dynamic_add_label(m, "Go Down", '>', 12, labels);
	}
	menu_dynamic_add_label(m, "Search", 's', 3, labels);
	menu_dynamic_add_label(m, "Look", 'l', 6, labels);
	menu_dynamic_add_label(m, "Rest", 'R', 4, labels);
	menu_dynamic_add_label(m, "Inventory", 'i', 5, labels);
	/* if object under player add pickup option */
	if (c_ptr->o_idx) {
		object_type *o_ptr = &(o_list[c_ptr->o_idx]);
		//if (!squelch_item_ok(o_ptr)) {
  			menu_dynamic_add_label(m, "Floor", 'i', 13, labels);
			if (inven_carry_okay(o_ptr)) {
  				menu_dynamic_add_label(m, "Pickup", 'g', 14, labels);
			} else {
  				menu_dynamic_add_label(m, "$Pickup", 'g', 14, labels);
			}
		//}
	}
	menu_dynamic_add_label(m, "Character", 'C', 7, labels);
	/* XXX Don't show the keymap line until the keymap list is implemented, to
	 * avoid confusion as to what should be there */
	/*menu_dynamic_add(m, "Keymaps", 10);*/
	if (!OPT(center_player)) {
		menu_dynamic_add_label(m, "^Center Map", 'L', 15, labels);
	}
	menu_dynamic_add_label(m, "Other", ' ', 9, labels);

	/* work out display region */
	r.width = 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();
	button_backup_all(TRUE);

	menu_layout(m, &r);
	rect_region_erase_bordered(&r);

	prtf(0, 0, "($UEnter to select$Y\n$V, $UESC$Y%c$V) Command:", ESCAPE);
	selected = menu_dynamic_select(m);

	menu_dynamic_free(m);
	string_free(labels);

	button_restore();
	screen_load();

	switch(selected) {
	case 1:
		{
			/* use an item */
			p_ptr->cmd.cmd = 'u';
			repeat_check();
			do_cmd_use();
		} break;
	case 2:
		{
			/* Cast a spell */
			p_ptr->cmd.cmd = 'm';
			repeat_check();
			do_cmd_cast_wrapper();
		} break;
	case 3:
		{
			/* search */
			p_ptr->cmd.cmd = 's';
			repeat_check();
			do_cmd_search();
		} break;
	case 4:
		{
			/* rest */
			p_ptr->cmd.cmd = 'R';
			repeat_check();
			do_cmd_rest();
		} break;
	case 5:
		{
			/* show inventory screen */
			Term_keypress('i');//,0);
		} break;
	case 6:
		{
			/* look mode */
			if (target_set(TARGET_LOOK)) {
			//if (target_set_interactive(TARGET_LOOK, p_ptr->px, p_ptr->py)) {
				msgf("Target Selected.");
			}
		} break;
	case 7:
		{
			/* show character screen */
			do_cmd_character();
		} break;
	case 9:
		{
			/* show another layer of menu options screen */
			int res;
			while ((res = context_menu_player_2(mx,my)) == 3);
			if (res == 2) return 3;
		} break;
	case 10:
		{
			/* show the commands */
			int res;
			while ((res = context_menu_command(mx,my)) == 3);
			if (res == 2) return 3;
		} break;
	case 11:
		{
			/* go up stairs */
			p_ptr->cmd.cmd = '<';
			repeat_check();
			do_cmd_go_up();
		} break;
	case 12:
		{
			/* go down stairs */
			p_ptr->cmd.cmd = '>';
			repeat_check();
			do_cmd_go_down();
		} break;
	case 13:
		{
			if (c_ptr->o_idx) {
				object_type *o_ptr = &(o_list[c_ptr->o_idx]);
				/* there is an item on the floor, show the inventory screen starting
				 * from the floor */
				if (o_ptr->next_o_idx) {
					do_cmd_inven_floor();
				} else {
					/* if  we only have one item, show the context menu directly */
					if (o_ptr->k_idx) {
						/* Track the object kind */
						object_kind_track(o_ptr->k_idx);

						while (context_menu_object(o_ptr) == 2);
					}
				}
			}
		} break;
	case 14:
		{
			/* pick the item up */
			//cmd_insert(CMD_PICKUP);
			//cmd_set_arg_item(cmd_get_top(), 0, -1);
			carry(TRUE);
		} break;
	case 15:
		{
			/* center the map on the player */
			/*panel_center(p_ptr->px, p_ptr->py);*/
			do_cmd_center_map();
		} break;
	case 16:
		{
			/* use character powers */
			p_ptr->cmd.cmd = 'U';
			repeat_check();
			do_cmd_racial_power();
		} break;

	}

	return 1;
}
Exemple #28
0
/**
 * Process a monster
 *
 * In several cases, we directly update the monster lore
 *
 * Note that a monster is only allowed to "reproduce" if there
 * are a limited number of "reproducing" monsters on the current
 * level.  This should prevent the level from being "swamped" by
 * reproducing monsters.  It also allows a large mass of mice to
 * prevent a louse from multiplying, but this is a small price to
 * pay for a simple multiplication method.
 *
 * XXX Monster fear is slightly odd, in particular, monsters will
 * fixate on opening a door even if they cannot open it.  Actually,
 * the same thing happens to normal monsters when they hit a door
 *
 * In addition, monsters which *cannot* open or bash down a door
 * will still stand there trying to open it...  XXX XXX XXX
 *
 * Technically, need to check for monster in the way combined
 * with that monster being in a wall (or door?) XXX
 */
static void process_monster(struct chunk *c, struct monster *mon)
{
	struct monster_lore *lore = get_lore(mon->race);

	bool did_something = false;

	int i;
	int dir = 0;
	bool stagger = false;
	char m_name[80];

	/* Get the monster name */
	monster_desc(m_name, sizeof(m_name), mon, MDESC_CAPITAL | MDESC_IND_HID);

	/* Try to multiply - this can use up a turn */
	if (process_monster_multiply(c, mon))
		return;

	/* Attempt to cast a spell */
	if (make_attack_spell(mon)) return;

	/* Work out what kind of movement to use - AI or staggered movement */
	if (!process_monster_should_stagger(mon)) {
		if (!get_moves(c, mon, &dir)) return;
	} else {
		stagger = true;
	}

	/* Process moves */
	for (i = 0; i < 5 && !did_something; i++) {
		int oy = mon->fy;
		int ox = mon->fx;

		/* Get the direction (or stagger) */
		int d = (stagger ? ddd[randint0(8)] : side_dirs[dir][i]);

		/* Get the destination */
		int ny = oy + ddy[d];
		int nx = ox + ddx[d];

		/* Check if we can move */
		if (!process_monster_can_move(c, mon, m_name, nx, ny, &did_something))
			continue;

		/* Try to break the glyph if there is one.  This can happen multiple
		 * times per turn because failure does not break the loop */
		if (square_iswarded(c, ny, nx) &&
			!process_monster_glyph(c, mon, nx, ny))
			continue;

		/* The player is in the way. */
		if (square_isplayer(c, ny, nx)) {
			/* Learn about if the monster attacks */
			if (mflag_has(mon->mflag, MFLAG_VISIBLE))
				rf_on(lore->flags, RF_NEVER_BLOW);

			/* Some monsters never attack */
			if (rf_has(mon->race->flags, RF_NEVER_BLOW))
				continue;

			/* Otherwise, attack the player */
			make_attack_normal(mon, player);

			did_something = true;
			break;
		} else {
			/* Some monsters never move */
			if (rf_has(mon->race->flags, RF_NEVER_MOVE)) {
				/* Learn about lack of movement */
				if (mflag_has(mon->mflag, MFLAG_VISIBLE))
					rf_on(lore->flags, RF_NEVER_MOVE);

				return;
			}
		}

		/* A monster is in the way, try to push past/kill */
		if (square_monster(c, ny, nx)) {
			did_something = process_monster_try_push(c, mon, m_name, nx, ny);
		} else {
			/* Otherwise we can just move */
			monster_swap(oy, ox, ny, nx);
			did_something = true;
		}

		/* Scan all objects in the grid, if we reached it */
		if (mon == square_monster(c, ny, nx)) {
			monster_desc(m_name, sizeof(m_name), mon,
						 MDESC_CAPITAL | MDESC_IND_HID);
			process_monster_grab_objects(c, mon, m_name, nx, ny);
		}
	}

	if (did_something) {
		/* Learn about no lack of movement */
		if (mflag_has(mon->mflag, MFLAG_VISIBLE))
			rf_on(lore->flags, RF_NEVER_MOVE);

		/* Possible disturb */
		if (mflag_has(mon->mflag, MFLAG_VISIBLE) &&
			mflag_has(mon->mflag, MFLAG_VIEW) && OPT(player, disturb_near))
			disturb(player, 0);		
	}

	/* Hack -- get "bold" if out of options */
	if (!did_something && mon->m_timed[MON_TMD_FEAR])
		mon_clear_timed(mon, MON_TMD_FEAR, MON_TMD_FLG_NOTIFY, false);

	/* If we see an unaware monster do something, become aware of it */
	if (did_something && mflag_has(mon->mflag, MFLAG_UNAWARE))
		become_aware(mon);
}
Exemple #29
0
int kvz_config_parse(kvz_config *cfg, const char *name, const char *value)
{
  static const char * const me_names[]          = { "hexbs", "tz", "full", "full8", "full16", "full32", "full64", NULL };
  static const char * const source_scan_type_names[] = { "progressive", "tff", "bff", NULL };

  static const char * const overscan_names[]    = { "undef", "show", "crop", NULL };
  static const char * const videoformat_names[] = { "component", "pal", "ntsc", "secam", "mac", "undef", NULL };
  static const char * const range_names[]       = { "tv", "pc", NULL };
  static const char * const colorprim_names[]   = { "", "bt709", "undef", "", "bt470m", "bt470bg", "smpte170m",
                                                    "smpte240m", "film", "bt2020", NULL };
  static const char * const transfer_names[]    = { "", "bt709", "undef", "", "bt470m", "bt470bg", "smpte170m",
                                                    "smpte240m", "linear", "log100", "log316", "iec61966-2-4",
                                                    "bt1361e", "iec61966-2-1", "bt2020-10", "bt2020-12", NULL };
  static const char * const colormatrix_names[] = { "GBR", "bt709", "undef", "", "fcc", "bt470bg", "smpte170m",
                                                    "smpte240m", "YCgCo", "bt2020nc", "bt2020c", NULL };
  static const char * const mv_constraint_names[] = { "none", "frame", "tile", "frametile", "frametilemargin", NULL };
  static const char * const hash_names[] = { "none", "checksum", "md5", NULL };

  static const char * const cu_split_termination_names[] = { "zero", "off", NULL };

  static const char * const preset_values[11][28] = {
      { 
        "ultrafast", 
        "pu-depth-intra", "2-3",
        "pu-depth-inter", "1-3",
        "rd", "0",
        "me", "hexbs",
        "ref", "1",
        "deblock", "0",
        "signhide", "0",
        "subme", "0",
        "sao", "0",
        "rdoq", "0",
        "transform-skip", "0", 
        "full-intra-search", "0",
        "mv-rdo", "0",
        NULL 
      },
      { 
        "superfast",
        "pu-depth-intra", "1-3",
        "pu-depth-inter", "1-3",
        "rd", "1",
        "me", "hexbs",
        "ref", "1",
        "deblock", "0",
        "signhide", "0",
        "subme", "0",
        "sao", "0",
        "rdoq", "0",
        "transform-skip", "0",
        "full-intra-search", "0",
        "mv-rdo", "0",
        NULL
      },
      {
        "veryfast",
        "pu-depth-intra", "1-3",
        "pu-depth-inter", "0-3",
        "rd", "1",
        "me", "hexbs",
        "ref", "2",
        "deblock", "1",
        "signhide", "0",
        "subme", "0",
        "sao", "0",
        "rdoq", "0",
        "transform-skip", "0",
        "full-intra-search", "0",
        "mv-rdo", "0",
        NULL
      },
      {
        "faster",
        "pu-depth-intra", "1-3",
        "pu-depth-inter", "0-3",
        "rd", "1",
        "me", "hexbs",
        "ref", "2",
        "deblock", "1",
        "signhide", "1",
        "subme", "0",
        "sao", "0",
        "rdoq", "0",
        "transform-skip", "0",
        "full-intra-search", "0",
        "mv-rdo", "0",
        NULL
      },
      {
        "fast",
        "pu-depth-intra", "1-3",
        "pu-depth-inter", "0-3",
        "rd", "1",
        "me", "hexbs",
        "ref", "2",
        "deblock", "1",
        "signhide", "1",
        "subme", "1",
        "sao", "0",
        "rdoq", "0",
        "transform-skip", "0",
        "full-intra-search", "0",
        "mv-rdo", "0",
        NULL
      },
      {
        "medium",
        "pu-depth-intra", "1-4",
        "pu-depth-inter", "0-3",
        "rd", "1",
        "me", "hexbs",
        "ref", "3",
        "deblock", "1",
        "signhide", "1",
        "subme", "1",
        "sao", "0",
        "rdoq", "0",
        "transform-skip", "0",
        "full-intra-search", "0",
        "mv-rdo", "0",
        NULL
      },
      {
        "slow",
        "pu-depth-intra", "1-4",
        "pu-depth-inter", "0-3",
        "rd", "2",
        "me", "hexbs",
        "ref", "3",
        "deblock", "1",
        "signhide", "1",
        "subme", "1",
        "sao", "1",
        "rdoq", "0",
        "transform-skip", "0",
        "full-intra-search", "0",
        "mv-rdo", "0",
        NULL
      },
      {
        "slower",
        "pu-depth-intra", "1-4",
        "pu-depth-inter", "0-3",
        "rd", "2",
        "me", "tz",
        "ref", "4",
        "deblock", "1",
        "signhide", "1",
        "subme", "1",
        "sao", "1",
        "rdoq", "1",
        "transform-skip", "0",
        "full-intra-search", "0",
        "mv-rdo", "0",
        NULL
      },
      {
        "veryslow",
        "pu-depth-intra", "1-4",
        "pu-depth-inter", "0-3",
        "rd", "2",
        "me", "tz",
        "ref", "4",
        "deblock", "1",
        "signhide", "1",
        "subme", "1",
        "sao", "1",
        "rdoq", "1",
        "transform-skip", "1",
        "full-intra-search", "0",
        "mv-rdo", "1",
        NULL
      },
      {
        "placebo",
        "pu-depth-intra", "0-4",
        "pu-depth-inter", "0-3",
        "rd", "3",
        "me", "tz",
        "ref", "6",
        "deblock", "1",
        "signhide", "1",
        "subme", "1",
        "sao", "1",
        "rdoq", "1",
        "transform-skip", "1",
        "full-intra-search", "1",
        "mv-rdo", "1",
        NULL
      },
      { NULL }
  };

  if (!name)
    return 0;

  if (!value)
    value = "true";

  // Treat "--no-param" as --param 0
  if ((!strncmp(name, "no-", 3))) {
    name += 3;
    value = atobool(value) ? "false" : "true";
  }

#define OPT(STR) (!strcmp(name, STR))
  if OPT("width")
    cfg->width = atoi(value);
  else if OPT("height")
Exemple #30
0
/*
 * Find the "first" inventory object with the given "tag".
 *
 * A "tag" is a char "n" appearing as "@n" anywhere in the
 * inscription of an object.
 *
 * Also, the tag "@xn" will work as well, where "n" is a tag-char,
 * and "x" is the action that tag will work for.
 */
static int get_tag(int *cp, char tag, cmd_code cmd, bool quiver_tags)
{
	int i;
	const char *s;
	int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG;

	/* (f)ire is handled differently from all others, due to the quiver */
	if (quiver_tags)
	{
		i = QUIVER_START + tag - '0';
		if (p_ptr->inventory[i].kind)
		{
			*cp = i;
			return (TRUE);
		}
		return (FALSE);
	}

	/* Check every object */
	for (i = 0; i < ALL_INVEN_TOTAL; ++i)
	{
		object_type *o_ptr = &p_ptr->inventory[i];

		/* Skip non-objects */
		if (!o_ptr->kind) continue;

		/* Skip empty inscriptions */
		if (!o_ptr->note) continue;

		/* Find a '@' */
		s = strchr(quark_str(o_ptr->note), '@');

		/* Process all tags */
		while (s)
		{
			unsigned char cmdkey;

			/* Check the normal tags */
			if (s[1] == tag)
			{
				/* Save the actual inventory ID */
				*cp = i;

				/* Success */
				return (TRUE);
			}

			cmdkey = cmd_lookup_key(cmd, mode);

			/* Hack - Only shift the command key if it actually needs to be shifted. */
			if (cmdkey < 0x20)
				cmdkey = UN_KTRL(cmdkey);

			/* Check the special tags */
			if ((s[1] == cmdkey) && (s[2] == tag))
			{
				/* Save the actual inventory ID */
				*cp = i;

				/* Success */
				return (TRUE);
			}

			/* Find another '@' */
			s = strchr(s + 1, '@');
		}
	}

	/* No such tag */
	return (FALSE);
}