1#include <inventory_system.h>
2#include <iostream>
3
4
5
6
7
8struct Item { };
9struct Container { };
10struct Inventory { };
11struct ContainedBy { };
12
13
14struct Active { };
15
16struct Amount {
17 int value;
18};
19
20struct Health {
21 int value;
22};
23
24struct Attack {
25 int value;
26};
27
28
29struct Sword : Item { };
30struct Armor : Item { };
31struct Coin : Item { };
32
33
34struct WoodenSword { };
35struct IronSword { };
36struct WoodenArmor { };
37struct IronArmor { };
38
39
43
45 if (id.is_entity()) {
46
47
48 if (
id.
entity().has(flecs::IsA, world.
id<Item>())) {
50 }
51 } else if (id.is_pair()) {
52
53
54 if (id.first() == flecs::IsA) {
56 if (base_kind) {
57 result = base_kind;
58 }
59 }
60 }
61 });
62
63 return result;
64}
65
66
67
70 const char *result = NULL;
71
73 if (id.is_entity()) {
74 if (
id.
entity().has(flecs::IsA, world.
id<Item>())) {
75 result = id.entity().name();
76 }
77 } else if (id.is_pair()) {
78 if (id.first() == flecs::IsA) {
80 if (base_kind) {
81 result = id.second().name();
82 }
83 }
84 }
85 });
86
87 return result;
88}
89
90
92 if (container.has<Container>()) {
93 return container;
94 }
95 return container.
target<Inventory>();
96}
97
98
99template <typename Func>
100void for_each_item(
flecs::entity container,
const Func& func) {
102 .with<ContainedBy>(container)
104}
105
106
109{
111
112 container = get_container(container);
113
115
116
117 if (active_required) {
118 if (!item.has<Active>()) {
119 return;
120 }
121 }
122
124 if (ik == kind) {
125 result = item;
126 }
127 });
128
129 return result;
130}
131
132
134 const Amount* amt = item.try_get<Amount>();
135 if (amt) {
136
137
141 if (dst_item) {
142
143 Amount& dst_amt = dst_item.ensure<Amount>();
144 dst_amt.value += amt->value;
146 return;
147 } else {
148
149
150 }
151 }
152
153
154 item.add<ContainedBy>(container);
155}
156
157
159 std::cout << ">> Transfer items from "
160 << src.
name() <<
" to " << dst.
name() <<
"\n\n";
161
162
164 dst = get_container(dst);
165 src = get_container(src);
166
168 transfer_item(dst.
mut(stage), item.
mut(stage));
169 });
171}
172
173
176
177 std::cout <<
">> " << player.
name() <<
" is attacked with a "
178 << item_name(weapon) << "!\n";
179
180 const Attack *att = weapon.try_get<Attack>();
181 if (!att) {
182
183 std::cout << " - the weapon is a dud\n";
184 return;
185 }
186
187 int att_value = att->value;
188
189
191 if (armor) {
192 Health *armor_health = armor.try_get_mut<Health>();
193 if (!armor_health) {
194
195 std::cout << " - the " << item_name(armor) << " armor is a dud\n";
196 } else {
197 std::cout <<
" - " << player.
name() <<
" defends with "
198 << item_name(armor) << "\n";
199
200
201
202 armor_health->value -= att_value;
203 if (armor_health->value <= 0) {
204 att_value += armor_health->value;
206 std::cout << " - " << item_name(armor) << " is destroyed!\n";
207 } else {
208 std::cout << " - " << item_name(armor) << " has "
209 << armor_health->value << " health left after taking "
210 << att_value << " damage\n";
211 att_value = 0;
212 }
213 }
214 } else {
215
216 std::cout <<
" - " << player.
name() <<
" fights without armor!\n";
217 }
218
219
220 Health& weapon_health = weapon.ensure<Health>();
221 if (!--weapon_health.value) {
222 std::cout << " - " << item_name(weapon) << " is destroyed!\n";
224 } else {
225 std::cout << " - " << item_name(weapon) << " has "
226 << weapon_health.value << " uses left";
227 }
228
229
230 if (att_value) {
231 Health& player_health = player.ensure<Health>();
232 if (!(player_health.value -= att_value)) {
233 std::cout <<
" - " << player.
name() <<
" died!\n";
235 } else {
236 std::cout <<
" - " << player.
name() <<
" has "
237 << player_health.value << " health left after taking "
238 << att_value << " damage\n";
239 }
240 }
241
242 std::cout << "\n";
243}
244
245
247 std::cout <<
"-- " << container.
name() <<
"'s inventory:\n";
248
249
250
251 container = get_container(container);
252
253 int32_t count = 0;
255
256
257 int32_t amount = 1;
258 item.get([&](const Amount& amt) {
259 amount = amt.value;
260 });
261
262 std::cout << " - " << amount << " " << item_name(item);
263 if (amount > 1) std::cout << "s";
264 std::cout << " (" << item_kind(item).name() << ")\n";
265
266 count ++;
267 });
268
269 if (!count) {
270 std::cout << " - << empty >>\n";
271 }
272
273 std::cout << "\n";
274}
275
276int main(int, char *[]) {
278
279
281 .add(flecs::Exclusive);
282
283
287
288
289 ecs.
prefab<WoodenSword>().add<Sword>()
290 .set<Attack>({ 1 })
291 .set_auto_override<Health>({ 5 });
292
293 ecs.
prefab<IronSword>().add<Sword>()
294 .set<Attack>({ 2 })
295 .set_auto_override<Health>({ 10 });
296
297 ecs.
prefab<WoodenArmor>().add<Armor>()
298 .set_auto_override<Health>({ 10 });
299
300 ecs.
prefab<IronArmor>().add<Armor>()
301 .set_auto_override<Health>({ 20 });
302
303
305 ecs.
entity().
is_a<IronSword>().add<ContainedBy>(loot_box);
306 ecs.
entity().
is_a<WoodenArmor>().add<ContainedBy>(loot_box);
307 ecs.
entity().add<Coin>().set<Amount>({ 30 }).add<ContainedBy>(loot_box);
308
309
311 ecs.
entity().add<Coin>().set<Amount>({ 20 })
312 .add<ContainedBy>(player_inventory);
314 .add<Inventory>(player_inventory);
315
316
317 print_items(loot_box);
318
319
320 print_items(player);
321
322
323 transfer_items(player, loot_box);
324
325
326 print_items(player);
327
328
329 print_items(loot_box);
330
331
333 if (armor) {
334 armor.add<Active>();
335 }
336
337
340
341
342 attack(player, my_sword);
343
344 std::cout << "\n";
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369}
flecs::component< T > component(Args &&... args) const
Find or register a component.
flecs::query_builder< Comps... > query_builder(Args &&... args) const
Create a query builder.
flecs::entity entity(Args &&... args) const
Create an entity.
flecs::entity prefab(const char *name=nullptr) const
Create a prefab that's associated with a type.
const Self & is_a(entity_t second) const
Shortcut for add(IsA, entity).
flecs::string_view name() const
Return the entity name.
void each(const Func &func) const
Iterate (component) IDs of an entity.
flecs::entity target(int32_t index=0) const
Get target for a given pair.
flecs::entity mut(const flecs::world &stage) const
Return a mutable entity handle for the current stage.
void destruct() const
Delete an entity.
entity()
Default constructor.
Class that wraps around a flecs::id_t.
flecs::world world() const
Get the world.
void merge() const
Merge world or stage.
flecs::id id() const
Get ID from a type.
void each(Func &&func) const
Iterate over all entities with components in the argument list of the function.
flecs::world get_stage(int32_t stage_id) const
Get stage-specific world pointer.
flecs::entity entity(Args &&... args) const
Create an entity.