#include "inventory.h" #include "tile.h" #include "message.h" #include // for sprintf and NULL #include "parser.h" // for Slots-related parsing /**** addToInventory Cleanly handles adding a Tile(second arg) to the passed Inventory(first arg). Does not remove from any previous Inventory membership. Arguments: struct Inventory *inventory, struct Tile *tile ****/ int addToInventory(struct Inventory *inventory, struct Tile *tile) { if (inventory->last_tile) { inventory->last_tile->next = tile; tile->prev = inventory->last_tile; inventory->last_tile = tile; } else { inventory->tile = tile; inventory->last_tile = tile; } inventory->count++; return 0; } int inventoryEquip(struct Inventory *inventory, int selected) { int i = 0; struct Tile *current_tile = inventory->tile; while (current_tile) { if (i == selected) { char difference[64]; char string[64]; int type = slotsCanAdd(difference, ((struct PlayerTile*)inventory->owner->data)->slots, ((struct PlayerTile*)inventory->owner->data)->used_slots, ((struct EquipTile*)current_tile->data)->required_slots); if (type == 2) { // sprintf(string, MESSAGE_EQUIP_NEED_FREE, difference); messageTile(current_tile, inventory->owner, string); } else if (type == 1) { sprintf(string, MESSAGE_EQUIP_NEED_SLOTS, difference); messageTile(current_tile, inventory->owner, string); } else { sprintf(string, MESSAGE_EQUIP, ((struct BasicTile*)current_tile->data)->name); slotsAddSlots(((struct PlayerTile*)inventory->owner->data)->used_slots, ((struct EquipTile*)current_tile->data)->required_slots); inventoryRemove(inventory, current_tile); addToInventory(&((struct PlayerTile*)inventory->owner->data)->equipment, current_tile); messageTile(current_tile, inventory->owner, string); } } current_tile = current_tile->next; i++; } return 1; } int inventoryUnequip(struct Inventory *inventory, int selected) { int i = 0; struct Tile *current_tile = inventory->tile; while (current_tile) { if (i == selected) { char string[64]; slotsRemoveSlots(((struct PlayerTile*)inventory->owner->data)->used_slots, ((struct EquipTile*)current_tile->data)->required_slots); inventoryRemove(inventory, current_tile); addToInventory(&((struct PlayerTile*)inventory->owner->data)->inventory, current_tile); sprintf(string, MESSAGE_UNEQUIP, ((struct BasicTile*)current_tile->data)->name); messageTile(current_tile, inventory->owner, string); } current_tile = current_tile->next; i++; } return 1; } /**** inventoryMove Moves the selected index around in the inventory by given x and y values (moves the cursor). Arguments: struct Inventory *inventory, int x, int y Returns: 0 on success 1 when target index is out of bounds ****/ int inventoryMove(struct Inventory *inventory, int x, int y) { int target; target = inventory->selected + x + (y*inventory->slots_per_row); if (target >= 0 && target < inventory->count) { //inventory->x = x; //inventory->y = y; inventory->selected = target; return 0; } else if (target >= 0 && target >= inventory->count) { inventory->selected = inventory->count-1; } else if (target <= 0) { inventory->selected = 0; } return 1; } /**** inventoryDrop Removes the selected index Tile from passed Inventory and moves it to under the Inventory->owner's position in its Tile Chain. Also sends a message to the Inventory->owner that the tile dropped. Arguments: struct Inventory *inventory, int selected Returns: 0 if selected is found 1 if selected is not found ****/ int inventoryDrop(struct Inventory *inventory, int selected) { int i = 0; struct Tile *current_tile = inventory->tile; while (current_tile) { if (i == selected) { inventoryRemove(inventory, current_tile); // Move item to below owner (e.g., dropped beneath the player) inventory->owner->prev->next = current_tile; current_tile->next = inventory->owner; current_tile->prev = inventory->owner->prev; inventory->owner->prev = current_tile; // Tell item owner it dropped char string[64]; sprintf(string, MESSAGE_DROP, ((struct BasicTile*)current_tile->data)->name); messageTile(current_tile, inventory->owner, string); return 0; break; } current_tile = current_tile->next; i++; } return 1; } int inventoryRemove(struct Inventory *inventory, struct Tile *tile) { // if item is the last tile, make last tile previous tile if (tile == inventory->last_tile) { inventory->last_tile = tile->prev; inventory->selected--; // if item is also the first tile, NULL it (in other words, inventory is empty) if (tile == inventory->tile) { inventory->tile = NULL; inventory->selected = 0; } } else { // if item is the beginning, but not the last, set the beginning to the next item if (tile == inventory->tile) { inventory->tile = tile->next; } } inventory->count--; // Detach item from chain, patching up neighbors as needed removeFromChain(tile); } struct Tile *inventoryGetSelected(struct Inventory *inventory) { struct Tile *current_tile = inventory->tile; int i = 0; while (current_tile) { if (i == inventory->selected) { return current_tile; } current_tile = current_tile->next; i++; } return NULL; }