Skip to content

Instantly share code, notes, and snippets.

@garrettjoecox
Created June 29, 2023 16:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save garrettjoecox/8654a35375546f250f57571adbd5b303 to your computer and use it in GitHub Desktop.
Save garrettjoecox/8654a35375546f250f57571adbd5b303 to your computer and use it in GitHub Desktop.
// 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