]> git.lizzy.rs Git - dungeon_game.git/blob - plugins/inventory/inventory.c
c3b533d70380e6b93cebbc08499c5eb37abd372f
[dungeon_game.git] / plugins / inventory / inventory.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "../inventory/inventory.h"
4
5 static struct color gray;
6 static struct color darkgray;
7
8 static bool use_item(struct itemstack *stack)
9 {
10         (void) stack;
11         return true;
12 }
13
14 struct inventory player_inventory = {NULL};
15
16 static int selected_index = 0;
17
18 void inventory_add(struct inventory *self, struct itemstack stack)
19 {
20         struct list **ptr = &self->stacks;
21
22         if (stack.item->stackable) {
23                 for (; *ptr != NULL; ptr = &(*ptr)->next) {
24                         struct itemstack *other = (*ptr)->element;
25                         if (other->item == stack.item) {
26                                 other->count += stack.count;
27                                 return;
28                         }
29                 }
30         }
31
32         *ptr = add_element(*ptr, make_buffer(&stack, sizeof(struct itemstack)));
33 }
34
35 /*
36
37 bool inventory_remove(struct inventory *self, struct itemstack *stack)
38 {
39         stack.count = -stack.count;
40
41         for (struct list **ptr = &self->stacks; *ptr != NULL; ) {
42                 struct itemstack *other = (*ptr)->element;
43
44                 if (other->item == stack.item) {
45                         stack.count += other->count;
46
47                         if (stack.count > 0) {
48                                 other->count = stack.count;
49                                 return true;
50                         } else {
51                                 struct list *next = ptr->next;
52
53                                 other->count = 0;
54
55                                 if (other->item->on_destroy)
56                                         other->item->on_destroy(other);
57
58                                 free(other);
59                                 free(*ptr);
60
61                                 *ptr = next;
62                                 continue;
63                         }
64                 }
65
66                 ptr = &(*ptr)->next;
67         }
68
69         return false;
70 }
71
72 */
73
74 static void decrease_item_count(struct list **ptr, struct itemstack *stack)
75 {
76         stack->count--;
77
78         if (stack->count == 0) {
79                 struct list *next = (*ptr)->next;
80
81                 if (stack->item->on_destroy)
82                         stack->item->on_destroy(stack);
83
84                 free(stack);
85                 free(*ptr);
86
87                 *ptr = next;
88         }
89 }
90
91 bool inventory_remove(struct inventory *self, struct item *item)
92 {
93         for (struct list **ptr = &self->stacks; *ptr != NULL; ptr = &(*ptr)->next) {
94                 struct itemstack *stack = (*ptr)->element;
95
96                 if (stack->item == item) {
97                         decrease_item_count(ptr, stack);
98
99                         return true;
100                 }
101         }
102
103         return false;
104 }
105
106 static void handle_enter()
107 {
108         int i = 0;
109
110         for (struct list **ptr = &player_inventory.stacks; *ptr != NULL; ptr = &(*ptr)->next, i++) {
111                 if (i == selected_index) {
112                         struct itemstack *stack = (*ptr)->element;
113
114                         if (stack->item->on_use && stack->item->on_use(stack))
115                                 decrease_item_count(ptr, stack);
116
117                         return;
118                 }
119         }
120 }
121
122 static void handle_arrow()
123 {
124         char c = fgetc(stdin);
125         if (c == '[') {
126                 char dir = fgetc(stdin);
127
128                 int count = 0;
129
130                 for (struct list *ptr = player_inventory.stacks; ptr != NULL; ptr = ptr->next)
131                         count++;
132
133                 if (count == 0)
134                         return;
135
136                 switch (dir) {
137                         case 'A':
138                                 selected_index--;
139
140                                 if (selected_index < 0)
141                                         selected_index = count - 1;
142                                 break;
143                         case 'B':
144                                 selected_index++;
145
146                                 if (selected_index >= count)
147                                         selected_index = 0;
148
149                                 break;
150                 }
151         } else {
152                 ungetc(c, stdin);
153         }
154 }
155
156 static void render_inventory(struct winsize ws)
157 {
158         printf("\e[3;0H");
159
160         printf(" \e[1mInventory\e[21m\n");
161
162         set_color(gray, false);
163
164         int i = 0;
165         for (struct list *ptr = player_inventory.stacks; ptr != NULL; ptr = ptr->next, i++) {
166                 struct itemstack *stack = ptr->element;
167
168                 if (i == selected_index) {
169                         printf(" \e[39m→ ");
170                         set_color(gray, false);
171                 } else {
172                         printf("   ");
173                 }
174
175                 printf("%s", stack->item->name);
176
177                 if (stack->count > 1) {
178                         set_color(darkgray, false);
179                         printf(" (x%u)", stack->count);
180                         set_color(gray, false);
181                 }
182
183                 printf("\n");
184         }
185 }
186
187 __attribute__ ((constructor)) static void init()
188 {
189         gray = get_color("#9E9E9E");
190         darkgray = get_color("#555555");
191
192         register_render_component(&render_inventory);
193
194         register_input_handler('\033', (struct input_handler) {
195                 .run_if_dead = false,
196                 .callback = &handle_arrow,
197         });
198
199         register_input_handler('\n', (struct input_handler) {
200                 .run_if_dead = false,
201                 .callback = &handle_enter,
202         });
203 }