Ejemplo n.º 1
0
/**
 * Remove an object from the gear list, leaving it unattached
 * \param obj the object being tested
 * \return whether an object was removed
 */
static bool gear_excise_object(struct object *obj)
{
	int i;

	pile_excise(&player->gear_k, obj->known);
	pile_excise(&player->gear, obj);

	/* Change the weight */
	player->upkeep->total_weight -= (obj->number * obj->weight);

	/* Make sure it isn't still equipped */
	for (i = 0; i < player->body.count; i++) {
		if (slot_object(player, i) == obj) {
			player->body.slots[i].obj = NULL;
			player->upkeep->equip_cnt--;
		}
	}

	/* Update the gear */
	calc_inventory(player->upkeep, player->gear, player->body);

	/* Housekeeping */
	player->upkeep->update |= (PU_BONUS);
	player->upkeep->notice |= (PN_COMBINE);
	player->upkeep->redraw |= (PR_INVEN | PR_EQUIP);

	return true;
}
Ejemplo n.º 2
0
/**
 * Handles the "death" of a monster.
 *
 * Disperses treasures carried by the monster centered at the monster location.
 * Note that objects dropped may disappear in crowded rooms.
 *
 * Checks for "Quest" completion when a quest monster is killed.
 *
 * Note that only the player can induce "monster_death()" on Uniques.
 * Thus (for now) all Quest monsters should be Uniques.
 *
 * If `stats` is true, then we skip updating the monster memory. This is
 * used by stats-generation code, for efficiency.
 */
void monster_death(struct monster *mon, bool stats)
{
	int dump_item = 0;
	int dump_gold = 0;
	struct object *obj = mon->held_obj;

	bool visible = (mflag_has(mon->mflag, MFLAG_VISIBLE) ||
					rf_has(mon->race->flags, RF_UNIQUE));

	/* Delete any mimicked objects */
	if (mon->mimicked_obj)
		object_delete(&mon->mimicked_obj);

	/* Drop objects being carried */
	while (obj) {
		struct object *next = obj->next;

		/* Object no longer held */
		obj->held_m_idx = 0;
		pile_excise(&mon->held_obj, obj);

		/* Count it and drop it - refactor once origin is a bitflag */
		if (!stats) {
			if (tval_is_money(obj) && (obj->origin != ORIGIN_STOLEN))
				dump_gold++;
			else if (!tval_is_money(obj) && ((obj->origin == ORIGIN_DROP)
					|| (obj->origin == ORIGIN_DROP_PIT)
					|| (obj->origin == ORIGIN_DROP_VAULT)
					|| (obj->origin == ORIGIN_DROP_SUMMON)
					|| (obj->origin == ORIGIN_DROP_SPECIAL)
					|| (obj->origin == ORIGIN_DROP_BREED)
					|| (obj->origin == ORIGIN_DROP_POLY)
					|| (obj->origin == ORIGIN_DROP_WIZARD)))
				dump_item++;
		}

		/* Change origin if monster is invisible, unless we're in stats mode */
		if (!visible && !stats)
			obj->origin = ORIGIN_DROP_UNKNOWN;

		drop_near(cave, obj, 0, mon->fy, mon->fx, true);
		obj = next;
	}

	/* Forget objects */
	mon->held_obj = NULL;

	/* Take note of any dropped treasure */
	if (visible && (dump_item || dump_gold))
		lore_treasure(mon, dump_item, dump_gold);

	/* Update monster list window */
	player->upkeep->redraw |= PR_MONLIST;

	/* Check if we finished a quest */
	quest_check(mon);
}
Ejemplo n.º 3
0
/**
 * Remove an object from the gear list, leaving it unattached
 * \param obj the object being tested
 * \return whether an object was removed
 */
bool gear_excise_object(struct object *obj)
{
	int i;

	pile_excise(&player->gear, obj);

	/* Make sure it isn't still equipped */
	for (i = 0; i < player->body.count; i++) {
		if (slot_object(player, i) == obj)
			player->body.slots[i].obj = NULL;
	}

	/* Housekeeping */
	player->upkeep->update |= (PU_BONUS | PU_MANA | PU_INVEN);
	player->upkeep->notice |= (PN_COMBINE);
	player->upkeep->redraw |= (PR_INVEN | PR_EQUIP);

	return TRUE;
}
Ejemplo n.º 4
0
/**
 * Excise an object from a floor pile, leaving it orphaned.
 */
void square_excise_object(struct chunk *c, int y, int x, struct object *obj) {
	pile_excise(&c->squares[y][x].obj, obj);
}
Ejemplo n.º 5
0
/**
 * Excise an object from a floor pile, leaving it orphaned.
 */
void square_excise_object(struct chunk *c, int y, int x, struct object *obj) {
	assert(square_in_bounds(c, y, x));
	pile_excise(&c->squares[y][x].obj, obj);
}
Ejemplo n.º 6
0
NOTEARDOWN

/* Testing the linked list functions in obj-pile.c */
int test_obj_piles(void *state) {
	struct object *pile = NULL;

	struct object *o1 = object_new();
	struct object *o2 = object_new();
	struct object *o3 = object_new();
	struct object *o4 = object_new();

	pile_insert(&pile, o1);
	eq(pile_contains(pile, o1), TRUE);
	eq(pile_contains(pile, o2), FALSE);
	ptreq(pile, o1);
	ptreq(pile_last_item(pile), o1);

	pile_insert_end(&pile, o2);
	eq(pile_contains(pile, o1), TRUE);
	eq(pile_contains(pile, o2), TRUE);
	eq(pile_contains(pile, o3), FALSE);
	ptreq(pile, o1);
	ptreq(pile_last_item(pile), o2);

	pile_insert_end(&pile, o3);
	eq(pile_contains(pile, o1), TRUE);
	eq(pile_contains(pile, o2), TRUE);
	eq(pile_contains(pile, o3), TRUE);
	ptreq(pile, o1);
	ptreq(pile_last_item(pile)->prev, o2);
	ptreq(pile_last_item(pile), o3);

	/* Now let's try excision */

	/* From the top */
	pile_excise(&pile, o1);
	ptreq(pile, o2);
	eq(pile_contains(pile, o1), FALSE);

	/* Now put it back */
	pile_insert(&pile, o1);

	/* From the end */
	pile_excise(&pile, o3);
	ptreq(pile, o1);
	eq(pile_contains(pile, o3), FALSE);
	ptreq(pile_last_item(pile), o2);
	ptreq(pile_last_item(pile)->prev, o1);
	object_delete(o3);

	/* Now put it back, and add another */
	o3 = object_new();
	pile_insert_end(&pile, o3);
	pile_insert_end(&pile, o4);

	/* Try removing from the middle */
	pile_excise(&pile, o3);
	ptreq(pile, o1);

	/* Now the list should look like o1 <-> o2 <-> o4, so check that */
	ptreq(o1->prev, NULL);
	ptreq(o1->next, o2);

	ptreq(o2->prev, o1);
	ptreq(o2->next, o4);

	ptreq(o3->prev, NULL);
	ptreq(o3->next, NULL);

	ptreq(o4->prev, o2);
	ptreq(o4->next, NULL);

	/* Free up */
	object_pile_free(pile);

	ok;
}