An ability management suite for Bevy.

Overview

About

A fully-featured set of tools for managing abilities in Bevy. This crate is meant to be used with Leafwing Input Manager, which converts inputs into actions.

Some of those actions will be abilities! Abilities are intended for gameplay use, and follow complex but relatively standardized logic about how they might be used.

use bevy::prelude::*;
use leafwing_abilities::prelude::*;
use leafwing_abilities::premade_pools::mana::{ManaPool, Mana};
use leafwing_abilities::premade_pools::life::{LifePool, Life};
use leafwing_input_manager::prelude::*;

// We're modelling https://leagueoflegends.fandom.com/wiki/Zyra/LoL
// to show off this crate's features!
#[derive(Actionlike, Abilitylike, Clone, Copy, PartialEq)]
pub enum ZyraAbility {
    GardenOfThorns,
    DeadlySpines,
    RampantGrowth,
    GraspingRoots,
    Stranglethorns,
}

impl ZyraAbility {
    fn input_map() -> InputMap<ZyraAbility> {
        use ZyraAbility::*;

        // We can use this `new` idiom, which accepts an iterator of pairs
        InputMap::new([
            (KeyCode::Q, DeadlySpines),
            (KeyCode::W, RampantGrowth),
            (KeyCode::E, GraspingRoots),
            (KeyCode::R, Stranglethorns),
        ])
    }

    // This match pattern is super useful to be sure you've defined an attribute for every variant
    fn cooldown(&self) -> Cooldown {
        use ZyraAbility::*;

        let seconds: f32 = match *self {
            GardenOfThorns => 13.0,
            DeadlySpines => 7.0,
            RampantGrowth => 18.0,
            GraspingRoots => 12.0,
            Stranglethorns => 110.0,
        };

        Cooldown::from_secs(seconds)
    }

    fn cooldowns() -> CooldownState<ZyraAbility> {
        let mut cooldowns = CooldownState::default();

        // Now, we can loop over all the variants to populate our struct
        for ability in ZyraAbility::variants() {
            cooldowns.set(ability, ability.cooldown());
        }

        cooldowns
    }

    fn charges() -> ChargeState<ZyraAbility> {
        // The builder API can be very convenient when you only need to set a couple of values
        ChargeState::default()
            .set(ZyraAbility::RampantGrowth, Charges::replenish_one(2))
            .build()
    }

    fn mana_costs() -> AbilityCosts<ZyraAbility, ManaPool> {
        use ZyraAbility::*;
        AbilityCosts::new([
            (DeadlySpines, Mana(70.)),
            (GraspingRoots, Mana(70.)),
            (Stranglethorns, Mana(100.)),
        ])
    }
}

/// Marker component for this champion
#[derive(Component)]
struct Zyra;

#[derive(Bundle)]
struct ZyraBundle {
    champion: Zyra,
    life_pool: LifePool,
    #[bundle]
    input_manager_bundle: InputManagerBundle<ZyraAbility>,
    #[bundle]
    abilities_bundle: AbilitiesBundle<ZyraAbility>,
    #[bundle]
    mana_bundle: PoolBundle<ZyraAbility, ManaPool>,
}

impl Default for ZyraBundle {
    fn default() -> Self {
        ZyraBundle {
            champion: Zyra,
            // Max life, then regen
            life_pool: LifePool::new_full(Life(574.), (Life(5.5))),
            input_manager_bundle: InputManagerBundle::<ZyraAbility> {
                input_map: ZyraAbility::input_map(),
                ..default()
            },
            abilities_bundle: AbilitiesBundle::<ZyraAbility> {
                cooldowns: ZyraAbility::cooldowns(),
                charges: ZyraAbility::charges(),
            },
            mana_bundle: PoolBundle::<ZyraAbility, ManaPool> {
                pool: ManaPool::new_full(Mana(418.), Mana(13.0)),
                ability_costs: ZyraAbility::mana_costs(),
            }
        }
    }
}

Features

  • track and automatically tick cooldowns
  • store multiple charges of abilities
  • Leafwing Studio's trademark #[deny(missing_docs)]

Planned:

  • resource management (health, mana, energy etc)
  • damage
  • cast times
  • range checking
Comments
  • Add range checks

    Add range checks

    What problem does this solve?

    I want to verify that I am in range of an ability before I can use it.

    What solution would you like?

    I pass in my current position and target's position to check if an ability is ready. If it's out of range, return false.

    Ideally, this supports non-Transform position types. This should also support both center-to-center and edge-to-edge range measures.

    enhancement 
    opened by alice-i-cecile 1
  • Add resource pools

    Add resource pools

    Fixes #3. Coauthored with @bzm3r.

    To do:

    • [x] figure out how to handle abilities that aren't associated with a resource
    • [x] add release notes
    • [x] update docs for Pool
    • [x] add tests
    • [ ] add example
    • [x] add a resource regeneration system
    enhancement code quality 
    opened by alice-i-cecile 0
  • Add initial prototype

    Add initial prototype

    Most of this code is ripped from the main branch of https://github.com/leafwing-studios/leafwing-input-manager and will have to be removed from there.

    enhancement 
    opened by alice-i-cecile 0
  • Add example of how to use resource pools

    Add example of how to use resource pools

    This is somewhat obscure. You seem to need to create your own Pool-implementing type, plus your own scalar value for it.

    Then, you need to add costs for each ability, initialize it via components or resources, and add a regen system.

    documentation 
    opened by alice-i-cecile 0
  • Change return type of `new*` functions on `ResourcePool` to a `Result`

    Change return type of `new*` functions on `ResourcePool` to a `Result`

    Which code could be improved?

    https://github.com/Leafwing-Studios/leafwing_abilities/blob/45cb55c4dd0674849efec65dbc17953633cf1ff3/src/pool.rs#L51

    https://github.com/Leafwing-Studios/leafwing_abilities/blob/45cb55c4dd0674849efec65dbc17953633cf1ff3/src/pool.rs#L58

    https://github.com/Leafwing-Studios/leafwing_abilities/blob/45cb55c4dd0674849efec65dbc17953633cf1ff3/src/pool.rs#L67

    How should this be changed?

    Note that the docs for new say:

    https://github.com/Leafwing-Studios/leafwing_abilities/blob/45cb55c4dd0674849efec65dbc17953633cf1ff3/src/pool.rs#L46-L50

    These should return Result<Self, MaxPoolLessThanZero>, that way, the expectation described in the doc is guaranteed to be fulfilled.

    documentation good first issue code quality 
    opened by bzm3r 0
  • Rename `ResourcePool::ZERO` to `MIN_LIMIT`

    Rename `ResourcePool::ZERO` to `MIN_LIMIT`

    Which code could be improved?

    https://github.com/Leafwing-Studios/leafwing_abilities/blob/45cb55c4dd0674849efec65dbc17953633cf1ff3/src/pool.rs#L44

    How should this be changed?

    This should be renamed to const MIN_LIMIT: Self::Quantity; because ZERO has additional semantic expectations: for example, it should be an identity with respect to Add/Sub.

    documentation good first issue code quality 
    opened by bzm3r 0
  • Remove `AbilitiesPlugin::server()` method

    Remove `AbilitiesPlugin::server()` method

    Which code could be improved?

    https://github.com/Leafwing-Studios/leafwing_abilities/blob/45cb55c4dd0674849efec65dbc17953633cf1ff3/src/plugin.rs#L62

    How should this be changed?

    This code shouldn't exist: it was copy-pasted from LWIM.

    good first issue code quality breaking-change 
    opened by alice-i-cecile 0
Owner
Leafwing Studios
Leafwing Studios
bevy-hikari is an implementation of voxel cone tracing global illumination with anisotropic mip-mapping in Bevy

Bevy Voxel Cone Tracing bevy-hikari is an implementation of voxel cone tracing global illumination with anisotropic mip-mapping in Bevy. Bevy Version

研究社交 208 Dec 27, 2022
A simple extension for `bevy-editor-pls` to support tilemap editing right inside the bevy app.

What is this This is a simple tilemap editor plugin, that hooks right into bevy_editor_pls to work with bevy_ecs_tilemap. It works completely within i

null 3 May 8, 2023
Bevy Simple Portals is a Bevy game engine plugin aimed to create portals.

Portals for Bevy Bevy Simple Portals is a Bevy game engine plugin aimed to create portals. Those portals are (for now) purely visual and can be used t

Sélène Amanita 11 May 28, 2023
Minecraft using Bevy and Bevy-Meshem

minecraft_bevy Minecraft_bevy was built to showcase bevy_meshem. After a week of developing it has: Chunk loading / unloading each chunk's mesh is bei

Adam 7 Oct 4, 2023
A Bevy plugin for loading the LDtk 2D tile map format.

bevy_ldtk ( Tileset from "Cavernas" by Adam Saltsman ) A Bevy plugin for loading LDtk tile maps. Usage use bevy::prelude::*; use bevy_ldtk::*; fn mai

Katharos Technology 23 Jul 4, 2022
Basic first-person fly camera for the Bevy game engine

bevy_flycam A basic first-person fly camera for Bevy 0.4 Controls WASD to move horizontally SPACE to ascend LSHIFT to descend ESC to grab/release curs

Spencer Burris 85 Dec 23, 2022
An ergonomic physics API for bevy games.

Heron An ergonomic physics API for 2d and 3d bevy games. (powered by rapier) How it looks like fn main() { App::build() .add_plugins(DefaultPlug

Jonathan Cornaz 313 Dec 16, 2022
Inspector plugin for the bevy game engine

bevy-inspector-egui This crate provides the ability to annotate structs with a #[derive(Inspectable)], which opens a debug interface using egui where

Jakob Hellermann 517 Dec 31, 2022
A plugin for Egui integration into Bevy

bevy_egui This crate provides a Egui integration for the Bevy game engine. Features: Desktop and web (bevy_webgl2) platforms support Clipboard (web su

Vladyslav Batyrenko 453 Jan 3, 2023
Crossterm plugin for the bevy game engine

What is bevy_crossterm? bevy_crossterm is a Bevy plugin that uses crossterm as a renderer. It provides custom components and events which allow users

null 79 Nov 2, 2022
A 4X style camera for bevy.

A 4X style camera for bevy. Demo Default Key Bindings: W / A / S / D / Arrow Keys / Mouse Left - Move along the horizontal plane Q / E / Mouse Right -

null 30 Jan 4, 2023
Game physics in one weekend with bevy

Game Physics in a Weekend (in Rust) This project is an implementation of the Game Physics in a Weekend book using the Rust programming language and th

Cameron Hart 28 Dec 23, 2022
A Bevy plugin to use Kira for game audio

Bevy Kira audio This bevy plugin is intended to try integrating Kira into Bevy. The end goal would be to replace or update bevy_audio, if Kira turns o

Niklas Eicker 172 Jan 5, 2023
Concise Reference Book for the Bevy Game Engine

Unofficial Bevy Cheat Book Click here to read the book! Concise reference to programming in the Bevy game engine. Covers useful syntax, features, prog

null 947 Jan 8, 2023
A prototype plugin providing a simple line drawing api for bevy.

bevy_debug_lines A prototype plugin providing a simple line drawing api for bevy. See docs.rs for documentation. Expect breakage on master. Click on t

Michael Palmos 92 Dec 31, 2022
Template for a Bevy game

A Bevy game template Template for a Game using the awesome Bevy engine featuring (almost) out of the box builds for Windows, Linux and MacOS. What doe

Niklas Eicker 346 Jan 1, 2023
Pixel-Perfect, 2D Renderer for Bevy that Seamlessly Targets Desktop and Web

bevy_retro ( Screenshot of Bounty Bros. game made with Bevy Retro and Skip'n Go ) Bevy Retro is a 2D, pixel-perfect renderer for Bevy that can target

Katharos Technology 224 Dec 23, 2022
A tilemap rendering crate for bevy which is more ECS friendly.

bevy_ecs_tilemap A tilemap rendering plugin for bevy which is more ECS friendly by having an entity per tile. Features A tile per entity Fast renderin

John 414 Dec 30, 2022
Proof-of-concept of getting OpenXR rendering support for Bevy game engine using gfx-rs abstractions

Introduction Proof-of-concept of getting OpenXR rendering support for Bevy game engine using gfx-rs abstractions. (hand interaction with boxes missing

Mika 52 Nov 14, 2022