Skip to content

SDesya74/bevy_mod_static_inventory

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Static Inventory

Crates.io Crates.io docs.rs

Proof of concept of static inventory for Bevy. A static inventory means that each item type is a struct (or enum) with a specific set of traits. The advantages of this approach are excellent editor support and validity checking of some actions at compile time, e.g. you can't put sticks and apples in the same item stack.

It also opens up possibilities for partial support for inventory requests in ECS. For example, it is possible to call the system only for entities that have an apple in their inventory using Bevy's query filters.

This also allows you to add parameters to each individual item, such as color or durability for tools.

The current (not for long, I hope) drawbacks of this method, however, is the inability to create items in runtime.

Installation

cargo add bevy_mod_static_inventory

Usage

use std::{any::TypeId, time::Duration};

use bevy::{app::ScheduleRunnerPlugin, prelude::*};
use bevy_mod_static_inventory::{HasInInventory, Inventory, Item, Key};

fn main() {
    App::new()
        .add_plugins(
            MinimalPlugins.set(ScheduleRunnerPlugin::run_loop(Duration::from_secs_f64(1.0))),
        )
        .add_systems(Startup, setup)
        .add_systems(
            Update,
            (log_when_apple_in_inventory, log_when_stick_in_hand_slot),
        )
        .run();
}

pub struct HandSlot;

// TODO: Create derive macro
impl From<HandSlot> for Key {
    fn from(_: HandSlot) -> Self {
        Key::Type(TypeId::of::<HandSlot>())
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Apple;

// TODO: Create derive macro
impl Item for Apple {}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Stick;

impl Item for Stick {}

fn setup(mut commands: Commands) {
    let mut inv = Inventory::new().with_slot_count(4);

    inv.add(Apple).unwrap(); // add 1 apple
    inv.add((Apple, 2)).unwrap(); // add 2 apples
    inv.add((2, Apple)).unwrap(); // you also can swap count and item

    commands.spawn(inv);
    println!("Spawned entity with apples in inventory");

    let mut inv = Inventory::new().with_custom_slot(HandSlot);

    inv.insert(HandSlot, Stick).unwrap();

    commands.spawn(inv);
    println!("Spawned entity with apples in inventory");
}

fn log_when_apple_in_inventory(entities_with_apples: Query<DebugName, HasInInventory<Apple>>) {
    for e in entities_with_apples.iter() {
        println!("{:?} has Apple in inventory", e);
    }
}

fn log_when_stick_in_hand_slot(
    entities_with_apples: Query<DebugName, HasInInventory<Stick, HandSlot>>,
) {
    for e in entities_with_apples.iter() {
        println!("{:?} has Stick in hand slot", e);
    }
}

Progress

  • Typed and boxed ItemStacks
  • Numbered and custom slots
  • Derive macros for defining Item and Key for custom slots
  • Advanced query filters (added/removed item etc)
  • Full documentation
  • Support for dynamic item registering (for modding)
  • Remove dependency on TypeId in all places as it is unstable between builds
  • Support for enum slots (e.g. ArmorSlot containing Head, Body, Legs variants)
  • Support downcasting for more concrete traits, that have Item as supertrait (now it is possible only in runtime with intertrait and linkme)

About

No description, website, or topics provided.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages