コード例 #1
0
ファイル: mon-blow-effects.c プロジェクト: Daedelus01/angband
/**
 * Melee effect handler: Eat the player's food.
 */
static void melee_effect_handler_EAT_FOOD(melee_effect_handler_context_t *context)
{
	/* Steal some food */
	int tries;

	/* Take damage */
	take_hit(context->p, context->damage, context->ddesc);

	for (tries = 0; tries < 10; tries++) {
		/* Pick an item from the pack */
		int index = randint0(z_info->pack_size);
		struct object *obj, *eaten;
		char o_name[80];

		/* Get the item */
		obj = context->p->upkeep->inven[index];

		/* Skip non-objects */
		if (obj == NULL) continue;

		/* Skip non-food objects */
		if (!tval_is_food(obj)) continue;

		if (obj->number == 1) {
			object_desc(o_name, sizeof(o_name), obj, ODESC_BASE);
			msg("Your %s (%c) was eaten!", o_name, I2A(index));
		} else {
			object_desc(o_name, sizeof(o_name), obj,
						ODESC_PREFIX | ODESC_BASE);
			msg("One of your %s (%c) was eaten!", o_name,
				I2A(index));
		}

		/* Steal and eat */
		eaten = gear_object_for_use(obj, 1, FALSE);
		object_delete(eaten);

		/* Obvious */
		context->obvious = TRUE;

		/* Done */
		break;
	}
}
コード例 #2
0
ファイル: obj-info.c プロジェクト: pnd10/angband
/**
 * Gives the known effects of using the given item.
 *
 * Fills in:
 *  - the effect id, or OBJ_KNOWN_PRESENT if there is an effect but details
 *    are unknown
 *  - whether the effect can be aimed
 *  -  the minimum and maximum time in game turns for the item to recharge 
 *     (or zero if it does not recharge)
 *  - the percentage chance of the effect failing when used
 *
 * Return FALSE if the object has no effect.
 */
static bool obj_known_effect(const struct object *obj, int *effect, bool *aimed, int *min_recharge, int *max_recharge, int *failure_chance)
{
	random_value timeout = {0, 0, 0, 0};

	*effect = 0;
	*min_recharge = 0;
	*max_recharge = 0;
	*failure_chance = 0;
	*aimed = FALSE;

	if (object_effect_is_known(obj)) {
		*effect = object_effect(obj);
		timeout = obj->time;
	} else if (object_effect(obj)) {
		/* Don't know much - be vague */
		*effect = OBJ_KNOWN_PRESENT;

		if (!obj->artifact && effect_aim(obj->effect))
			*aimed = TRUE;
					
		return TRUE;
	} else {
		/* No effect - no info */
		return FALSE;
	}
	
	if (randcalc(timeout, 0, MAXIMISE) > 0)	{
		*min_recharge = randcalc(timeout, 0, MINIMISE);
		*max_recharge = randcalc(timeout, 0, MAXIMISE);
	}

	if (tval_is_food(obj) || tval_is_potion(obj) || tval_is_scroll(obj)) {
		*failure_chance = 0;
	} else {
		*failure_chance = get_use_device_chance(obj);
	}

	return TRUE;
}
コード例 #3
0
ファイル: obj-make.c プロジェクト: myshkin/angband
/**
 * Wipe an object clean and make it a standard object of the specified kind.
 */
void object_prep(struct object *o_ptr, struct object_kind *k, int lev,
				 aspect rand_aspect)
{
	int i;

	/* Clean slate */
	memset(o_ptr, 0, sizeof(*o_ptr));

	/* Assign the kind and copy across data */
	o_ptr->kind = k;
	o_ptr->tval = k->tval;
	o_ptr->sval = k->sval;
	o_ptr->ac = k->ac;
	o_ptr->dd = k->dd;
	o_ptr->ds = k->ds;
	o_ptr->weight = k->weight;
	o_ptr->effect = k->effect;
	o_ptr->time = k->time;

	/* Weight is always known */
	id_on(o_ptr->id_flags, ID_WEIGHT);

	/* Default number */
	o_ptr->number = 1;

	/* Copy flags */
	of_copy(o_ptr->flags, k->base->flags);
	of_copy(o_ptr->flags, k->flags);

	/* Assign modifiers */
	for (i = 0; i < OBJ_MOD_MAX; i++)
		o_ptr->modifiers[i] = randcalc(k->modifiers[i], lev, rand_aspect);

	/* Assign charges (wands/staves only) */
	if (tval_can_have_charges(o_ptr))
		o_ptr->pval = randcalc(k->charge, lev, rand_aspect);

	/* Assign pval for food, oil and launchers */
	if (tval_is_food(o_ptr) || tval_is_potion(o_ptr) || tval_is_fuel(o_ptr) ||
		tval_is_launcher(o_ptr))
		o_ptr->pval
			= randcalc(k->pval, lev, rand_aspect);

	/* Default fuel */
	if (tval_is_light(o_ptr)) {
		if (of_has(o_ptr->flags, OF_BURNS_OUT))
			o_ptr->timeout = z_info->fuel_torch;
		else if (of_has(o_ptr->flags, OF_TAKES_FUEL))
			o_ptr->timeout = z_info->default_lamp;
	}

	/* Default magic */
	o_ptr->to_h = randcalc(k->to_h, lev, rand_aspect);
	o_ptr->to_d = randcalc(k->to_d, lev, rand_aspect);
	o_ptr->to_a = randcalc(k->to_a, lev, rand_aspect);

	/* Default slays and brands */
	copy_slay(&o_ptr->slays, k->slays);
	copy_brand(&o_ptr->brands, k->brands);

	/* Default resists */
	for (i = 0; i < ELEM_MAX; i++) {
		o_ptr->el_info[i].res_level = k->el_info[i].res_level;
		o_ptr->el_info[i].flags = k->el_info[i].flags;
		o_ptr->el_info[i].flags |= k->base->el_info[i].flags;

		/* Unresistables have no hidden properties */
		if (i > ELEM_HIGH_MAX)
			o_ptr->el_info[i].flags |= EL_INFO_KNOWN;
	}
}
コード例 #4
0
ファイル: obj-pile.c プロジェクト: danaris/tgcangband
/**
 * Determine if an item can "absorb" a second item
 *
 * See "object_absorb()" for the actual "absorption" code.
 *
 * If permitted, we allow weapons/armor to stack, if "known".
 *
 * Missiles will combine if both stacks have the same "known" status.
 * This is done to make unidentified stacks of missiles useful.
 *
 * Food, potions, scrolls, and "easy know" items always stack.
 *
 * Chests, and activatable items, except rods, never stack (for various
 * reasons).
 */
bool object_stackable(const struct object *obj1, const struct object *obj2,
					  object_stack_t mode)
{
	int i;

	/* Equipment items don't stack */
	if (object_is_equipped(player->body, obj1))
		return FALSE;
	if (object_is_equipped(player->body, obj2))
		return FALSE;

	/* If either item is unknown, do not stack */
	if (mode & OSTACK_LIST && obj1->marked == MARK_AWARE) return FALSE;
	if (mode & OSTACK_LIST && obj2->marked == MARK_AWARE) return FALSE;

	/* Hack -- identical items cannot be stacked */
	if (obj1 == obj2) return FALSE;

	/* Require identical object kinds */
	if (obj1->kind != obj2->kind) return FALSE;

	/* Different flags don't stack */
	if (!of_is_equal(obj1->flags, obj2->flags)) return FALSE;

	/* Different elements don't stack */
	for (i = 0; i < ELEM_MAX; i++) {
		if (obj1->el_info[i].res_level != obj2->el_info[i].res_level)
			return FALSE;
		if ((obj1->el_info[i].flags & (EL_INFO_HATES | EL_INFO_IGNORE)) !=
			(obj2->el_info[i].flags & (EL_INFO_HATES | EL_INFO_IGNORE)))
			return FALSE;
	}

	/* Artifacts never stack */
	if (obj1->artifact || obj2->artifact) return FALSE;

	/* Analyze the items */
	if (tval_is_chest(obj1)) {
		/* Chests never stack */
		return FALSE;
	}
	else if (tval_is_food(obj1) || tval_is_potion(obj1) ||
		tval_is_scroll(obj1) || tval_is_rod(obj1)) {
		/* Food, potions, scrolls and rods all stack nicely,
		   since the kinds are identical, either both will be
		   aware or both will be unaware */
	} else if (tval_can_have_charges(obj1) || tval_is_money(obj1)) {
		/* Gold, staves and wands stack most of the time */
		/* Too much gold or too many charges */
		if (obj1->pval + obj2->pval > MAX_PVAL)
			return FALSE;

		/* ... otherwise ok */
	} else if (tval_is_weapon(obj1) || tval_is_armor(obj1) ||
		tval_is_jewelry(obj1) || tval_is_light(obj1)) {
		bool obj1_is_known = object_is_known(obj1);
		bool obj2_is_known = object_is_known(obj2);

		/* Require identical values */
		if (obj1->ac != obj2->ac) return FALSE;
		if (obj1->dd != obj2->dd) return FALSE;
		if (obj1->ds != obj2->ds) return FALSE;

		/* Require identical bonuses */
		if (obj1->to_h != obj2->to_h) return FALSE;
		if (obj1->to_d != obj2->to_d) return FALSE;
		if (obj1->to_a != obj2->to_a) return FALSE;

		/* Require all identical modifiers */
		for (i = 0; i < OBJ_MOD_MAX; i++)
			if (obj1->modifiers[i] != obj2->modifiers[i])
				return (FALSE);

		/* Require identical ego-item types */
		if (obj1->ego != obj2->ego) return FALSE;

		/* Hack - Never stack recharging wearables ... */
		if ((obj1->timeout || obj2->timeout) &&
			!tval_is_light(obj1)) return FALSE;

		/* ... and lights must have same amount of fuel */
		else if ((obj1->timeout != obj2->timeout) &&
				 tval_is_light(obj1)) return FALSE;

		/* Prevent unIDd items stacking with IDd items in the object list */
		if (mode & OSTACK_LIST && (obj1_is_known != obj2_is_known))
			return FALSE;
	} else {
		/* Anything else probably okay */
	}

	/* Require compatible inscriptions */
	if (obj1->note && obj2->note && (obj1->note != obj2->note))
		return FALSE;

	/* They must be similar enough */
	return TRUE;
}