Created
June 29, 2023 16:12
-
-
Save garrettjoecox/8654a35375546f250f57571adbd5b303 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is an inventory architecture using Bevy's ECS | |
// An inventory is a collection of inventory slots, which can hold an item. | |
// An inventory can be any shape or size (think a chest vs a player's inventory vs a crafting table) | |
// An inventory slot can be empty, or hold an item stack. | |
// Some inventory slots can only hold certain types of item stacks (think armor slots) | |
// An item stack is a collection of items of the same type, some items can be stacked, some can't. | |
// An item stack can be split into two item stacks, or merged with another item stack. | |
// Each type of item has different properties like consumable, stackable, etc. | |
#[derive(PartialEq)] | |
enum ItemType { | |
None, | |
Apple, | |
BakedApple, | |
WoodBlock, | |
IronSword, | |
Coal, | |
} | |
enum ConsumeAction { | |
Eat, | |
Drink, | |
} | |
#[derive(Component)] | |
struct Consumable(ConsumeAction); | |
#[derive(Component)] | |
struct Placeable; | |
#[derive(Component)] | |
struct Strength(f32); | |
#[derive(Component)] | |
struct Durability { | |
current: f32, | |
step: f32, | |
} | |
#[derive(Component)] | |
struct Stackable { | |
max: u32, | |
current: u32, | |
} | |
impl Default for Stackable { | |
fn default() -> Self { | |
Stackable { | |
max: 64, | |
current: 1, | |
} | |
} | |
} | |
#[derive(Component)] | |
struct Name(String); | |
#[derive(Component)] | |
struct Item(ItemType); | |
#[derive(Component)] | |
struct Smeltable { | |
result: ItemType, | |
time: f32, | |
} | |
#[derive(Component)] | |
struct Fuel { | |
time: f32, | |
} | |
#[derive(Bundle)] | |
struct AppleBundle { | |
item: Item, | |
name: Name, | |
consumable: Consumable, | |
smeltable: Smeltable, | |
stackable: Stackable, | |
} | |
impl Default for AppleBundle { | |
fn default() -> Self { | |
AppleBundle { | |
item: Item(ItemType::Apple), | |
name: Name("Apple".to_string()), | |
consumable: Consumable(ConsumeAction::Eat), | |
smeltable: Smeltable { | |
result: ItemType::BakedApple, | |
time: 1.0, | |
}, | |
stackable: Stackable { | |
max: 64, | |
current: 1, | |
}, | |
} | |
} | |
} | |
#[derive(Bundle)] | |
struct WoodBlockBundle { | |
item: Item, | |
name: Name, | |
stackable: Stackable, | |
placeable: Placeable, | |
smeltable: Smeltable, | |
fuel: Fuel, | |
} | |
impl Default for WoodBlockBundle { | |
fn default() -> Self { | |
WoodBlockBundle { | |
item: Item(ItemType::WoodBlock), | |
name: Name("Wood Block".to_string()), | |
stackable: Stackable { | |
max: 64, | |
current: 1, | |
}, | |
placeable: Placeable, | |
smeltable: Smeltable { | |
result: ItemType::Coal, | |
time: 4.0, | |
}, | |
fuel: Fuel { time: 16.0 }, | |
} | |
} | |
} | |
#[derive(Bundle)] | |
struct IronSwordBundle { | |
item: Item, | |
name: Name, | |
durability: Durability, | |
strength: Strength, | |
} | |
impl Default for IronSwordBundle { | |
fn default() -> Self { | |
IronSwordBundle { | |
item: Item(ItemType::WoodBlock), | |
name: Name("Wood Block".to_string()), | |
durability: Durability { | |
current: 100.0, | |
step: 1.0, | |
}, | |
strength: Strength(10.0), | |
} | |
} | |
} | |
#[derive(PartialEq)] | |
enum InventorySlotType { | |
Smeltable, | |
Fuel, | |
Armor, | |
ArmorHead, | |
ArmorChest, | |
ArmorLegs, | |
ArmorFeet, | |
Any, | |
} | |
#[derive(Component)] | |
struct InventorySlot { | |
id: u32, | |
slot_type: InventorySlotType, | |
} | |
#[derive(Component)] | |
struct Inventory; | |
#[derive(Component)] | |
struct Player; | |
fn init_starting_inventory(mut commands: Commands) { | |
commands | |
.spawn((Player, Name("ProxySaw".to_string()))) | |
.with_children(|parent: &mut ChildBuilder<'_, '_, '_>| { | |
parent.spawn(Inventory).with_children(|parent| { | |
for i in 0..10 { | |
let mut slot = parent.spawn(InventorySlot { | |
id: i, | |
slot_type: InventorySlotType::Any, | |
}); | |
if i == 0 { | |
slot.with_children(|parent| { | |
parent.spawn(IronSwordBundle::default()); | |
}); | |
} | |
if i == 1 { | |
slot.with_children(|parent| { | |
parent.spawn(AppleBundle { | |
stackable: Stackable { | |
current: 32, | |
..default() | |
}, | |
..default() | |
}); | |
}); | |
} | |
} | |
parent.spawn(InventorySlot { | |
id: 11, | |
slot_type: InventorySlotType::ArmorHead, | |
}); | |
parent.spawn(InventorySlot { | |
id: 12, | |
slot_type: InventorySlotType::ArmorChest, | |
}); | |
parent.spawn(InventorySlot { | |
id: 13, | |
slot_type: InventorySlotType::ArmorLegs, | |
}); | |
parent.spawn(InventorySlot { | |
id: 14, | |
slot_type: InventorySlotType::ArmorFeet, | |
}); | |
}); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment