bevy_magic/spellbook.rs
1//! [`Spellbook`] component — stores all [`Spell`] handles an entity can cast.
2
3use bevy::prelude::*;
4
5use crate::spell::Spell;
6
7/// Component that holds every [`Spell`] an entity is capable of casting.
8///
9/// Attach this to player characters, NPCs, or any entity you want to give
10/// casting ability. Individual spells are referenced as asset [`Handle`]s so
11/// the same spell asset can be shared across many entities with no duplication.
12///
13/// # Example
14///
15/// ```rust,ignore
16/// fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
17/// let fireball = asset_server.load("spells/fireball.spell");
18/// commands.spawn((Player, Spellbook::new().with_spell(fireball)));
19/// }
20/// ```
21#[derive(Component, Default, Debug)]
22pub struct Spellbook {
23 /// Ordered spell slots. The index acts as the "slot number."
24 pub spells: Vec<Handle<Spell>>,
25}
26
27impl Spellbook {
28 /// Creates an empty spellbook.
29 pub fn new() -> Self {
30 Self::default()
31 }
32
33 /// Builder-style: add a spell handle before spawning.
34 pub fn with_spell(mut self, handle: Handle<Spell>) -> Self {
35 self.spells.push(handle);
36 self
37 }
38
39 /// Appends `handle` to the next available slot.
40 pub fn add_spell(&mut self, handle: Handle<Spell>) {
41 self.spells.push(handle);
42 }
43
44 /// Removes the first slot whose handle matches `handle`.
45 pub fn remove_spell(&mut self, handle: &Handle<Spell>) {
46 self.spells.retain(|h| h != handle);
47 }
48
49 /// Returns `true` if any slot holds `handle`.
50 pub fn contains(&self, handle: &Handle<Spell>) -> bool {
51 self.spells.contains(handle)
52 }
53
54 /// Number of spells currently in the spellbook.
55 pub fn len(&self) -> usize {
56 self.spells.len()
57 }
58
59 /// Returns `true` when the spellbook has no spells.
60 pub fn is_empty(&self) -> bool {
61 self.spells.is_empty()
62 }
63}