예제 #1
0
/*
 * Know inventory and home items upon death
 */
static void death_knowledge(void)
{
	store_type *st_ptr = &store[STORE_HOME];
	object_type *o_ptr;

	int i;

	for (i = 0; i < ALL_INVEN_TOTAL; i++)
	{
		o_ptr = &p_ptr->inventory[i];
		if (!o_ptr->kind) continue;

		object_flavor_aware(o_ptr);
		object_notice_everything(o_ptr);
	}

	for (i = 0; i < st_ptr->stock_num; i++)
	{
		o_ptr = &st_ptr->stock[i];
		if (!o_ptr->kind) continue;

		object_flavor_aware(o_ptr);
		object_notice_everything(o_ptr);
	}

	history_unmask_unknown();

	/* Hack -- Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);
	handle_stuff(p_ptr);
}
예제 #2
0
/*
 * Checks for additional knowledge implied by what the player already knows.
 *
 * \param o_ptr is the object to check
 *
 * returns whether it calls object_notice_everyting
 */
bool object_check_for_ident(object_type *o_ptr)
{
	bitflag flags[OF_SIZE], known_flags[OF_SIZE];
	
	object_flags(o_ptr, flags);
	object_flags_known(o_ptr, known_flags);

	/* Some flags are irrelevant or never learned or too hard to learn */
	flags_clear(flags, OF_SIZE, OF_OBJ_ONLY_MASK, FLAG_END);
	flags_clear(known_flags, OF_SIZE, OF_OBJ_ONLY_MASK, FLAG_END);

	if (!of_is_equal(flags, known_flags)) return FALSE;

	/* If we know attack bonuses, and defence bonuses, and effect, then
	 * we effectively know everything, so mark as such */
	if ((object_attack_plusses_are_visible(o_ptr) || (object_was_sensed(o_ptr) && o_ptr->to_h == 0 && o_ptr->to_d == 0)) &&
	    (object_defence_plusses_are_visible(o_ptr) || (object_was_sensed(o_ptr) && o_ptr->to_a == 0)) &&
	    (object_effect_is_known(o_ptr) || !object_effect(o_ptr)))
	{
		object_notice_everything(o_ptr);
		return TRUE;
	}

	/* We still know all the flags, so we still know if it's an ego */
	else if (ego_item_p(o_ptr))
	{
		/* require worn status so you don't learn launcher of accuracy or gloves of slaying before wield */
		if (object_was_worn(o_ptr))
			object_notice_ego(o_ptr);
	}

	return FALSE;
}
예제 #3
0
/**
 * Allocate objects upon opening a chest
 *
 * Disperse treasures from the given chest, centered at (x,y).
 *
 * Small chests often contain "gold", while Large chests always contain
 * items.  Wooden chests contain 2 items, Iron chests contain 4 items,
 * and Steel chests contain 6 items.  The "value" of the items in a
 * chest is based on the level on which the chest is generated.
 *
 * Judgment of size and construction of chests is currently made from the name.
 */
static void chest_death(int y, int x, struct object *chest)
{
	int number, value;

	bool tiny;

	struct object *treasure;

	/* Small chests often hold "gold" */
	tiny = strstr(chest->kind->name, "Small") ? TRUE : FALSE;

	/* Determine how much to drop (see above) */
	if (strstr(chest->kind->name, "wooden"))
		number = 2;
	else if (strstr(chest->kind->name, "iron"))
		number = 4;
	else if (strstr(chest->kind->name, "steel"))
		number = 6;
	else
		number = 2 * (randint1(3));

	/* Zero pval means empty chest */
	if (!chest->pval) number = 0;

	/* Determine the "value" of the items */
	value = chest->origin_depth - 10 + 2 * chest->sval;
	if (value < 1)
		value = 1;

	/* Drop some objects (non-chests) */
	for (; number > 0; --number) {
		/* Small chests often drop gold */
		if (tiny && (randint0(100) < 75))
			treasure = make_gold(value, "any");

		/* Otherwise drop an item, as long as it isn't a chest */
		else {
			treasure = make_object(cave, value, FALSE, FALSE, FALSE, NULL, 0);
			if (!treasure) continue;
			if (tval_is_chest(treasure)) {
				mem_free(treasure);
				continue;
			}
		}

		/* Record origin */
		treasure->origin = ORIGIN_CHEST;
		treasure->origin_depth = chest->origin_depth;

		/* Drop it in the dungeon */
		drop_near(cave, treasure, 0, y, x, TRUE);
	}

	/* Empty */
	chest->pval = 0;

	/* Known */
	object_notice_everything(chest);
}
예제 #4
0
/**
 * This draws the Object Recall subwindow when displaying a recalled item kind
 * (e.g. a generic ring of acid or a generic blade of chaos)
 */
void display_object_kind_recall(struct object_kind *kind)
{
	struct object object = { 0 };
	object_prep(&object, kind, 0, EXTREMIFY);
	if (kind->aware)
		object_notice_everything(&object);

	display_object_recall(&object);
}
예제 #5
0
/* Unlock chests */
static void project_object_handler_KILL_TRAP(project_object_handler_context_t *context)
{
	/* Chests are noticed only if trapped or locked */
	if (is_locked_chest(context->obj)) {
		/* Disarm or Unlock */
		unlock_chest((struct object * const)context->obj);

		/* Identify */
		object_notice_everything((struct object * const)context->obj);

		/* Notice */
		if (context->obj->marked > MARK_UNAWARE && !ignore_item_ok(context->obj)) {
			msg("Click!");
			context->obvious = TRUE;
		}
	}
}
예제 #6
0
/*
 * Describe fake object
 */
static void desc_obj_fake(int k_idx)
{
	object_kind *kind = &k_info[k_idx];
	object_type object_type_body;
	object_type *o_ptr = &object_type_body;

	char header[120];

	textblock *tb;
	region area = { 0, 0, 0, 0 };

	/* Check for known artifacts, display them as artifacts */
	if (of_has(kind->flags, OF_INSTA_ART) && artifact_is_known(get_artifact_from_kind(kind)))
	{
		desc_art_fake(get_artifact_from_kind(kind));
		return;
	}

	/* Update the object recall window */
	track_object_kind(k_idx);
	handle_stuff(p_ptr);

	/* Wipe the object */
	object_wipe(o_ptr);

	/* Create the artifact */
	object_prep(o_ptr, kind, 0, EXTREMIFY);

	/* Hack -- its in the store */
	if (kind->aware) o_ptr->ident |= (IDENT_STORE);

	/* It's fully know */
	if (!kind->flavor) object_notice_everything(o_ptr);

	/* Hack -- Handle stuff */
	handle_stuff(p_ptr);

	tb = object_info(o_ptr, OINFO_NONE);
	object_desc(header, sizeof(header), o_ptr, ODESC_PREFIX | ODESC_FULL);

	textui_textblock_show(tb, area, format("%^s", header));
	textblock_free(tb);
}
예제 #7
0
/*
 * Show artifact lore
 */
static void desc_art_fake(int a_idx)
{
	object_type *o_ptr;
	object_type object_type_body = { 0 };

	char header[120];

	textblock *tb;
	region area = { 0, 0, 0, 0 };

	o_ptr = find_artifact(&a_info[a_idx]);

	/* If it's been lost, make a fake artifact for it */
	if (!o_ptr)
	{
		o_ptr = &object_type_body;

		make_fake_artifact(o_ptr, &a_info[a_idx]);
		o_ptr->ident |= IDENT_NAME;

		/* Check the history entry, to see if it was fully known before it
		 * was lost */
		if (history_is_artifact_known(o_ptr->artifact))
			object_notice_everything(o_ptr);
	}

	/* Hack -- Handle stuff */
	handle_stuff(p_ptr);

	tb = object_info(o_ptr, OINFO_NONE);
	object_desc(header, sizeof(header), o_ptr, ODESC_PREFIX | ODESC_FULL);

	textui_textblock_show(tb, area, format("%^s", header));
	textblock_free(tb);

#if 0
	/* XXX This should be in object_info */
	if (lost) text_out("\nThis artifact has been lost.");
#endif
}
예제 #8
0
파일: cmd1.c 프로젝트: tonberrytoby/angband
/*
 * Search for hidden things.  Returns true if a search was attempted, returns
 * false when the player has a 0% chance of finding anything.  Prints messages
 * for negative confirmation when verbose mode is requested.
 */
bool search(bool verbose)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	int y, x, chance;

	bool found = FALSE;

	object_type *o_ptr;


	/* Start with base search ability */
	chance = p_ptr->state.skills[SKILL_SEARCH];

	/* Penalize various conditions */
	if (p_ptr->timed[TMD_BLIND] || no_light()) chance = chance / 10;
	if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) chance = chance / 10;

	/* Prevent fruitless searches */
	if (chance <= 0)
	{
		if (verbose)
		{
			msg("You can't make out your surroundings well enough to search.");

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

		return FALSE;
	}

	/* Search the nearby grids, which are always in bounds */
	for (y = (py - 1); y <= (py + 1); y++)
	{
		for (x = (px - 1); x <= (px + 1); x++)
		{
			/* Sometimes, notice things */
			if (randint0(100) < chance)
			{
				/* Invisible trap */
				if (cave->feat[y][x] == FEAT_INVIS)
				{
					found = TRUE;

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

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

					/* Disturb */
					disturb(p_ptr, 0, 0);
				}

				/* Secret door */
				if (cave->feat[y][x] == FEAT_SECRET)
				{
					found = TRUE;

					/* Message */
					msg("You have found a secret door.");

					/* Pick a door */
					place_closed_door(cave, y, x);

					/* Disturb */
					disturb(p_ptr, 0, 0);
				}

				/* Scan all objects in the grid */
				for (o_ptr = get_first_object(y, x); o_ptr; o_ptr = get_next_object(o_ptr))
				{
					/* Skip non-chests */
					if (o_ptr->tval != TV_CHEST) continue;

					/* Skip disarmed chests */
					if (o_ptr->pval[DEFAULT_PVAL] <= 0) continue;

					/* Skip non-trapped chests */
					if (!chest_traps[o_ptr->pval[DEFAULT_PVAL]]) continue;

					/* Identify once */
					if (!object_is_known(o_ptr))
					{
						found = TRUE;

						/* Message */
						msg("You have discovered a trap on the chest!");

						/* Know the trap */
						object_notice_everything(o_ptr);

						/* Notice it */
						disturb(p_ptr, 0, 0);
					}
				}
			}
		}
	}

	if (verbose && !found)
	{
		if (chance >= 100)
			msg("There are no secrets here.");
		else
			msg("You found nothing.");
	}

	return TRUE;
}
예제 #9
0
파일: chest.c 프로젝트: JEAus/angband
/*
 * Allocate objects upon opening a chest
 *
 * Disperse treasures from the given chest, centered at (x,y).
 *
 * Small chests often contain "gold", while Large chests always contain
 * items.  Wooden chests contain 2 items, Iron chests contain 4 items,
 * and Steel chests contain 6 items.  The "value" of the items in a
 * chest is based on the level on which the chest is generated.
 */
static void chest_death(int y, int x, s16b o_idx)
{
	int number, value;

	bool tiny;

	object_type *o_ptr;

	object_type *i_ptr;
	object_type object_type_body;


	/* Get the chest */
	o_ptr = object_byid(o_idx);

	/* Small chests often hold "gold" */
	tiny = (o_ptr->sval < SV_CHEST_MIN_LARGE);

	/* Determine how much to drop (see above) */
	number = (o_ptr->sval % SV_CHEST_MIN_LARGE) * 2;

	/* Zero pval means empty chest */
	if (!o_ptr->pval[DEFAULT_PVAL]) number = 0;

	/* Determine the "value" of the items */
	value = o_ptr->origin_depth - 10 + 2 * o_ptr->sval;
	if (value < 1)
		value = 1;

	/* Drop some objects (non-chests) */
	for (; number > 0; --number)
	{
		/* Get local object */
		i_ptr = &object_type_body;

		/* Wipe the object */
		object_wipe(i_ptr);

		/* Small chests often drop gold */
		if (tiny && (randint0(100) < 75))
			make_gold(i_ptr, value, SV_GOLD_ANY);

		/* Otherwise drop an item, as long as it isn't a chest */
		else {
			if (!make_object(cave, i_ptr, value, FALSE, FALSE, NULL)) continue;
			if (i_ptr->tval == TV_CHEST) continue;
		}

		/* Record origin */
		i_ptr->origin = ORIGIN_CHEST;
		i_ptr->origin_depth = o_ptr->origin_depth;

		/* Drop it in the dungeon */
		drop_near(cave, i_ptr, 0, y, x, TRUE);
	}

	/* Empty */
	o_ptr->pval[DEFAULT_PVAL] = 0;

	/* Known */
	object_notice_everything(o_ptr);
}
예제 #10
0
파일: cmd-obj.c 프로젝트: Hrrunstar/angband
/*
 * Use an object the right way.
 *
 * There may be a BIG problem with any "effect" that can cause "changes"
 * to the inventory.  For example, a "scroll of recharging" can cause
 * a wand/staff to "disappear", moving the inventory up.  Luckily, the
 * scrolls all appear BEFORE the staffs/wands, so this is not a problem.
 * But, for example, a "staff of recharging" could cause MAJOR problems.
 * In such a case, it will be best to either (1) "postpone" the effect
 * until the end of the function, or (2) "change" the effect, say, into
 * giving a staff "negative" charges, or "turning a staff into a stick".
 * It seems as though a "rod of recharging" might in fact cause problems.
 * The basic problem is that the act of recharging (and destroying) an
 * item causes the inducer of that action to "move", causing "o_ptr" to
 * no longer point at the correct item, with horrifying results.
 */
void do_cmd_use(cmd_code code, cmd_arg args[])
{
	int item = args[0].item;
	object_type *o_ptr = object_from_item_idx(item);
	int effect;
	bool ident = FALSE, used = FALSE;
	bool was_aware = object_flavor_is_aware(o_ptr);
	int dir = 5;
	int px = p_ptr->px, py = p_ptr->py;
	int snd, boost, level;
	use_type use;
	int items_allowed = 0;

	/* Determine how this item is used. */
	if (obj_is_rod(o_ptr))
	{
		if (!obj_can_zap(o_ptr))
		{
			msg("That rod is still charging.");
			return;
		}

		use = USE_TIMEOUT;
		snd = MSG_ZAP_ROD;
		items_allowed = USE_INVEN | USE_FLOOR;
	}
	else if (obj_is_wand(o_ptr))
	{
		if (!obj_has_charges(o_ptr))
		{
			msg("That wand has no charges.");
			return;
		}

		use = USE_CHARGE;
		snd = MSG_ZAP_ROD;
		items_allowed = USE_INVEN | USE_FLOOR;
	}
	else if (obj_is_staff(o_ptr))
	{
		if (!obj_has_charges(o_ptr))
		{
			msg("That staff has no charges.");
			return;
		}

		use = USE_CHARGE;
		snd = MSG_USE_STAFF;
		items_allowed = USE_INVEN | USE_FLOOR;
	}
	else if (obj_is_food(o_ptr))
	{
		use = USE_SINGLE;
		snd = MSG_EAT;
		items_allowed = USE_INVEN | USE_FLOOR;
	}
	else if (obj_is_potion(o_ptr))
	{
		use = USE_SINGLE;
		snd = MSG_QUAFF;
		items_allowed = USE_INVEN | USE_FLOOR;
	}
	else if (obj_is_scroll(o_ptr))
	{
		/* Check player can use scroll */
		if (!player_can_read())
			return;

		use = USE_SINGLE;
		snd = MSG_GENERIC;
		items_allowed = USE_INVEN | USE_FLOOR;
	}
	else if (obj_is_activatable(o_ptr))
	{
		if (!obj_can_activate(o_ptr))
		{
			msg("That item is still charging.");
			return;
		}

		use = USE_TIMEOUT;
		snd = MSG_ACT_ARTIFACT;
		items_allowed = USE_EQUIP;
	}
	else
	{
		msg("The item cannot be used at the moment");
	}

	/* Check if item is within player's reach. */
	if (items_allowed == 0 || !item_is_available(item, NULL, items_allowed))
	{
		msg("You cannot use that item from its current location.");
		return;
	}

	/* track the object used */
	track_object(item);

	/* Figure out effect to use */
	effect = object_effect(o_ptr);

	/* If the item requires a direction, get one (allow cancelling) */
	if (obj_needs_aim(o_ptr))
		dir = args[1].direction;

	/* Check for use if necessary, and execute the effect */
	if ((use != USE_CHARGE && use != USE_TIMEOUT) || check_devices(o_ptr))
	{
		int beam = beam_chance(o_ptr->tval);

		/* Special message for artifacts */
		if (o_ptr->artifact)
		{
			msgt(snd, "You activate it.");
			if (o_ptr->artifact->effect_msg)
				activation_message(o_ptr, o_ptr->artifact->effect_msg);
			level = o_ptr->artifact->level;
		}
		else
		{
			/* Make a noise! */
			sound(snd);
			level = o_ptr->kind->level;
		}

		/* A bit of a hack to make ID work better.
			-- Check for "obvious" effects beforehand. */
		if (effect_obvious(effect)) object_flavor_aware(o_ptr);

		/* Boost damage effects if skill > difficulty */
		boost = MAX(p_ptr->state.skills[SKILL_DEVICE] - level, 0);

		/* Do effect */
		used = effect_do(effect, &ident, was_aware, dir, beam, boost);

		/* Quit if the item wasn't used and no knowledge was gained */
		if (!used && (was_aware || !ident)) return;
	}

	/* If the item is a null pointer or has been wiped, be done now */
	if (!o_ptr || !o_ptr->kind) return;

	if (ident) object_notice_effect(o_ptr);

	/* Food feeds the player */
	if (o_ptr->tval == TV_FOOD || o_ptr->tval == TV_POTION)
		(void)set_food(p_ptr->food + o_ptr->pval[DEFAULT_PVAL]);

	/* Use the turn */
	p_ptr->energy_use = 100;

	/* Mark as tried and redisplay */
	p_ptr->notice |= (PN_COMBINE | PN_REORDER);
	p_ptr->redraw |= (PR_INVEN | PR_EQUIP | PR_OBJECT);

	/*
	 * If the player becomes aware of the item's function, then mark it as
	 * aware and reward the player with some experience.  Otherwise, mark
	 * it as "tried".
	 */
	if (ident && !was_aware)
	{
		/* Object level */
		int lev = o_ptr->kind->level;

		object_flavor_aware(o_ptr);
		if (o_ptr->tval == TV_ROD) object_notice_everything(o_ptr);
		player_exp_gain(p_ptr, (lev + (p_ptr->lev / 2)) / p_ptr->lev);
		p_ptr->notice |= PN_SQUELCH;
	}
	else if (used)
	{
		object_flavor_tried(o_ptr);
	}

	/* If there are no more of the item left, then we're done. */
	if (!o_ptr->number) return;

	/* Chargeables act differently to single-used items when not used up */
	if (used && use == USE_CHARGE)
	{
		/* Use a single charge */
		o_ptr->pval[DEFAULT_PVAL]--;

		/* Describe charges */
		if (item >= 0)
			inven_item_charges(item);
		else
			floor_item_charges(0 - item);
	}
	else if (used && use == USE_TIMEOUT)
	{
		/* Artifacts use their own special field */
		if (o_ptr->artifact)
			o_ptr->timeout = randcalc(o_ptr->artifact->time, 0, RANDOMISE);
		else
			o_ptr->timeout += randcalc(o_ptr->kind->time, 0, RANDOMISE);
	}
	else if (used && use == USE_SINGLE)
	{
		/* Destroy a potion in the pack */
		if (item >= 0)
		{
			inven_item_increase(item, -1);
			inven_item_describe(item);
			inven_item_optimize(item);
		}

		/* Destroy a potion on the floor */
		else
		{
			floor_item_increase(0 - item, -1);
			floor_item_describe(0 - item);
			floor_item_optimize(0 - item);
		}
	}
	
	/* Hack to make Glyph of Warding work properly */
	if (cave->feat[py][px] == FEAT_GLYPH)
	{
		/* Push objects off the grid */
		if (cave->o_idx[py][px]) push_object(py, px);
	}


}
예제 #11
0
파일: wiz-spoil.c 프로젝트: apwhite/angband
/*
 * Describe the kind
 */
static void kind_info(char *buf, size_t buf_len,
                      char *dam, size_t dam_len,
                      char *wgt, size_t wgt_len,
                      int *lev, s32b *val, int k)
{
	object_kind *k_ptr;

	object_type *i_ptr;
	object_type object_type_body;
	int i;

	/* Get local object */
	i_ptr = &object_type_body;

	/* Prepare a fake item */
	object_prep(i_ptr, &k_info[k], 0, MAXIMISE);

	/* Obtain the "kind" info */
	k_ptr = i_ptr->kind;

	/* Cancel bonuses */
	for (i = 0; i < MAX_PVALS; i++)
		i_ptr->pval[i] = 0;
	i_ptr->to_a = 0;
	i_ptr->to_h = 0;
	i_ptr->to_d = 0;


	/* Level */
	(*lev) = k_ptr->level;

	/* Make known */
	object_notice_everything(i_ptr);

	/* Value */
	(*val) = object_value(i_ptr, 1, FALSE);

	/* Description (too brief) */
	if (buf)
		object_desc(buf, buf_len, i_ptr, ODESC_BASE | ODESC_SPOIL);

	/* Weight */
	if (wgt)
		strnfmt(wgt, wgt_len, "%3d.%d",
				i_ptr->weight / 10, i_ptr->weight % 10);

	/* Hack */
	if (!dam)
		return;

	/* Misc info */
	dam[0] = '\0';

	/* Damage */
	switch (i_ptr->tval)
	{
		/* Bows */
		case TV_BOW:
		{
			break;
		}

		/* Ammo */
		case TV_SHOT:
		case TV_BOLT:
		case TV_ARROW:
		{
			strnfmt(dam, dam_len, "%dd%d", i_ptr->dd, i_ptr->ds);
			break;
		}

		/* Weapons */
		case TV_HAFTED:
		case TV_POLEARM:
		case TV_SWORD:
		case TV_DIGGING:
		{
			strnfmt(dam, dam_len, "%dd%d", i_ptr->dd, i_ptr->ds);
			break;
		}

		/* Armour */
		case TV_BOOTS:
		case TV_GLOVES:
		case TV_CLOAK:
		case TV_CROWN:
		case TV_HELM:
		case TV_SHIELD:
		case TV_SOFT_ARMOR:
		case TV_HARD_ARMOR:
		case TV_DRAG_ARMOR:
		{
			strnfmt(dam, dam_len, "%d", i_ptr->ac);
			break;
		}
	}
}
예제 #12
0
파일: cmd-cave.c 프로젝트: Chillbon/angband
/**
 * Search for hidden things.  Returns true if a search was attempted, returns
 * false when the player has a 0% chance of finding anything.  Prints messages
 * for negative confirmation when verbose mode is requested.
 */
bool search(bool verbose)
{
	int py = player->py;
	int px = player->px;
	int y, x, chance;
	bool found = false;
	struct object *obj;

	/* Start with base search ability */
	chance = player->state.skills[SKILL_SEARCH];

	/* Penalize various conditions */
	if (player->timed[TMD_BLIND] || no_light())
		chance = chance / 10;
	if (player->timed[TMD_CONFUSED] || player->timed[TMD_IMAGE])
		chance = chance / 10;

	/* Prevent fruitless searches */
	if (chance <= 0) {
		if (verbose) {
			msg("You can't make out your surroundings well enough to search.");

			/* Cancel repeat */
			disturb(player, 0);
		}

		return false;
	}

	/* Search the nearby grids, which are always in bounds */
	for (y = (py - 1); y <= (py + 1); y++) {
		for (x = (px - 1); x <= (px + 1); x++) {
			/* Sometimes, notice things */
			if (randint0(100) < chance) {
				if (square_issecrettrap(cave, y, x)) {
					found = true;

					/* Reveal trap, display a message */
					if (square_reveal_trap(cave, y, x, chance, true))
						/* Disturb */
						disturb(player, 0);
				}

				/* Secret door */
				if (square_issecretdoor(cave, y, x)) {
					found = true;

					/* Message */
					msg("You have found a secret door.");

					/* Pick a door */
					place_closed_door(cave, y, x);

					/* Disturb */
					disturb(player, 0);
				}

				/* Scan all objects in the grid */
				for (obj = square_object(cave, y, x); obj; obj = obj->next) {
					/* Skip if not a trapped chest */
					if (!is_trapped_chest(obj)) continue;

					/* Identify once */
					if (!object_is_known(obj)) {
						found = true;

						/* Message */
						msg("You have discovered a trap on the chest!");

						/* Know the trap */
						object_notice_everything(obj);

						/* Notice it */
						disturb(player, 0);
					}
				}
			}
		}
	}

	if (verbose && !found) {
		if (chance >= 100)
			msg("There are no secrets here.");
		else
			msg("You found nothing.");
	}

	return true;
}
예제 #13
0
/* XXX Eddie should messages be adhoc all over the place?  perhaps the main
 * loop should check for change in inventory/wieldeds and all messages be
 * printed from one place
 */
void object_notice_on_wield(object_type *o_ptr)
{
	bitflag f[OF_SIZE], obvious_mask[OF_SIZE];
	bool obvious = FALSE;
	const slay_t *s_ptr;

	flags_init(obvious_mask, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END);

	/* Save time of wield for later */
	object_last_wield = turn;

	/* Only deal with un-ID'd items */
	if (object_is_known(o_ptr)) return;

	/* Wear it */
	object_flavor_tried(o_ptr);
	if (object_add_ident_flags(o_ptr, IDENT_WORN))
		object_check_for_ident(o_ptr);

	if (obj_is_light(o_ptr) && ego_item_p(o_ptr))
		object_notice_ego(o_ptr);

	if (object_flavor_is_aware(o_ptr) && easy_know(o_ptr))
	{
		object_notice_everything(o_ptr);
		return;
	}

	/* Automatically sense artifacts upon wield */
	object_sense_artifact(o_ptr);

	/* Note artifacts when found */
	if (artifact_p(o_ptr))
		history_add_artifact(o_ptr->name1, object_is_known(o_ptr), TRUE);

	/* special case FA, needed at least for mages wielding gloves */
	if (object_FA_would_be_obvious(o_ptr))
		of_on(obvious_mask, OF_FREE_ACT);

	/* Learn about obvious flags */
	of_union(o_ptr->known_flags, obvious_mask);

	/* Extract the flags */
	object_flags(o_ptr, f);

	/* Find obvious things (disregarding curses) */
	flags_clear(obvious_mask, OF_SIZE, OF_CURSE_MASK, FLAG_END);
	if (of_is_inter(f, obvious_mask)) obvious = TRUE;
	flags_init(obvious_mask, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END);

	/* XXX Eddie should these next NOT call object_check_for_ident due to worries about repairing? */


	/* XXX Eddie this is a small hack, but jewelry with anything noticeable really is obvious */
	/* XXX Eddie learn =soulkeeping vs =bodykeeping when notice sustain_str */
	if (object_is_jewelry(o_ptr))
	{
		/* Learn the flavor of jewelry with obvious flags */
		if (EASY_LEARN && obvious)
			object_flavor_aware(o_ptr);

		/* Learn all flags on any aware non-artifact jewelry */
		if (object_flavor_is_aware(o_ptr) && !artifact_p(o_ptr))
			object_know_all_flags(o_ptr);
	}

	object_check_for_ident(o_ptr);

	if (!obvious) return;

	/* Messages */
	for (s_ptr = slay_table; s_ptr->slay_flag; s_ptr++)
	{
		if (of_has(f, s_ptr->slay_flag) && s_ptr->brand)
		{
			char o_name[40];
			object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);
			msg_format("Your %s %s!", o_name, s_ptr->active_verb);
		}
	}

	/* XXX Eddie need to add stealth here, also need to assert/double-check everything is covered */
	if (of_has(f, OF_STR))
		msg_format("You feel %s!", o_ptr->pval > 0 ? "stronger" : "weaker");
	if (of_has(f, OF_INT))
		msg_format("You feel %s!", o_ptr->pval > 0 ? "smarter" : "more stupid");
	if (of_has(f, OF_WIS))
		msg_format("You feel %s!", o_ptr->pval > 0 ? "wiser" : "more naive");
	if (of_has(f, OF_DEX))
		msg_format("You feel %s!", o_ptr->pval > 0 ? "more dextrous" : "clumsier");
	if (of_has(f, OF_CON))
		msg_format("You feel %s!", o_ptr->pval > 0 ? "healthier" : "sicklier");
	if (of_has(f, OF_CHR))
		msg_format("You feel %s!", o_ptr->pval > 0 ? "cuter" : "uglier");
	if (of_has(f, OF_SPEED))
		msg_format("You feel strangely %s.", o_ptr->pval > 0 ? "quick" : "sluggish");
	if (flags_test(f, OF_SIZE, OF_BLOWS, OF_SHOTS, FLAG_END))
		msg_format("Your hands %s", o_ptr->pval > 0 ? "tingle!" : "ache.");
	if (of_has(f, OF_INFRA))
		msg_format("Your eyes tingle.");
	if (of_has(f, OF_LIGHT))
		msg_print("It glows!");
	if (of_has(f, OF_TELEPATHY))
		msg_print("Your mind feels strangely sharper!");

	/* WARNING -- masking f by obvious mask -- this should be at the end of this function */
	flags_mask(f, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END);

	/* learn the ego on any obvious brand or slay */
	if (EASY_LEARN && ego_item_p(o_ptr) && obvious &&
	    flags_test(f, OF_SIZE, OF_ALL_SLAY_MASK, FLAG_END))
		object_notice_ego(o_ptr);

	/* Remember the flags */
	object_notice_sensing(o_ptr);

	/* XXX Eddie should we check_for_ident here? */
}
예제 #14
0
/*
 * Sense the inventory
 */
void sense_inventory(void)
{
	int i;
	
	char o_name[80];
	
	unsigned int rate;
	
	
	/* No ID when confused in a bad state */
	if (p_ptr->timed[TMD_CONFUSED]) return;


	/* Notice some things after a while */
	if (turn >= (object_last_wield + 3000))
	{
		object_notice_after_time();
		object_last_wield = 0;
	}


	/* Get improvement rate */
	if (player_has(PF_PSEUDO_ID_IMPROV))
		rate = cp_ptr->sense_base / (p_ptr->lev * p_ptr->lev + cp_ptr->sense_div);
	else
		rate = cp_ptr->sense_base / (p_ptr->lev + cp_ptr->sense_div);

	if (!one_in_(rate)) return;


	/* Check everything */
	for (i = 0; i < ALL_INVEN_TOTAL; i++)
	{
		const char *text = NULL;

		object_type *o_ptr = &p_ptr->inventory[i];
		obj_pseudo_t feel;
		bool cursed;

		bool okay = FALSE;

		/* Skip empty slots */
		if (!o_ptr->k_idx) continue;

		/* Valid "tval" codes */
		switch (o_ptr->tval)
		{
			case TV_SHOT:
			case TV_ARROW:
			case TV_BOLT:
			case TV_BOW:
			case TV_DIGGING:
			case TV_HAFTED:
			case TV_POLEARM:
			case TV_SWORD:
			case TV_BOOTS:
			case TV_GLOVES:
			case TV_HELM:
			case TV_CROWN:
			case TV_SHIELD:
			case TV_CLOAK:
			case TV_SOFT_ARMOR:
			case TV_HARD_ARMOR:
			case TV_DRAG_ARMOR:
			{
				okay = TRUE;
				break;
			}
		}
		
		/* Skip non-sense machines */
		if (!okay) continue;
		
		/* It is known, no information needed */
		if (object_is_known(o_ptr)) continue;
		
		
		/* It has already been sensed, do not sense it again */
		if (object_was_sensed(o_ptr))
		{
			/* Small chance of wielded, sensed items getting complete ID */
			if (!o_ptr->name1 && (i >= INVEN_WIELD) && one_in_(1000))
				do_ident_item(i, o_ptr);

			continue;
		}

		/* Occasional failure on inventory items */
		if ((i < INVEN_WIELD) && one_in_(5)) continue;


		/* Sense the object */
		object_notice_sensing(o_ptr);
		cursed = object_notice_curses(o_ptr);

		/* Get the feeling */
		feel = object_pseudo(o_ptr);

		/* Stop everything */
		disturb(0, 0);

		if (cursed)
			text = "cursed";
		else
			text = inscrip_text[feel];

		object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);

		/* Average pseudo-ID means full ID */
		if (feel == INSCRIP_AVERAGE)
		{
			object_notice_everything(o_ptr);

			message_format(MSG_PSEUDOID, 0,
					"You feel the %s (%c) %s %s average...",
					o_name, index_to_label(i),((i >= INVEN_WIELD) ? "you are using" : "in your pack"),
					((o_ptr->number == 1) ? "is" : "are"));
		}
		else
		{
			if (i >= INVEN_WIELD)
			{
				message_format(MSG_PSEUDOID, 0, "You feel the %s (%c) you are %s %s %s...",
							   o_name, index_to_label(i), describe_use(i),
							   ((o_ptr->number == 1) ? "is" : "are"),
				                           text);
			}
			else
			{
				message_format(MSG_PSEUDOID, 0, "You feel the %s (%c) in your pack %s %s...",
							   o_name, index_to_label(i),
							   ((o_ptr->number == 1) ? "is" : "are"),
				                           text);
			}
		}


		/* Set squelch flag as appropriate */
		if (i < INVEN_WIELD)
			p_ptr->notice |= PN_SQUELCH;
		
		
		/* Combine / Reorder the pack (later) */
		p_ptr->notice |= (PN_COMBINE | PN_REORDER | PN_SORT_QUIVER);
		
		/* Redraw stuff */
		p_ptr->redraw |= (PR_INVEN | PR_EQUIP);
	}
}