diff --git a/Cargo.toml b/Cargo.toml index aaa1c29..b7da80a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ version = "0.18.0" authors = ["Kat Marchán "] edition = "2021" description = "Rusty Utility AI library" +exclude = ["assets/"] license = "Apache-2.0" readme = "README.md" keywords = ["utility-ai", "bevy", "ai", "ecs"] @@ -20,6 +21,7 @@ big-brain-derive = { version = "=0.18.0", path = "./derive" } [dev-dependencies] bevy = { version = "0.12.1", default-features = true } rand = { version = "0.8.5", features = ["small_rng"] } +bevy-scene-hook = "9.0.0" [features] trace = [] diff --git a/assets/models/town.glb b/assets/models/town.glb new file mode 100644 index 0000000..85ece1d Binary files /dev/null and b/assets/models/town.glb differ diff --git a/examples/farming_sim.rs b/examples/farming_sim.rs new file mode 100644 index 0000000..e7fae19 --- /dev/null +++ b/examples/farming_sim.rs @@ -0,0 +1,648 @@ +//! An intermediate example of a utility AI agent for a farmer +//! +//! The farmer agent will: +//! - Get tired over time, indicated by their [Fatigue] component +//! - When tired, find the house and sleep to reduce fatigue +//! - When not tired, find the farm field and harvest items over time +//! - When inventory is full, find the market and sell items for money + +use bevy::{log::LogPlugin, prelude::*}; +use bevy_scene_hook::{HookPlugin, HookedSceneBundle, SceneHook}; +use big_brain::prelude::*; +use big_brain_derive::ActionBuilder; + +const DEFAULT_COLOR: Color = Color::BLACK; +const SLEEP_COLOR: Color = Color::RED; +const FARM_COLOR: Color = Color::BLUE; +const MAX_DISTANCE: f32 = 0.1; +const MAX_INVENTORY_ITEMS: f32 = 20.0; +const WORK_NEED_SCORE: f32 = 0.6; +const SELL_NEED_SCORE: f32 = 0.6; +const MOVEMENT_SPEED: f32 = 1.5; + +/// A marker for our spawned gltf indicating the farm's field location. +#[derive(Component, Debug, Clone)] +pub struct Field; + +/// A marker for our spawned gltf indicating the market's location. +#[derive(Component, Debug, Clone)] +pub struct Market; + +/// A marker for our spawned gltf indicating the house's location. +#[derive(Component, Debug, Clone)] +pub struct House; + +/// The farmer's inventory. +#[derive(Component, Reflect)] +pub struct Inventory { + /// How much money this entity has. + pub money: u32, + /// How many items the entity has. + // We use a float here to simplify the math in the farming action. + pub items: f32, +} + +/// A marker for our money UI text. +#[derive(Component)] +pub struct MoneyText; + +/// A marker for our fatigue UI text. +#[derive(Component)] +pub struct FatigueText; + +/// A marker for our inventory UI text. +#[derive(Component)] +pub struct InventoryText; + +// ================================================================================ +// Sleepiness 😴 +// ================================================================================ + +// This is not an AI component, but a standard Bevy component that increases an +// entity's fatigue over time. The AI will interact with this component later. +#[derive(Component, Debug, Reflect)] +pub struct Fatigue { + /// A boolean indicating whether the entity is currently sleeping. + pub is_sleeping: bool, + /// The rate at which the fatigue level increases per second. + pub per_second: f32, + /// The current fatigue level of the entity. + pub level: f32, +} + +/// Increases an entity's fatigue over time +pub fn fatigue_system(time: Res