示例#1
0
/**
 * Sense the existence of objects on a grid in the current level
 */
void floor_pile_sense(struct chunk *c, int y, int x)
{
	struct object *obj;

	if (c != cave) return;

	/* Sense every item on this grid */
	for (obj = square_object(c, y, x); obj; obj = obj->next) {
		struct object *known_obj = cave_k->objects[obj->oidx];

		/* Make new sensed objects where necessary */
		if (known_obj == NULL) {
			/* Make and list the new object */
			struct object *new_obj = object_new();
			cave_k->objects[obj->oidx] = new_obj;
			new_obj->oidx = obj->oidx;
			obj->known = new_obj;
			new_obj->number = 1;

			/* Give it a fake kind */
			if (tval_is_money(obj))
				new_obj->kind = unknown_gold_kind;
			else
				new_obj->kind = unknown_item_kind;

			/* Attach it to the current floor pile */
			new_obj->iy = y;
			new_obj->ix = x;
			pile_insert_end(&cave_k->squares[y][x].obj, new_obj);
		}
	}
}
示例#2
0
文件: obj-pile.c 项目: fizzix/angband
/**
 * 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;
}
示例#3
0
文件: obj-gear.c 项目: fe051/angband
void gear_insert_end(struct object *obj)
{
	pile_insert_end(&player->gear, obj);
	pile_insert_end(&player->gear_k, obj->known);
}
示例#4
0
/**
 * Update the player's knowledge of the objects on a grid in the current level
 */
void floor_pile_know(struct chunk *c, int y, int x)
{
	struct object *obj;

	if (c != cave) return;

	object_lists_check_integrity();

	/* Know every item on this grid */
	for (obj = square_object(c, y, x); obj; obj = obj->next) {
		struct object *known_obj = cave_k->objects[obj->oidx];

		/* Make new known objects, fully know sensed ones, relocate old ones */
		if (known_obj == NULL) {
			/* Make and/or list the new object */
			struct object *new_obj;

			/* Check whether we need to make a new one or list the old one */
			if (obj->known) {
				new_obj = obj->known;
			} else {
				new_obj = object_new();
				obj->known = new_obj;
				object_set_base_known(obj);
			}
			cave_k->objects[obj->oidx] = new_obj;
			new_obj->oidx = obj->oidx;

			/* Attach it to the current floor pile */
			new_obj->iy = y;
			new_obj->ix = x;
			new_obj->number = obj->number;
			if (!square_holds_object(cave_k, y, x, new_obj))
				pile_insert_end(&cave_k->squares[y][x].obj, new_obj);
		} else if (known_obj->kind != obj->kind) {
			int iy = known_obj->iy;
			int ix = known_obj->ix;

			/* Make sure knowledge is correct */
			assert(known_obj == obj->known);

			/* Detach from any old pile (possibly the correct one) */
			if (iy && ix && square_holds_object(cave_k, iy, ix, known_obj))
				square_excise_object(cave_k, iy, ix, known_obj);

			/* Copy over actual details */
			object_set_base_known(obj);

			/* Attach it to the current floor pile */
			known_obj->iy = y;
			known_obj->ix = x;
			known_obj->held_m_idx = 0;
			if (!square_holds_object(cave_k, y, x, known_obj))
				pile_insert_end(&cave_k->squares[y][x].obj, known_obj);
		} else if (!square_holds_object(cave_k, y, x, known_obj)) {
			int iy = known_obj->iy;
			int ix = known_obj->ix;

			/* Make sure knowledge is correct */
			assert(known_obj == obj->known);
			known_obj->number = obj->number;

			/* Detach from any old pile */
			if (iy && ix && square_holds_object(cave_k, iy, ix, known_obj))
				square_excise_object(cave_k, iy, ix, known_obj);

			/* Attach it to the current floor pile */
			known_obj->iy = y;
			known_obj->ix = x;
			known_obj->held_m_idx = 0;
			pile_insert_end(&cave_k->squares[y][x].obj, known_obj);
		}
	}

	/* Remove known location of anything not on this grid */
	obj = square_object(cave_k, y, x);
	while (obj) {
		struct object *next = obj->next;
		assert(c->objects[obj->oidx]);
		if (!square_holds_object(c, y, x, c->objects[obj->oidx])) {
			struct object *original = c->objects[obj->oidx];
			square_excise_object(cave_k, y, x, obj);
			obj->iy = 0;
			obj->ix = 0;

			/* Delete objects which no longer exist anywhere */
			if (obj->notice & OBJ_NOTICE_IMAGINED) {
				delist_object(cave_k, obj);
				object_delete(&obj);
				original->known = NULL;
				delist_object(c, original);
				object_delete(&original);
			}
		}
		obj = next;
	}
}
示例#5
0
文件: pile.c 项目: myshkin/angband
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;
}