164 lines
5.4 KiB
C
164 lines
5.4 KiB
C
#include "inventory.h"
|
|
#include "tile.h"
|
|
#include "message.h"
|
|
#include <stdio.h> // 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;
|
|
}
|