227 lines
4.0 KiB
C
227 lines
4.0 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "../inventory/inventory.h"
|
|
|
|
static struct color gray;
|
|
static struct color darkgray;
|
|
|
|
static bool use_item(struct itemstack *stack)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
struct inventory player_inventory = {NULL};
|
|
|
|
static int selected_index = 0;
|
|
|
|
void inventory_add(struct inventory *self, struct itemstack stack)
|
|
{
|
|
struct list **ptr = &self->stacks;
|
|
|
|
if (stack.item->stackable) {
|
|
for (; *ptr != NULL; ptr = &(*ptr)->next) {
|
|
struct itemstack *other = (*ptr)->element;
|
|
if (other->item == stack.item) {
|
|
other->count += stack.count;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
struct itemstack *buf = make_buffer(&stack, sizeof(struct itemstack));
|
|
*ptr = add_element(*ptr, buf);
|
|
|
|
if (buf->item->on_create)
|
|
buf->item->on_create(buf);
|
|
}
|
|
|
|
/*
|
|
|
|
bool inventory_remove(struct inventory *self, struct itemstack *stack)
|
|
{
|
|
stack.count = -stack.count;
|
|
|
|
for (struct list **ptr = &self->stacks; *ptr != NULL; ) {
|
|
struct itemstack *other = (*ptr)->element;
|
|
|
|
if (other->item == stack.item) {
|
|
stack.count += other->count;
|
|
|
|
if (stack.count > 0) {
|
|
other->count = stack.count;
|
|
return true;
|
|
} else {
|
|
struct list *next = ptr->next;
|
|
|
|
other->count = 0;
|
|
|
|
if (other->item->on_destroy)
|
|
other->item->on_destroy(other);
|
|
|
|
free(other);
|
|
free(*ptr);
|
|
|
|
*ptr = next;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
ptr = &(*ptr)->next;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
*/
|
|
|
|
static void decrease_item_count(struct list **ptr)
|
|
{
|
|
struct itemstack *stack = (*ptr)->element;
|
|
|
|
stack->count--;
|
|
|
|
if (stack->count == 0) {
|
|
struct list *next = (*ptr)->next;
|
|
|
|
if (stack->item->on_destroy)
|
|
stack->item->on_destroy(stack);
|
|
|
|
if (stack->meta)
|
|
free(stack->meta);
|
|
|
|
free(stack);
|
|
free(*ptr);
|
|
|
|
*ptr = next;
|
|
}
|
|
}
|
|
|
|
static struct list **find_item(struct inventory *self, struct item *item)
|
|
{
|
|
for (struct list **ptr = &self->stacks; *ptr != NULL; ptr = &(*ptr)->next) {
|
|
struct itemstack *stack = (*ptr)->element;
|
|
|
|
if (stack->item == item)
|
|
return ptr;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
bool inventory_remove(struct inventory *self, struct item *item)
|
|
{
|
|
struct list **ptr = find_item(self, item);
|
|
|
|
if (ptr) {
|
|
decrease_item_count(ptr);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
struct itemstack *inventory_find(struct inventory *self, struct item *item)
|
|
{
|
|
struct list **ptr = find_item(self, item);
|
|
return ptr ? (*ptr)->element : NULL;
|
|
}
|
|
|
|
static void handle_enter()
|
|
{
|
|
int i = 0;
|
|
|
|
for (struct list **ptr = &player_inventory.stacks; *ptr != NULL; ptr = &(*ptr)->next, i++) {
|
|
if (i == selected_index) {
|
|
struct itemstack *stack = (*ptr)->element;
|
|
|
|
if (stack->item->on_use && stack->item->on_use(stack))
|
|
decrease_item_count(ptr);
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void handle_arrow()
|
|
{
|
|
char c = fgetc(stdin);
|
|
if (c == '[') {
|
|
char dir = fgetc(stdin);
|
|
|
|
int count = 0;
|
|
|
|
for (struct list *ptr = player_inventory.stacks; ptr != NULL; ptr = ptr->next)
|
|
count++;
|
|
|
|
if (count == 0)
|
|
return;
|
|
|
|
switch (dir) {
|
|
case 'A':
|
|
selected_index--;
|
|
|
|
if (selected_index < 0)
|
|
selected_index = count - 1;
|
|
break;
|
|
case 'B':
|
|
selected_index++;
|
|
|
|
if (selected_index >= count)
|
|
selected_index = 0;
|
|
|
|
break;
|
|
}
|
|
} else {
|
|
ungetc(c, stdin);
|
|
}
|
|
}
|
|
|
|
static void render_inventory(struct winsize ws)
|
|
{
|
|
printf("\e[3;0H");
|
|
|
|
printf(" \e[1mInventory\e[21m\n");
|
|
|
|
set_color(gray, false);
|
|
|
|
int i = 0;
|
|
for (struct list *ptr = player_inventory.stacks; ptr != NULL; ptr = ptr->next, i++) {
|
|
struct itemstack *stack = ptr->element;
|
|
|
|
if (i == selected_index) {
|
|
printf(" \e[39m→ ");
|
|
set_color(gray, false);
|
|
} else {
|
|
printf(" ");
|
|
}
|
|
|
|
printf("%s", stack->item->name);
|
|
|
|
if (stack->count > 1) {
|
|
set_color(darkgray, false);
|
|
printf(" (x%u)", stack->count);
|
|
set_color(gray, false);
|
|
}
|
|
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
__attribute__ ((constructor)) static void init()
|
|
{
|
|
gray = get_color("#9E9E9E");
|
|
darkgray = get_color("#555555");
|
|
|
|
register_render_component(&render_inventory);
|
|
|
|
register_input_handler('\033', (struct input_handler) {
|
|
.run_if_dead = false,
|
|
.callback = &handle_arrow,
|
|
});
|
|
|
|
register_input_handler('\n', (struct input_handler) {
|
|
.run_if_dead = false,
|
|
.callback = &handle_enter,
|
|
});
|
|
}
|