Ejemplo n.º 1
0
/**
 * Let the floor carry an object, deleting old ignored items if necessary.
 * The calling function must deal with the dropped object on failure.
 *
 * Optionally put the object at the top or bottom of the pile
 */
bool floor_carry(struct chunk *c, int y, int x, struct object *drop, bool last)
{
	int n = 0;
	struct object *obj, *ignore = floor_get_oldest_ignored(y, x);

	/* Fail if the square can't hold objects */
	if (!square_isobjectholding(c, y, x))
		return false;

	/* Scan objects in that grid for combination */
	for (obj = square_object(c, y, x); obj; obj = obj->next) {
		/* Check for combination */
		if (object_similar(obj, drop, OSTACK_FLOOR)) {
			/* Combine the items */
			object_absorb(obj, drop);

			/* Result */
			return true;
		}

		/* Count objects */
		n++;
	}

	/* The stack is already too large */
	if (n >= z_info->floor_size || (!OPT(player, birth_stacking) && n)) {
		/* Delete the oldest ignored object */
		if (ignore) {
			square_excise_object(c, y, x, ignore);
			delist_object(c, ignore);
			object_delete(&ignore);
		} else
			return false;
	}

	/* Location */
	drop->iy = y;
	drop->ix = x;

	/* Forget monster */
	drop->held_m_idx = 0;

	/* Link to the first or last object in the pile */
	if (last)
		pile_insert_end(&c->squares[y][x].obj, drop);
	else
		pile_insert(&c->squares[y][x].obj, drop);

	/* Record in the level list */
	list_object(c, drop);

	/* Redraw */
	square_note_spot(c, y, x);
	square_light_spot(c, y, x);

	/* Result */
	return true;
}
Ejemplo n.º 2
0
/**
 * Read a monster
 */
static bool rd_monster(struct chunk *c, struct monster *mon)
{
	byte tmp8u;
	u16b tmp16u;
	char race_name[80];
	size_t j;

	/* Read the monster race */
	rd_string(race_name, sizeof(race_name));
	mon->race = lookup_monster(race_name);
	if (!mon->race) {
		note(format("Monster race %s no longer exists!", race_name));
		return (-1);
	}

	/* Read the other information */
	rd_byte(&mon->fy);
	rd_byte(&mon->fx);
	rd_s16b(&mon->hp);
	rd_s16b(&mon->maxhp);
	rd_byte(&mon->mspeed);
	rd_byte(&mon->energy);
	rd_byte(&tmp8u);

	for (j = 0; j < tmp8u; j++)
		rd_s16b(&mon->m_timed[j]);

	/* Read and extract the flag */
	for (j = 0; j < mflag_size; j++)
		rd_byte(&mon->mflag[j]);

	for (j = 0; j < of_size; j++)
		rd_byte(&mon->known_pstate.flags[j]);

	for (j = 0; j < elem_max; j++)
		rd_s16b(&mon->known_pstate.el_info[j].res_level);

	rd_u16b(&tmp16u);

	if (tmp16u) {
		/* Find and set the mimicked object */
		struct object *square_obj = square_object(c, mon->fy, mon->fx);

		/* Try and find the mimicked object; if we fail, create a new one */
		while (square_obj) {
			if (square_obj->mimicking_m_idx == tmp16u) break;
			square_obj = square_obj->next;
		}
		if (square_obj) {
			mon->mimicked_obj = square_obj;
		} else {
			mon_create_mimicked_object(c, mon, tmp16u);
		}
	}

	/* Read all the held objects (order is unimportant) */
	while (true) {
		struct object *obj = rd_item();
		if (!obj)
			break;

		pile_insert(&mon->held_obj, obj);
		assert(obj->oidx);
		assert(c->objects[obj->oidx] == NULL);
		c->objects[obj->oidx] = obj;
	}

	return true;
}
Ejemplo n.º 3
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;
}