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