diff options
Diffstat (limited to 'plugins/inventory')
-rw-r--r-- | plugins/inventory/Makefile | 4 | ||||
-rw-r--r-- | plugins/inventory/dependencies.txt | 1 | ||||
-rw-r--r-- | plugins/inventory/inventory.c | 203 | ||||
-rw-r--r-- | plugins/inventory/inventory.h | 30 |
4 files changed, 238 insertions, 0 deletions
diff --git a/plugins/inventory/Makefile b/plugins/inventory/Makefile new file mode 100644 index 0000000..a665b55 --- /dev/null +++ b/plugins/inventory/Makefile @@ -0,0 +1,4 @@ +plugins/inventory/inventory.so: plugins/inventory/inventory.c plugins/inventory/inventory.h plugins/game/game.h + cc -g -shared -fpic -o plugins/inventory/inventory.so plugins/inventory/inventory.c + +PLUGINS := ${PLUGINS} plugins/inventory/inventory.so diff --git a/plugins/inventory/dependencies.txt b/plugins/inventory/dependencies.txt new file mode 100644 index 0000000..dc22e61 --- /dev/null +++ b/plugins/inventory/dependencies.txt @@ -0,0 +1 @@ +game diff --git a/plugins/inventory/inventory.c b/plugins/inventory/inventory.c new file mode 100644 index 0000000..c3b533d --- /dev/null +++ b/plugins/inventory/inventory.c @@ -0,0 +1,203 @@ +#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) +{ + (void) 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; + } + } + } + + *ptr = add_element(*ptr, make_buffer(&stack, sizeof(struct itemstack))); +} + +/* + +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) +{ + stack->count--; + + if (stack->count == 0) { + struct list *next = (*ptr)->next; + + if (stack->item->on_destroy) + stack->item->on_destroy(stack); + + free(stack); + free(*ptr); + + *ptr = next; + } +} + +bool inventory_remove(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) { + decrease_item_count(ptr, stack); + + return true; + } + } + + return false; +} + +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, stack); + + 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, + }); +} diff --git a/plugins/inventory/inventory.h b/plugins/inventory/inventory.h new file mode 100644 index 0000000..4b13f94 --- /dev/null +++ b/plugins/inventory/inventory.h @@ -0,0 +1,30 @@ +#ifndef _INVENTORY_H_ +#define _INVENTORY_H_ +#include "../game/game.h" + +struct itemstack +{ + struct item *item; + int count; + void *meta; +}; + +struct item +{ + char *name; + bool stackable; + + bool (*on_use)(struct itemstack *stack); + void (*on_destroy)(struct itemstack *stack); +}; + +struct inventory +{ + struct list *stacks; +}; + +void inventory_add(struct inventory *self, struct itemstack stack); +bool inventory_remove(struct inventory *self, struct item *item); + +extern struct inventory player_inventory; +#endif |